How Albus Dumbledore would sell Haskell

It is unscientific to ask the (highly biased) people on this list how to sell Haskell. A focus group of the target audience is clearly called for. Having said that, I will now violate my own advice. Knowledge of the audience is critical to the success of a presentation. Simon (aka Dumbledore) is speaking to four different Houses: scientists (Ravenclaw), engineers (Hufflepuff), entrepreneurs (Slytherin), and managers (Griffindor). My advice to him is: You have already won over the scientists. Stop priming the pump. Algebraic runes, spells from the Book of Category Theory, bananas, lenses, arrows, cata, ana, hylo, endo, all is vanity. You cannot interest the engineer with new tricks. He has spent too long mastering difficult tricks to work around limitations to want to see them eliminated. His competitive advantage and prized reputation are at stake. Get him to believe that he is on the verge of being "left behind". You cannot win over the entrepreneur with promises of "easier and more robust". This translates to "anyone can do it" and the valuable "trade secret" of arcane wizardry is now devalued. Show something exciting that cannot be done (or would never have been attempted) without FP. Monads, CPS, existential data types, or other high-priestess wizardry are no impediment (less competition from lesser peers). But marginal improvement is unimpressive. A new language brings high risk, and must have high reward. Examples must be powerful (not another prime number generator). Effective complexity management, correctness reasoning in concurrent/distributed processing, and so on will get their interest. Risk is scary for managers. "Great promise" promises the manager only headaches. This translates to "no one can be hired to do it" and "those that can will shake me down for more money". You must promote instead the *inevitability* of Haskell's success: the fact that Haskell has recently dominated the ICFP Programming Contest, the strongly upward trend of Haskell taught at universities (hopefully there is a strongly upward trend?), some anecdotal measure of the predisposition to relatively better "quality" of those who seek to learn Haskell. Allay the unspoken fear that there are always plenty of Haskellers to cause trouble in a company (design and implement great tasks), but never enough more mediocre Haskellers to keep out of trouble (content to do "maintenance" tasks and minor upgrades to existing software) by marketing Haskell as a recruitment tool to attract the best, a motivational tool to reenergize engineers (see above) who've let their skills go stale in larger companies, and a staff-development tool to spur internal friendly competition to modernize their skills (and excuse wage stagnation in those that do not). Since "inevitability" is a hard sell for Haskell right now, avoid mentioning ML or Erlang. There needs to be only one FPL for a manager, or he will fret about VHS vs. Betamax syndrome (and he won't want to have been the one to invest in a Betamax). Don't show any Haskell function with the prefix "unsafe". Even now, I find the name unsettling. The Harry Potter series makes money because we can't do magic but we want to. It is human nature that what is given away will never be thought to have value. Don't give away the magic of Haskell. Let the audience in on the secret that the Haskell wizarding world is doing great things with it for glory and profit, and others will steal the secret for themselves readily enough. If Simon can do all this, then he really is worthy of the name Dumbledore. :) Dan

Simon (aka Dumbledore) is speaking to four different Houses: scientists (Ravenclaw), engineers (Hufflepuff), entrepreneurs (Slytherin), and managers (Griffindor). Agreed, although perhaps there are two groups of scientists: Computer Scientists and Other Scientists. Dan describes Computer Scientists. The Other Scientists see programming as a tool to solve larger problems such as analyzing data and simulating things. They have a very
Dan Weston wrote: pragmatic view, but their nightmare is buggy programs. See for instance http://www.sciencemag.org/cgi/content/full/314/5807/1856 This kind of thing can be very damaging to a scientist's career. Haskell has three big selling points here: 1: The type system helps to catch errors. Dimensional analysis can be done in the type system. 2: The programs are shorter. Hence less scope for errors. 3: Haskell is very close to the underlying mathematics. What you know is what you type. Recursion and equational reasoning will appeal to Other Scientists because that is how they think anyway.
You cannot win over the entrepreneur with promises of "easier and more robust". This translates to "anyone can do it" and the valuable "trade secret" of arcane wizardry is now devalued. I suggest reading extracts from "Beating the Averages" by Paul Graham. Then explain that Graham only wrote in Lisp because his university didn't teach Haskell.
Risk is scary for managers.
Selling new technology to managers is the hardest thing there is to do. The only way to get any traction is to find a problem they already know they have, and then present a solution. That will get their attention. Anything else will go in the "clever but irrelevant" bin. The biggest problem that software managers have is the unpredictability of development. Managers (especially middle managers) don't actually care how much it costs; they just care about meeting their budgets and deadlines. The big nightmare is software that never works reliably, so you might get some traction by talking about composability as a way of reducing integration risk. However its a bit difficult to draw a straight line from closures to the integration of 100 kSLOC. If they don't follow the argument then you've lost it. Senior managers do care how much it costs, just not very much (except for software houses, their businesses are generally dominated by other costs). If you can make a strong cost reduction argument then you will get at least some traction. Show how cost is proportional to SLOC. COCOMO II demonstrates this clearly. Then demonstrate how few SLOC you need to do something in Haskell.

Paul Johnson wrote:
You cannot win over the entrepreneur with promises of "easier and more robust". This translates to "anyone can do it" and the valuable "trade secret" of arcane wizardry is now devalued.
I suggest reading extracts from "Beating the Averages" by Paul Graham. Then explain that Graham only wrote in Lisp because his university didn't teach Haskell.
I think a more powerful argument would be to talk about cases where Haskell is *actually being used* industrially. E.g., "these folks at Credit Suisse are using Haskell for their analytics because in their line of work, if the implementation of the code doesn't match up perfectly with the spec, their employer could lose millions of dollars, and the programmers might not notice the bug until those millions were long gone".

