
I'm looking for cool but mind-bending examples of functional brilliance. Let us say, hypothetically, you had a bathroom without any reading material. And having read all the Dilbert and Garfield you could seriously stomach, decide you should educate yourself while "on the job". :-) So you decide to print up some "one-liner" style programs into a little booklet. Something between credit-card and postcard sized, with a neat but mind-bending program on it. Don Stewart occasionally swoops in with some fixpoint malarkey to defuse heated discussions. I mean that kind of thing, but with a slightly wider scope than just fibs... Suggestions, please! D.

On 8/14/07, Dougal Stanton
I'm looking for cool but mind-bending examples of functional brilliance.
Let us say, hypothetically, you had a bathroom without any reading material. And having read all the Dilbert and Garfield you could seriously stomach, decide you should educate yourself while "on the job". :-)
So you decide to print up some "one-liner" style programs into a little booklet. Something between credit-card and postcard sized, with a neat but mind-bending program on it. Don Stewart occasionally swoops in with some fixpoint malarkey to defuse heated discussions. I mean that kind of thing, but with a slightly wider scope than just fibs...
Suggestions, please!
D. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Maybe: http://www.haskell.org/haskellwiki/Blow_your_mind and: http://haskell.org/haskellwiki/Research_papers/Functional_pearls regards, Bas van Dijk

On Tue, 2007-08-14 at 17:22 +0200, Bas van Dijk wrote:
On 8/14/07, Dougal Stanton
wrote: I'm looking for cool but mind-bending examples of functional brilliance.
Maybe:
http://www.haskell.org/haskellwiki/Blow_your_mind http://haskell.org/haskellwiki/Research_papers/Functional_pearls
The "Evolution of a Haskell Programmer" is cute: http://www.willamette.edu/~fruehr/haskell/evolution.html -k

On Aug 14, 2007, at 11:17 , Dougal Stanton wrote:
Let us say, hypothetically, you had a bathroom without any reading material. And having read all the Dilbert and Garfield you could seriously stomach, decide you should educate yourself while "on the job". :-)
Sounds to me like you want a waterproof panel displaying #haskell. :) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Tuesday 14 August 2007 10:17:53 Dougal Stanton wrote:
I'm looking for cool but mind-bending examples of functional brilliance.
Let us say, hypothetically, you had a bathroom without any reading material. And having read all the Dilbert and Garfield you could seriously stomach, decide you should educate yourself while "on the job". :-)
So you decide to print up some "one-liner" style programs into a little booklet. Something between credit-card and postcard sized, with a neat but mind-bending program on it. Don Stewart occasionally swoops in with some fixpoint malarkey to defuse heated discussions. I mean that kind of thing, but with a slightly wider scope than just fibs...
Suggestions, please!
D.
Here's a small puzzle: without using a Haskell interpreter, explain what the 'foo' function does.
foo = filterM (const [True, False])
In case you aren't familiar, here's the definition of filterM:
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a] filterM _ [] = return [] filterM p (x:xs) = do flg <- p x ys <- filterM p xs return (if flg then x:ys else ys)
Cheers, Spencer Janssen

On 2007-08-14, Spencer Janssen
On Tuesday 14 August 2007 10:17:53 Dougal Stanton wrote:
I'm looking for cool but mind-bending examples of functional brilliance.
Let us say, hypothetically, you had a bathroom without any reading material. And having read all the Dilbert and Garfield you could seriously stomach, decide you should educate yourself while "on the job". :-)
So you decide to print up some "one-liner" style programs into a little booklet. Something between credit-card and postcard sized, with a neat but mind-bending program on it. Don Stewart occasionally swoops in with some fixpoint malarkey to defuse heated discussions. I mean that kind of thing, but with a slightly wider scope than just fibs...
Suggestions, please!
D.
Here's a small puzzle: without using a Haskell interpreter, explain what the 'foo' function does.
foo = filterM (const [True, False])
powerset. Very nice use of the list monad. -- Aaron Denney -><-

Someone mentioned the "Blow your mind" page. One example there really caught my attention. "1234567" => ("1357","246") foldr (\a ~(x,y) -> (a:y,x)) ([],[]) I've known about lazy match since an early version of the Haskell report, but have never actually used it. Last night, looking at that example, the lights went on and I finally grokked why it's there and understood when/why I might use it myself. Oh, I knew perfectly well what it does. It just never made itself at home in my head. I'd like to recommend this example for some sort of prize, therefore.