Seth Gordon wrote:
I think a more powerful argument would be to talk about cases where Haskell is *actually being used* industrially. E.g., "these folks at Credit Suisse are using Haskell for their analytics because in their line of work, if the implementation of the code doesn't match up perfectly with the spec, their employer could lose millions of dollars, and the programmers might not notice the bug until those millions were long gone".
Indeed, hence the Haskell Communities and Activities Report http://www.haskell.org/communities/, Commerial Uses of Function Programming (CUFP) http://cufp.galois.com/, and the new category of Experience Report http://icfp07.eecs.harvard.edu/cfp.html#experience at ICFP.

In general, problems that would lose millions of dollars are noticed very quickly. Quants are constantly analyzing the sources of shortfall in implementing strategies. Also, time to market is generally more important than correctness. It's much better to have a strategy that mostly works sooner than a strategy that's perfect later. The opportunities to extract alpha from the market decay as more people see them (it is a zero sum game after all). Most of this technology has a lot in common with a Formula 1 race car: you can't win the race with a car that doesn't risk breaking down halfway through the race. Of course, there are exceptions (risk systems, systems that handle client orders, etc). The interest I've seen in Haskell and ML in the quant world has been driven by expressiveness. On Apr 18, 2007, at 1:47 PM, Seth Gordon wrote:
Paul Johnson wrote:
You cannot win over the entrepreneur with promises of "easier and more robust". This translates to "anyone can do it" and the valuable "trade secret" of arcane wizardry is now devalued.
I suggest reading extracts from "Beating the Averages" by Paul Graham. Then explain that Graham only wrote in Lisp because his university didn't teach Haskell.
I think a more powerful argument would be to talk about cases where Haskell is *actually being used* industrially. E.g., "these folks at Credit Suisse are using Haskell for their analytics because in their line of work, if the implementation of the code doesn't match up perfectly with the spec, their employer could lose millions of dollars, and the programmers might not notice the bug until those millions were long gone". _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

| Simon (aka Dumbledore) is speaking to four different Houses: scientists | (Ravenclaw), engineers (Hufflepuff), entrepreneurs (Slytherin), and | managers (Griffindor). I wish I could live up to this image! Lots of interesting ideas on this thread, and Haskell-Cafe threads are *supposed* to wander a bit. But, just to remind you all: I'm particularly interested in concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language I have lots of *general* ideas. What I'm hoping is that I can steal working code for one or two compelling examples, so that I can spend my time thinking about how to present it, rather than on dreaming up the example and writing the code. (But don't let me inhibit wider-ranging discussion as well.) thanks Simon

G'day all.
Quoting Simon Peyton-Jones
Lots of interesting ideas on this thread, and Haskell-Cafe threads are *supposed* to wander a bit. But, just to remind you all: I'm particularly interested in
concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
I updated the diff example a bit: http://andrew.bromage.org/darcs/diff/ It now features TWO newtype synonyms. This illustrates a crucial feature of Haskell: Abstractions are cheap. Cheers, Andrew Bromage

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 ajb@spamcop.net wrote:
I updated the diff example a bit:
http://andrew.bromage.org/darcs/diff/
It now features TWO newtype synonyms. This illustrates a crucial feature of Haskell: Abstractions are cheap.
Okay, looking at that code: The comments before the type definitions are mostly good... now it looks like I'm going into critique mode :) Range (that is, the comment describing it) needs to say whether it's inclusive of its first and/or its last endpoint (in fact it is inclusive, I can determine by looking at the definition of rangeDist) I suppose Match is the same (inclusive), but I can't tell. And personally I don't know what the significance/meaning of a "found match" is. Comparing "data Range = Range Line Line" and "type Match = (Line,Line)", they are isomorphic, but declared differently (which is fine IMO) With just a little modification, it could use haddock syntax for the comments! I got a little lost reading the code. I think all the data/type definitions should be moved together, to the top. And the comments on the types enhanced a little to make it clearer how the algorithm goes. Or if diff is a weird confusing algorithm even in Haskell, put a more thorough description of why/how it uses those types and/or a reference to a paper on the subject, I would personally like :). Maybe that doesn't show off how clear Haskell itself is, or maybe it gives the reader a better chance of understanding it at all and thereby seeing how straightforward it is. I don't know, are there QuickCheck-style properties we can say about diff? (they are another valuable tool for understanding in detail what the code is supposed to do) The only IO that displayDiff does is putStrLn. It should probably return a string instead (and be called showDiff? would it be necessary to replace the putStrLn IO with some sort of writer monad to keep the code's clarity? or the ShowS-style sequencing/concatenation is (.) and output is (str++) (or, showLn: (\s -> str ++ '\n' : s)) -- that can be abstracted so it's not so ugly...) Then, displayDiff = putStr . showDiff Isaac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGJ09qHgcxvIWYTTURAhqrAJ9SFYmIifl5Ahf0umg0SnImGKr3tgCgwLze bZdTYUzmy+C2uXwFOkJOcdU= =KfVH -----END PGP SIGNATURE-----

G'day all.
Quoting Isaac Dupree
Okay, looking at that code: The comments before the type definitions are mostly good... now it looks like I'm going into critique mode :)
BTW, for the record, I didn't try too hard with this. It is meant to be illustrative of what you can do with Haskell and not too much time to spare. I didn't haddock-ise the comments because Diff isn't a library. The comments are meant to be more commentary (this is a tutorial, remember!) than developer documentation.
Range (that is, the comment describing it) needs to say whether it's inclusive of its first and/or its last endpoint (in fact it is inclusive, I can determine by looking at the definition of rangeDist)
Fair point.
I suppose Match is the same (inclusive), but I can't tell. And personally I don't know what the significance/meaning of a "found match" is.
OK, this needs explanation. A Match is a match _between_ the two files being diffed. So (a,b) means that line a in file 1 matches line b in file 2. I'll note that, thanks.
Comparing "data Range = Range Line Line" and "type Match = (Line,Line)", they are isomorphic, but declared differently (which is fine IMO)
Yup. They only have to be different enough to cause a type error if you accidentally try to mix them.
The only IO that displayDiff does is putStrLn. It should probably return a string instead [...]
Possibly, or even use a Writer monad. I habitually use putStrLn, though, because I regularly program in multiple languages, and this way I don't have to remember how Haskell handles line termination on different platforms. Cheers, Andrew Bromage

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 ajb@spamcop.net wrote:
G'day all.
Quoting Isaac Dupree
: Okay, looking at that code: The comments before the type definitions are mostly good... now it looks like I'm going into critique mode :)
BTW, for the record, I didn't try too hard with this. It is meant to be illustrative of what you can do with Haskell and not too much time to spare.
I know, (but if you got it from somewhere, the code could really be improved where it came from? >:) or did I misunderstand?)
I didn't haddock-ise the comments because Diff isn't a library. The comments are meant to be more commentary (this is a tutorial, remember!) than developer documentation.
Admittedly. Haddock standardizes what bit of the code a comment is meant to refer to, though, so I like using its syntax anyway. (And all code might be part of a library someday... Haskell lets you think of almost all your code as libraries! it is an excellent way to think about modularity that is far too cumbersome in many other languages!)
I suppose Match is the same (inclusive), but I can't tell. And personally I don't know what the significance/meaning of a "found match" is.
OK, this needs explanation. A Match is a match _between_ the two files being diffed. So (a,b) means that line a in file 1 matches line b in file 2. I'll note that, thanks.
Ah, I see now.
Comparing "data Range = Range Line Line" and "type Match = (Line,Line)", they are isomorphic, but declared differently (which is fine IMO)
Yup. They only have to be different enough to cause a type error if you accidentally try to mix them.
Tuples are always a bit risky though (every tuple matches every other tuple you introduce, as well as libraries using them) -- but undoubtedly convenient syntax (and certainly worth showing off to those whose languages don't contain native tuples)
The only IO that displayDiff does is putStrLn. It should probably return a string instead [...]
Possibly, or even use a Writer monad. I habitually use putStrLn, though, because I regularly program in multiple languages, and this way I don't have to remember how Haskell handles line termination on different platforms.
Hmm, reasonable. (I hope haskell just uses '\n' in-program everywhere..) You could return a list of lines instead (and mapM_ putStrLn the result). Is there any way to make IO be an instance of MonadWriter? Not in a reasonable way, I think, given 'listen' etc... possibly a different class interface would be more useful, but we're certainly not into trying that here! Isaac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGKOjaHgcxvIWYTTURAj/tAKCF1NoAR/tsCk/2F90qrJqotEa+GACfbYzs uWYo+EFqlpZTnsdS1YTndl8= =IR0K -----END PGP SIGNATURE-----

* small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
Something I like: A finite (binary) relation
data Rel q = Rel { elems :: [(q,q)] }
We do not export constructors, hence
rel xs = Rel { elems = xs }
Now, the function mirror
mirror r = rel [ (p,q) | (q,p) <- elems r ]
is an involution, that is mirror . mirror == id. Okay, how to exploit that? Nothing easier than that in Haskell: Just make mirror a field of Rel
data Rel q = Rel { elems :: [(q,q)], mirror :: Rel q }
and change the construction function to
rel xs = r where r = Rel { elems = xs , mirror = let m = rel [ (p,q) | (q,p) <- elems r ] in m { mirror = r } }
Note that the signatures of mirror and rel are the same as before. Try this in your favorite language! Regards, -- -- Mirko Rahn -- Tel +49-721 608 7504 -- --- http://liinwww.ira.uka.de/~rahn/ ---

Mirko Rahn wrote:
Note that the signatures of mirror and rel are the same as before. Try this in your favorite language!

Thanks for your answer, I think it emphasizes that my example matches the exclaimed conditions
* small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
It's easy to encode this in some object oriented language with generics, ^^^^ [some dozen lines of java]
The haskell solution may be much shorter, but it is far from impossible to encode such things in a plain-and-boring mainstream language like java. The promotional value of this (and similar) examples shrinks down to "haskell code is much shorter". Wich is true, and important, but may not be enough to consider learning some crazy programming language.
Okay, nobody sayed its impossible. GHC compiles Haskell programs to some kind of C. But first: Shorter code has less chances for bugs and is easier to maintain... More important: Correct me, if I'm wrong, but as far as I understand java, it is still impossible in your solution to evaluate the equivalent of head $ mirror $ rel [ (i,i) | i <- [0..] ] in finite time, that is, your MirrorRel is not lazy in the elements. You have to build this also by hand and your code becomes even longer and more complex.
(Java developers who don't understand Java's advanced features like generics and anonymous classes may not be able to write or understand the above written Java solution; but do you expect them to understand Haskell?)
Add 1: This statement contradicts your "easyness" claim!? Add 2: In contrast, the Haskell solution does'nt uses "advanced Haskell features" (whatever this might be), it consists of 6 lines of plain Haskell 98 only. Regards, -- -- Mirko Rahn -- Tel +49-721 608 7504 -- --- http://liinwww.ira.uka.de/~rahn/ ---

Mirko Rahn wrote:
More important: Correct me, if I'm wrong, but as far as I understand java, it is still impossible in your solution to evaluate the equivalent of
head $ mirror $ rel [ (i,i) | i <- [0..] ]
in finite time, that is, your MirrorRel is not lazy in the elements. You have to build this also by hand and your code becomes even longer and more complex.
Yes, that's true. Java is strict, and each bit of laziness has to be introduced by hand. Just as Haskell is lazy, and each bit of strictness has to be introduced by hand. It's not clear for a non-Haskell-programmer that the haskell aproach is better, and i don't think that it becomes clear by showing a single program wich uses laziness.
(Java developers who don't understand Java's advanced features like generics and anonymous classes may not be able to write or understand the above written Java solution; but do you expect them to understand Haskell?)
Add 1: This statement contradicts your "easyness" claim!?
I don't think so. I was able to write a short (modulo syntactical overhad of the Java language) and modular Java solution without consulting reference manuals, drawing diagrams or something.
Add 2: In contrast, the Haskell solution does'nt uses "advanced Haskell features" (whatever this might be), it consists of 6 lines of plain Haskell 98 only.
The Haskell solution has no need for "advanced Haskell features" because Haskell is an advanced programming language. This can be good (no need to implement advanced features yourself) or bad (fear of what the advanced features do with your simple-looking code). Tillmann

Simon Peyton-Jones
But, just to remind you all: I'm particularly interested in
concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
I have something that I think nearly fits the bill. Unfortunately, I don't think it quite works because it's a bit specialised. However, I think it suggests a possible area to look, which I'll mention at the end. It's a theorem prover for intuitionistic propositional logic: http://www.polyomino.f2s.com/david/haskell/gentzen.html It's much shorter in Haskell than it would be in other languages. (It's even shorter than the ML that I based it on, because of some shortcuts I can take using lazy evaluation.) Strengths of Haskell that it demonstrates are: * How easy it is to define datatypes (eg trees), and manipulate them using pattern matching, with constructors, Eq, Show coming for free. * How lazy evaluation reduces code length by letting you write code that looks like it would do too much, and then lazy evaluate it (in the "proof" function) * The ability to extend the syntax with new symbolic operators * Use of higher order functions to simplify code (the (+++) operator) The problem is that I think Gentzen systems are a bit obscure. But I think you could probably show most of the same strengths of Haskell in something similar: game search, eg alpha-beta algorithm. Another advantage of doing game search would be that you'd get to show off persistent data structures (so that when you make a move in lookahead, you don't need to make a copy of the game state, because when you update the game state the old state still persists).

A theorem prover might be a really cool example, but if there's one person in the audience that cares then Simon is lucky. :) You need to have examples that people can recognize and see the utility of. -- Lennart On Apr 19, 2007, at 20:48 , DavidA wrote:
Simon Peyton-Jones
writes: But, just to remind you all: I'm particularly interested in
concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
I have something that I think nearly fits the bill. Unfortunately, I don't think it quite works because it's a bit specialised. However, I think it suggests a possible area to look, which I'll mention at the end.
It's a theorem prover for intuitionistic propositional logic: http://www.polyomino.f2s.com/david/haskell/gentzen.html
It's much shorter in Haskell than it would be in other languages. (It's even shorter than the ML that I based it on, because of some shortcuts I can take using lazy evaluation.)
Strengths of Haskell that it demonstrates are: * How easy it is to define datatypes (eg trees), and manipulate them using pattern matching, with constructors, Eq, Show coming for free. * How lazy evaluation reduces code length by letting you write code that looks like it would do too much, and then lazy evaluate it (in the "proof" function) * The ability to extend the syntax with new symbolic operators * Use of higher order functions to simplify code (the (+++) operator)
The problem is that I think Gentzen systems are a bit obscure. But I think you could probably show most of the same strengths of Haskell in something similar: game search, eg alpha-beta algorithm. Another advantage of doing game search would be that you'd get to show off persistent data structures (so that when you make a move in lookahead, you don't need to make a copy of the game state, because when you update the game state the old state still persists).
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