I hate to be a party pooper, but isn't this just:
f = foldr (\a z -> (a:snd z,fst z)) ([],[])
This takes less time to grok and takes no longer to run. But why stop there?
import Control.Arrow swap = snd &&& fst
f = foldr (\a -> swap >>> first (a:)) ([],[])
Just read this aloud to see what it does (without the tilde encryption algorithm at work!). More importantly, there is manifestly no pattern failure to check for here. It is fun that with ~p we don't need deconstructors for p (reminds me of Lisp's setf), but how many types have exported constructors with no deconstructors? And Arrow notation makes up for the loss of fun, so you don't feel cheated. :) Dan P.S. Either doesn't count, because you can easily roll your own deconstructors: getLeft = either id undefined getRight = either undefined id but I honestly don't know why these aren't in Data.Either. Or for that matter, why swap is not in Control.Arrow, since it comes in handy quite frequently with pointless programming. ok wrote:
Someone mentioned the "Blow your mind" page. One example there really caught my attention. "1234567" => ("1357","246") foldr (\a ~(x,y) -> (a:y,x)) ([],[])
I've known about lazy match since an early version of the Haskell report, but have never actually used it. Last night, looking at that example, the lights went on and I finally grokked why it's there and understood when/why I might use it myself.
Oh, I knew perfectly well what it does. It just never made itself at home in my head.
I'd like to recommend this example for some sort of prize, therefore.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Dan Weston wrote:
I hate to be a party pooper, but isn't this just:
f = foldr (\a z -> (a:snd z,fst z)) ([],[])
This takes less time to grok and takes no longer to run.
For each type with exported constructors, one can always write deconstructors for it, if not already found in libraries. One may then argue that ~ is never necessary. Given f ( ~(Left (z0,_)) : Right ~(Just z1) : xs ) = (z0, z1, xs) you can always hand-compile to f (x0 : Right y1 : xs) = (fst (getLeft x0), fromJust y1, xs) But ~ is desirable: 0. Which version is easier to understand? That is a bit subjective, but I think it comes down to this. (As do all debates over whether concise notation is readable, really.) To a kid who has not learned the word "arctan", I have to say, "draw this right-angled triangle, with this side being length 3, that side being length 4, now measure this angle, that is what I mean by arctan(3/4)" - you know, all the details, step by step, hand in hand. To a learned adult, I can just say, "arctan". In fact, if I spelt out the details to the adult, step by step, hand in hand, he/she would think I'm condescending or counterproductive. Specifically in the case of ~, it makes transparent the structure of the data to be expected: By just reading one spot, you see it wants a list of two or more items, the first item is a Left, in which there is a tuple, the second item is a Right, in which there is a Just. That same information is torned apart without ~: part of the information is on the left, and the rest is hidden on the right to be recovered from the deconstructor calls and re-constructing the picture in your head. This is because it is more low-level. The "what" is encoded beneath the "how". You follow the code execution and then you reverse-engineer its purpose. It is quite attractive when you have no notation to denote the purpose. It is a poor choice when you have a notation to denote the purpose: "what" data parts are wanted, and "when" they are wanted, without reading a single function call, the "how". 1. Which version is easier to change strictness? Strictness and non-strictness are tricky to get right for performance or even mere feasibility. An important programming activity is investigating various levels of strictness. It is imperative to be able to change strictness efficiently. ~ is already a non-strictness annotation. Anyone who already understands the ! strictness annotation understands this one too. By just toggling ~'s you toggle non-strictness. It's that easy to change. Here is the function again. I'm going to change its strictness. f ( ~(Left (z0,_)) : Right ~(Just z1) : xs ) = (z0, z1, xs) I now want the second cons to be later, the Left to be earlier (at the same time as the first cons), the tuple to be later, the Right to be later (even later than the second cons), and the Just to be earlier (at the same time as the Right). I can do that by just toggling ~'s: f ( Left ~(z0,_) : ~(~(Right (Just z1)) : xs) ) = (z0, z1, xs) Without ~, much more change is necessary. Here is the non-~ code before change again: f (x0 : Right y1 : xs) = (fst (getLeft x0), fromJust y1, xs) The change is: f (Left y0 : xs) = (fst y0, fromJust (getRight (head xs)), tail xs) Both sides have to be changed. On the left, the data structure has to be changed. On the right, the function call structure has to be changed. You have to remove a constructor on the left and add a deconstructor on the right, or add a constructor on the left and remove a deconstructor on the right. This is a dream come true for IDE marketeers. This code manipulation is too annoying to be done by hand on a daily basis, yet mechanical enough to be done by software easily. A marketeer can sell an IDE plugin for this and garner much money and gratitude from unsuspecting programmers, capitalizing on the fact that some languages do not provide an annotation to trivialize this whole business, and in those that do, some programmers refuse to use it.