I think you are right. If you used something like a theorem prover as
an example, you accidentally send the messsage that Haskell is very
useful for esoteric stuff that only academics are interested in.
Now, that doesn't mean that the example has to solve a real problem,
but it does need to be something that the audience can relate to their
own problems.
There's already a lot of general buzz about functional techniques.
Closures and lambda expressions are being, or have been, added to
several imperative languages. This naturally leads to interest in
higher order functions. The concurrency revolution is driving interest
in immutable values and lockless algorithms. For people who do
transactional work, having launchTheMissiles in the middle of a
transaction be caught by the type system is incredible. At least some
of the interest in dynamic types is driven by frustration with dealing
with type annotations.
So really, the example code just has to solve a problem they
recognize. Even the sudoko solvers would be good, trite as they are.
Or, some of the unix tools in Haskell.
$0.02
-SMD
On 4/19/07, Lennart Augustsson
A theorem prover might be a really cool example, but if there's one person in the audience that cares then Simon is lucky. :) You need to have examples that people can recognize and see the utility of.
-- Lennart
On Apr 19, 2007, at 20:48 , DavidA wrote:
Simon Peyton-Jones
writes: But, just to remind you all: I'm particularly interested in
concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
I have something that I think nearly fits the bill. Unfortunately, I don't think it quite works because it's a bit specialised. However, I think it suggests a possible area to look, which I'll mention at the end.
It's a theorem prover for intuitionistic propositional logic: http://www.polyomino.f2s.com/david/haskell/gentzen.html
It's much shorter in Haskell than it would be in other languages. (It's even shorter than the ML that I based it on, because of some shortcuts I can take using lazy evaluation.)
Strengths of Haskell that it demonstrates are: * How easy it is to define datatypes (eg trees), and manipulate them using pattern matching, with constructors, Eq, Show coming for free. * How lazy evaluation reduces code length by letting you write code that looks like it would do too much, and then lazy evaluate it (in the "proof" function) * The ability to extend the syntax with new symbolic operators * Use of higher order functions to simplify code (the (+++) operator)
The problem is that I think Gentzen systems are a bit obscure. But I think you could probably show most of the same strengths of Haskell in something similar: game search, eg alpha-beta algorithm. Another advantage of doing game search would be that you'd get to show off persistent data structures (so that when you make a move in lookahead, you don't need to make a copy of the game state, because when you update the game state the old state still persists).
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

DavidA wrote:
Simon Peyton-Jones
writes: But, just to remind you all: I'm particularly interested in
concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
I have something that I think nearly fits the bill. Unfortunately, I don't think it quite works because it's a bit specialised. However, I think it suggests a possible area to look, which I'll mention at the end.
It's a theorem prover for intuitionistic propositional logic: http://www.polyomino.f2s.com/david/haskell/gentzen.html
It's much shorter in Haskell than it would be in other languages. (It's even shorter than the ML that I based it on, because of some shortcuts I can take using lazy evaluation.)
Strengths of Haskell that it demonstrates are: * How easy it is to define datatypes (eg trees), and manipulate them using pattern matching, with constructors, Eq, Show coming for free. * How lazy evaluation reduces code length by letting you write code that looks like it would do too much, and then lazy evaluate it (in the "proof" function) * The ability to extend the syntax with new symbolic operators * Use of higher order functions to simplify code (the (+++) operator)
The problem is that I think Gentzen systems are a bit obscure. But I think you could probably show most of the same strengths of Haskell in something similar: game search, eg alpha-beta algorithm. Another advantage of doing game search would be that you'd get to show off persistent data structures (so that when you make a move in lookahead, you don't need to make a copy of the game state, because when you update the game state the old state still persists).
Game search is exactly an example use in "Why Functional Programming Matters" (http://www.math.chalmers.se/~rjmh/Papers/whyfp.html). That paper, 23 years later, is still pretty compelling. Perhaps, it should just be modernized and somewhat expanded.

Derek Elkins wrote:
Game search is exactly an example use in "Why Functional Programming Matters" (http://www.math.chalmers.se/~rjmh/Papers/whyfp.html). That paper, 23 years later, is still pretty compelling. Perhaps, it should just be modernized and somewhat expanded.
I'll echo Lennart's response to the theorem proving suggestion :-) Tom Moertel's parallel port scanner is much more the kind of thing that will get people's attention. It's practical; it's parallel; and it's short. And for Simon's convenience, it's already been written, so he can concentrate on presenting it, rather than writing it.

On 4/19/07, Simon Peyton-Jones
I have lots of *general* ideas. What I'm hoping is that I can steal working code for one or two compelling examples, so that I can spend my time thinking about how to present it, rather than on dreaming up the example and writing the code.
Last night I thought writing a simple arithmetic calculator in Haskell would be pretty cool. Parsec makes it so easy to parse simple arithmetic expressions. Coming from a Ruby/C# background, that would really impress me - that kind of parsing isn't easy! Not sure how hard it would be - but extending the calculator to different units or to symbolic expressions (i.e. simple variable assignments) would be impressive. Sorry I don't have any code to provide :) Justin

Simon Peyton-Jones wrote:
Lots of interesting ideas on this thread, and Haskell-Cafe threads are *supposed* to wander a bit. But, just to remind you all: I'm particularly interested in
concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
I have lots of *general* ideas. What I'm hoping is that I can steal working code for one or two compelling examples, so that I can spend my time thinking about how to present it, rather than on dreaming up the example and writing the code.
Put up or shut up, huh? OK, I have attached my feeble contribution for consideration. Not quite as trivial as a prime number generator. Since many in the audience might be database people, it might be instructive how some simple relational algebra (inner join, transitive closure) can be done from scratch (and without looking first at how others do it!). It's not quite point-free, but I was surprised how easily the set-like list invariant (sorted, no duplicates) was preserved through many of the operations, allowing me to junk the set datatype I started out with. In a non-FP language, I would have likely overlooked this. Also, I reminded me of how Haskell enables the easy and powerful method of writing a correct by naive algorithm and continuously transforming it into what you want. In C++, the code noise is so high that this would be prohibitive and tedious. Obviously, some QuickCheck is needed to round things off, but I ran out of time for this week. There are no monads, but I slipped the categorical product operator *** in there, along with lots of higher-order functions and showed how easily one-off utility functions are created when needed. It all fits on one slide. Plus, the indentation is so visually appealing! Code as art. Dan module TransitiveClosure(innerJoin,transitiveClosure) where import Data.List(sort,nubBy) import Control.Arrow((***)) ---------------------------------------------------------------------- -- RELATIONAL ALGEBRA ifKeyMatchesAddValue seekKey (findKey,value) = if seekKey === findKey then (:) value else id lookupAll seekKey = foldr (ifKeyMatchesAddValue seekKey) [] lookupAllIn keyValueDict = flip lookupAll keyValueDict -- PRE : abDict and bcDict are set-like -- POST: Returned acDict is set-like innerJoin :: (Ord a, Ord b, Ord c) => [(a, b)] -> [(b, c)] -> [(a, c)] innerJoin abDict bcDict = concatMap innerJoinFor joinKeys where getKeys = map fst `andThen` removeDupsFromSorted joinKeys = getKeys abDict joinedValues = lookupAllIn abDict `andThen` concatMap (lookupAllIn bcDict) `andThen` sortAndRemoveDups innerJoinFor = dup -- key into (joinKey,seekKey) `andThen` (repeat {- joinKey -} *** joinedValues {- seekKey -}) `andThen` uncurry zip -- (joinKey,joinedValues) -- PRE : Arg is set-like -- POST: Returned is set-like, transitiveClosure is idempotent transitiveClosure :: (Ord a) => [(a, a)] -> [(a, a)] transitiveClosure aaDict | aaDict === aaDictNew = aaDictNew | otherwise = transitiveClosure aaDictNew where aaDictNew = mergeInSelfJoin aaDict mergeInSelfJoin d = d `merge` innerJoin d d ---------------------------------------------------------------------- -- USING LISTS AS SETS -- DEF: A list is set-like if it is in strictly increasing order -- Why is this not in Prelude? dup x = (x,x) -- I prefer reading function composition from left-to-right andThen = flip (.) -- Uses < instead of == to preserve set-like structures x === y = not (x < y || y < x) -- PRE : Arg is sorted -- POST: Result is set-like removeDupsFromSorted :: Ord a => [a] -> [a] removeDupsFromSorted = nubBy (===) -- POST: Result is set-like sortAndRemoveDups :: Ord a => [a] -> [a] sortAndRemoveDups = sort `andThen` removeDupsFromSorted -- PRE : Args are set-like -- POST: Result is set-like, the sorted union of args merge as [] = as merge [] bs = bs merge aas@(a:as) bbs@(b:bs) | a < b = a : merge as bbs | b < a = b : merge aas bs | otherwise = a : merge as bs

seems Simon has got himself a tricky problem. i was about to hit reply to his first call, but then i browsed through the oscon site, and thought that perhaps my background isn't close enough to the intended audience to make useful suggestions, not to mention the concrete examples asked for. but while there have been good suggestions, i still feel there are some general trends/ideas missing: - oscon seems to be a huge event. on the negative side, that means that if the pre-talk advertising isn't good enough (mainly abstract and general buzz, i guess), there won't be much of an audience, as there are too many other things going on. on the positive side, that means that almost no advertising should be needed in the talk itself - if people aren't interested, they won't be there. that kind of breaks the usual strategy for talking to non-haskellers. - it will still be necessary to convince the attendees, not that haskell is worth looking into, but that their first 3 hours of doing so has been time well spent, and a quick rehash of all the other wonderful things haskellers have been up to might be a small part of that, but it won't be sufficient. - 3 hours is long for a talk, but distressing for a tutorial: too short to really get the functional style of programming across to imperative/oo programmers, yet too long to stay within small and safe examples (thereby avoiding explanations of haskells more complicated sides). - i would expect the audience to be a similarly mixed blessing: imperative mindsets liable to stumble over even simple functional programming patterns, but at the same time too experienced to be impressible with toy examples. in light of all this, Simon's approach seems promising:
concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
working code for one or two compelling examples, engagingly presented, should have a chance of giving that audience some value for money. and perhaps it is best not to dwell on how different functional programming is - given that there isn't all that much time to get acquainted, it might be best to jump right in with "here's what you can do, and this is how you do it". people who pick up weird things like ajax, .. must be used to getting into strange lands, as long as they have good guidance, and useful examples. don't get bogged down in language features (there's reference manuals and tutorials for that), but focus on techniques and on achieving things. still, the central issue remains: how to present them with something that their current background tells them would be interesting, useful, and understandable, while at the same time presenting something that demonstrates haskell's advantages and culture. as i said, i can't offer concrete examples for that kind of audience, but let me report one experience that might be helpful: how i got into perl;-) at the time, i was doing lots of shell-scripting, and i thought that awk was about the most wonderful unix tool ever. what i was actually using awk for were two features: sets of rules triggered by pattern matching, and associative arrays for storing away the information extracted using those patterns. if you could express your problem in terms of these two, it would just disappear into thin air (clever storage tricks obviated any need for further processing). but if you couldn't, things would get awkward: processing data within awk's programming language wasn't fun, processing data within some shell wasn't much better (and at the time there were just too many shells, all with their own community, advantages and shortcomings). but the worst thing of all was passing data between scripts written in different tools (shell, awk, sed, make, ..), integrating the whole mess, maintaining and extending it. then someone suggested perl4, and i had to figure out whether i wanted to know more about it (new syntax, new concepts, and all that..). fortunately, there was a little tool for converting awk scripts to perl, allowing me to compare my old scripts with the new syntax. that immediately got me into a little of perl's control structures, and it was clear that perl's syntax for pattern processing was inspired by sed, just as its associative arrays were inspired by awk. so i could dump my awk, my sed, and my shells, and do it all in perl - i was convinced. i still use shells and sed for small things, and make for what it is good at, but i stopped using my favourite awk, and when multiple tasks needed to be integrated, i started to prefer perl. if i extrapolate from this experience to Simon's current adventure: powerful examples showing off perl's/haskell's features would sail right by me ("nice, but what does that have to do with me?" at best, "aargh, that looks very complicated; perhaps another time" at worst); small examples showing that perl/haskell can do what my current tools can already do just as well or better wouldn't even elicit much interest ("oh, yeah? so what?"). what would convince me to get started are two things: a general pattern showing me how to address my typical problems in perl/haskell, and the realisation that my hacking life would become simpler by integrating the work of different tools into one. for perl, the pattern was roughly: take your awk scripts, split them into pattern matching and associative array access, then write a perl loop to do just that; take your sed scripts and just inline the commands into your perl script; take the logic you were trying to express in your shell, and express it in a proper imperative language in perl (that was before oo perl); once you've done all that, forget the complexities of integrating all the pieces/syntaxes/string escape variants/pattern format differences/.. just manage it all in one script [that this was actually a step forward is all the more impressive given the unix shell philosphy of being a framework in which to integrate/compose lots of little tools]. for haskell, what would be the equivalent patterns, integration, and simplification advantages? my personal favourite would have to be domain-specific languages: to solve a problem, iteratively design the constructs/functions/data structures that make up a suitable language for describing said problem, all the while prototyping that domain-specific language in haskell; once you have the dsl, model your problem, and run it; if you have different kinds of problems, you'll have different dsls, but they'll all be embedded into the same general purpose language, so they'll share some features, and models in different dsls can fairly easily be integrated. dsl modelling is not unlike oo modelling, but instead of expressing everything as objects and classes, you express everything as whatever concepts are relevant to your domain, and haskell also provides an executable meta-modelling and integration language. now, whether this personal favourite is of any use with the oscon audience is another question, and the general interest has certainly shifted from local network scripting with shells to www scripting with browsers. we are still talking about pattern extraction/data storage/data processing/result presentation, but haskell's standard library support for www programming is still not quite up to the same levels as perl's (practical extraction and report language, well targetted). perhaps, i'd suggest a local scripting example to start with, followed by a www scripting example to build on; in both cases, i'd emphasize the embedded dsl approach. select or define suitable edsls for each of the phases/aspects of your typical problem: regular expressions/ parser combinators for the pattern extraction aspect; algebraic data types for data representation; Data.Map or a functional database interface for the data storage aspect; functional and monadic programming for the sequential data processing aspect; concurrent haskell, stm, and nested parallelism for non-sequential processing; pretty-printing and gui libraries for the result presentation aspect. it doesn't matter much what the two examples are, as long as they exhibit the haskell edsl approach to problems, and some generally useful edsl examples, rather than details of complicated language features. as the examples need to fit into the 3 hours, preferably with some interaction, they need to give a lot of bang for the buck. so instead of politically correct XML processing of well-formed RSS feeds (hah!-), one might take something radically simple, like Neil's tagsoup, then focus on the points one would want to demonstrate, rather than the example itself: http://www-users.cs.york.ac.uk/~ndm/tagsoup/ the source code for that library is almost criminally simple (and might need some minor improvements before demonstrating it), yet it allows us to approach web-scripting with the same level of intentional ignorance that made awk and perl so successful ("what do you mean, parsing? the world is based on regular expressions, all the way down!"). spice that up with proper regexps, some minimal parsing and pretty printing (gui, if you dare;-), some concurrency for tracking different sites, a little bit of data representation and processing, all expressed in their own dsls, all of which embedded in haskell, simply imported as modules, integrated in functional monadic code, and you might have the core of a small but useful example? definitely do a little daring online rewriting, just to demonstrate that the type-system tells you that the interface of a component allows it to be moved without unexpected side-effects. and since its a demo, be prepared for unexpected side-effects anyway!-) good luck! hth, claus

Claus Reinke wrote:
- oscon seems to be a huge event.
A bold idea would be to redo a talk of another speaker in Haskell and "accidentally" surpass the techniques presented there :) Alas, this doesn't work for OSCON since there are too many talks attendees have to choose between and the event starts with the tutorials, so the audience doesn't know a common talk it could compare the Haskell tutorial to. Regards, apfelmus