ok-4 wrote:
Someone mentioned the "Blow your mind" page. One example there really caught my attention. "1234567" => ("1357","246") foldr (\a ~(x,y) -> (a:y,x)) ([],[])
I've known about lazy match since an early version of the Haskell report, but have never actually used it. Last night, looking at that example, the lights went on and I finally grokked why it's there and understood when/why I might use it myself.
Don't you want an infinite list to illustrate the necessity of laziness? -- View this message in context: http://www.nabble.com/Bathroom-reading-tf4267956.html#a12196642 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

So you decide to print up some "one-liner" style programs into a little booklet. Something between credit-card and postcard sized, with a neat but mind-bending program on it. Don Stewart occasionally swoops in with some fixpoint malarkey to defuse heated discussions. I mean that kind of thing, but with a slightly wider scope than just fibs...
Clearly, we need to actually put together such a book! I'm imagining something where you have two mostly blank facing pages, with the code by itself in the middle of the right page; then the next 2-4 pages devoted to a short discussion of the code, how it works, related issues and techniques, and a list of references. All featuring beautiful typography and fantastic writing, of course. =) -Brent

On 14/08/07, Brent Yorgey
Clearly, we need to actually put together such a book! I'm imagining something where you have two mostly blank facing pages, with the code by itself in the middle of the right page; then the next 2-4 pages devoted to a short discussion of the code, how it works, related issues and techniques, and a list of references. All featuring beautiful typography and fantastic writing, of course. =)
Oh indeed! This wasn't *completely* idle chatter on my part. I used to work in a print shop and we did a lot of work for art and architecture students who would do this kind of thing all the time. Fantastic little notebook-style gifts of images and blank pages and elegant typography. It's just a shame so many of them were terrible at spelling! :-P It shouldn't be too difficult to use LaTeX to this end. Once a document class has been hammered out you can offer a range of different booklets! The "Evolution of a Haskell Programmer" series would be a good place to start. Bring it to your next job interview to whip out when someone points to that bit on your CV and says, "what's that?". Any skilled TeXers in the house? D.

On 8/14/07, Dougal Stanton
On 14/08/07, Brent Yorgey
wrote: Clearly, we need to actually put together such a book! I'm imagining something where you have two mostly blank facing pages, with the code by itself in the middle of the right page; then the next 2-4 pages devoted to a short discussion of the code, how it works, related issues and techniques, and a list of references. All featuring beautiful typography and fantastic writing, of course. =)
Oh indeed! This wasn't *completely* idle chatter on my part. I used to work in a print shop and we did a lot of work for art and architecture students who would do this kind of thing all the time. Fantastic little notebook-style gifts of images and blank pages and elegant typography. It's just a shame so many of them were terrible at spelling! :-P
It shouldn't be too difficult to use LaTeX to this end. Once a document class has been hammered out you can offer a range of different booklets! The "Evolution of a Haskell Programmer" series would be a good place to start. Bring it to your next job interview to whip out when someone points to that bit on your CV and says, "what's that?".
Any skilled TeXers in the house?
D.
Well, it wasn't completely idle chatter on my part, either! =) After spending the past year writing (and typesetting) a mathematics book in my spare time, I would consider myself an intermediate to advanced user of LaTeX, although I know much less about TeX itself than I would like (although I do intend to learn). Unfortunately, what with applying to grad school and other things, it probably wouldn't be wise for me to spearhead such a project at the moment, although I'd be excited about contributing. But I very well might pick it up at a later date if no one decides to run with it right now. -Brent

On 8/14/07, Dougal Stanton
I'm looking for cool but mind-bending examples of functional brilliance.
One of my favourite examples is: http://citeseer.ist.psu.edu/hinze99functional.html Anyone who studies binomial heaps is struck by the similarity to binary arithmetic. What Hinze does is formalise that similarity so that binomial heaps and binary numbers are instances of the same type class. Very pretty. -- Dan
participants (12)
-
Aaron Denney
-
Albert Y. C. Lai
-
Bas van Dijk
-
Brandon S. Allbery KF8NH
-
Brent Yorgey
-
Dan Piponi
-
Dan Weston
-
Dougal Stanton
-
Ketil Malde
-
Kim-Ee Yeoh
-
ok
-
Spencer Janssen