Closures look like magic to those who don't know them. So you might try something like this (which I have not compiled BTW):
-- Haskell version
data Train = Train {departs :: Time, platform :: Int }
departsBefore :: Time -> Train -> Bool departsBefore t train = t < departs train
beforeAfter :: Time -> [Train] -> ([Train], [Train]) beforeAfter t = partition (departsBefore t) departures
The crucial point is that "partition" takes a function argument, but that function has to carry the 't' argument with it. The only way you could write "partition" as a generic function in Java would be to define an interface class "discriminator" which is passed to "partition". "discriminator" is then specialised for every closure you want to create. This is a lot of code for something that can be done in-line in Haskell. The fact that all functions are curried by default also saves having lots of lambdas. You might also show how deforestation optimises functional pipelines. Lots of Haskell code contains lines of the form
foo = bar x $ foldr1 boz $ map baz ls
In other FP languages (like Erlang) you can use this style, but it tends to be inefficient because of all the intermediate lists. Haskell is free to arrange the functions how it likes because of purity. Hence it can optimise this pipeline into a single loop. Obviously you know much more about this than I do, but to me its one of the biggest arguments in favour of purity. Paul.

Since no one mentioned automatic differentiation (AD), I will. I think AD is a nice example of using type classes and higher order functions to get small and useful code. Maybe this example is not ideal for the audience, but anyway, Simon has the last word. Here is how demo would go: Define a polynomial with roots at -9, 0 and 9:
Main> let poly x = (x + 9) * x * (x - 9)
check type:
Main> :t poly poly :: (Num a) => a -> a
then explain type and handwave a bit about the polymorphism +overloading and the type. Check that it works:
Main> poly 2 -154 Main> poly 9 0
Aha, it works. Let's see a graph then (sorry if the email formatting destroys the graph):
Main> draw poly ****** | * *** | ** * | * ** | * *| --*-----------------**----------------*- * | ** * | * ** * | *** * | ******
"Oh did I mention that 'draw' is a higher order function?" (handwavy explanation of H.O. functions, bla bla)
Main> :t draw draw :: (Double -> Double) -> IO ()
Now define, first derivative of "poly":
Main> let poly' x = d poly x
(Note that x is required because of monomorphism restriction, but I wouldn't mention it). and test it:
Main> draw poly' * | * | * ** | ** * | * * | * ** | ** ** | ** ----------**-----------------**--------- **** | **** *********
one can do it once again:
Main> let poly'' x = d poly' x Main> draw poly'' | *** | **** | **** | ***** --------------------****---------------- ****| ***** | **** | **** | *** |
The nice thing is that the code for "d" is very small (unlike the drawing code, for example):
data Dual a = Dual a a deriving (Eq,Show)
instance (Num a) => Num (Dual a) where (Dual x y) + (Dual x' y') = Dual (x+x') (y+y') (Dual x y) * (Dual x' y') = Dual (x*x') (x*y'+y*x') negate (Dual x y) = Dual (negate x) (negate y) fromInteger n = Dual (fromInteger n) 0
(omitting some methods here) Below, "d is a H.O. function bla bla"
type Poli = forall a.(Num a) => a -> a
d :: Poli -> Poli d f x = case f (Dual x 1) of Dual f_x f'_x -> f'_x
end of pseudo-demo This code is based on a blog post[1] which is in turn based on some nice posts by Dan Piponi. It's nothing new, but it's worthwhile to stress how easy it is to do this kind of thing in Haskell. Cheers, Alexey [1] http://insomne.pinguinos.org/2006/06/25/derivacion-automatica- utilizando-numeros-duales-y-clases-type-classes/ On Apr 19, 2007, at 10:05, Simon Peyton-Jones wrote:
| Simon (aka Dumbledore) is speaking to four different Houses: scientists | (Ravenclaw), engineers (Hufflepuff), entrepreneurs (Slytherin), and | managers (Griffindor).
I wish I could live up to this image!
Lots of interesting ideas on this thread, and Haskell-Cafe threads are *supposed* to wander a bit. But, just to remind you all: I'm particularly interested in
concrete examples (pref running code) of programs that are * small * useful * demonstrate Haskell's power * preferably something that might be a bit tricky in another language
I have lots of *general* ideas. What I'm hoping is that I can steal working code for one or two compelling examples, so that I can spend my time thinking about how to present it, rather than on dreaming up the example and writing the code.
(But don't let me inhibit wider-ranging discussion as well.)
thanks
Simon _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

I don't know how many of the other people on this list are actually going to *be* at OSCON. I will. I think it is important to think about the kinds of problems the audience is trying to solve, as well as the context in which they are trying to solve them. For the most part, the attendees at OSCON work on system software: operating systems, operating system services (printing, packaging, scheduling, etc), network & distributed computing infrastructure, databases, languages, and every imaginable variation on the word web. 1) Build a simple database access layer that is immune to SQL injection attacks from user input (using the type system to guarantee that safety). Include the FFI portion (FFI is a point of paranoia about any "new" language). Now the, the audience values the type system. 2) Show something appallingly simple, yet blazingly fast. Demonstrate that it is blazingly fast. I would implement "wc -l" using data.Bytestring.lazy and run in over a huge file. It's a one line program and it will run faster than the built in unix command. Explain that its fast because of GHCs rewrite rules. Explain that the rewrite rules are only possible because of purity. Now the, the audience values purity. 3) Build a simple combinator framework that supports multiple evaluation schemes (like your derivative framework that supported both valuation and settlement processes). For this audience, it might be cool to build a simple package system that both installed software and later verified the integrity of the installation. Although, if you *wanted* to present "How to write a financial contract" I could not object. Quantitative finance is my business and I promise to be in the audience for this. Also, see if Audrey Tang is going to be present. If she is, consider enlisting her support. Haskell has *enormous* credibility in the Perl 6 community because of PUGS. I recently had a conversation with Jesse Vincent, the Perl 6 program manager. He said that the majority of the Perl 6 community is aware that PUGS (and therefore Haskell) are crucial to the success of Perl 6. Perl has its own track at this conference. reilly hayes

Henning Thielemann wrote:
On Wed, 18 Apr 2007, Dan Weston wrote:
You have already won over the scientists.
I only know few mathematicians using Haskell, most of the (applied) mathematician colleagues I know prefer MatLab.
Blehr! >_< I hate MatLab... it's horrid! (OTOH, I'm not a "real" mathematition, so...)

On May 21, 2007, at 14:15 , Andrew Coppin wrote:
Henning Thielemann wrote:
I only know few mathematicians using Haskell, most of the (applied) mathematician colleagues I know prefer MatLab. I hate MatLab... it's horrid!
Everyone hates Matlab. Problem is, it's hard to find anything like its toolkits.... -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

(aside to Dylan T: I hope you don't mind me advertising your (well, public) web pages here. In my opinion a lot more people should know about the stuff that both you and Ken are doing!) Here's an example of some great math being done in haskell: http://www.math.columbia.edu/~dpt/genus2fiber/ (the code for this paper): http://arxiv.org/abs/math.GT/0510129 On Mon, 21 May 2007, Brandon S. Allbery KF8NH wrote:
On May 21, 2007, at 14:15 , Andrew Coppin wrote:
Henning Thielemann wrote:
I only know few mathematicians using Haskell, most of the (applied) mathematician colleagues I know prefer MatLab. I hate MatLab... it's horrid!
Everyone hates Matlab. Problem is, it's hard to find anything like its toolkits....
-- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (25)
-
ajb@spamcop.net
-
Alexey Rodriguez Yakushev
-
Andrew Coppin
-
apfelmus
-
Brandon S. Allbery KF8NH
-
Bryan O'Sullivan
-
Cale Gibbard
-
Claus Reinke
-
Clifford Beshers
-
Dan Weston
-
DavidA
-
Derek Elkins
-
Dipankar Ray
-
Duncan Coutts
-
Henning Thielemann
-
Isaac Dupree
-
Justin Bailey
-
Lennart Augustsson
-
Mirko Rahn
-
Paul Johnson
-
R Hayes
-
Seth Gordon
-
Simon Peyton-Jones
-
Steve Downey
-
Tillmann Rendel