Learning Functional Programming through Multimedia
As the title implies, The Haskell School of Expression introduces functional programming through the Haskell programming language and through the use of graphics and music. It serves as an effective introduction to both the language and the concepts behind functional programming. This text was published in 2000, but since Haskell 98 is the current standard, this is still a very relevant book.
Haskell's standardization process gives us a window into two different facets of the community: Haskell is designed to be both a stable, standardized language (called Haskell 98), and a platform for experimentation in cutting-edge programming language research. So though we have a standard from 1998, the implementations (both compilers and interpreters) are continually evolving to implement new, experimental features which may or may not make it into the next standard.
For instance, the Glasgow Haskell Compiler has implemented a meta-programming environment called Template Haskell. Haskell is also easy to extend in directions that don't change the language itself, through the use of Embedded Domain-Specific Languages (EDSLs) such as WASH for web authoring, Parsec for parsing, and Dance (more of Paul Hudak's work) for controlling humanoid robots.
Before we get too far, I should offer a disclaimer: The Haskell community is rather small, and if you scour the net, you may find conversations between myself and Paul Hudak or folks in his research group, since I use some of their software. That said, I don't work directly with Hudak or his research group.
In fact, the small size of the Haskell community is a useful feature. It is very easy to get involved, and folks are always willing to help newbies learn, since we love sharing what we know. You may even find that if you post a question about an exercise in The Haskell School of Expression , you'll get a reply from the author himself.
I consider this book to be written in a "tutorial" style. It walks the reader through the building of applications, but doesn't skimp on the concepts (indeed, the chapters are meant to alternate between "concepts" and "applications"). In some ways, the code examples make it a little difficult to jump around, since you are expected to build upon previous code. The web site provides code, however, so you can always grab that and use it to fill in the missing pieces.
For readers who wish to use this book as a tutorial, and to implement all of the examples (which is highly recommended), I suggest that you grab the Hugs interpreter and read the User's Guide while you're reading the first few chapters of The Haskell School of Expression. Hugs is very portable, free, and easy to use. It also has an interface with Emacs. Unfortunately, some of the example code has suffered from bit-rot, and certain things don't work out-of-the-box for X11-based systems. The bit-rot can be solved by using the "November 2002" version of Hugs. This is all explained on SOE's web page.
The Haskell School of Expression should be very effective for programmers who have experience in more traditional languages, and programmers with a Lisp background can probably move quickly through some of the early material. If you've never learned a functional language, I highly recommend Haskell: Since Haskell is purely functional (unlike Lisp), it will more or less prevent you from "cheating" by reverting to a non-functional style. In fact, if you've never really looked at functional programming languages, it may surprise you to learn that Haskell has no looping constructs or destructive assignment (that is, no x = x + 1). All of the tasks that you would accomplish through the use of loops are accomplished instead through recursion, or through higher-level abstractions upon recursion.
Since I was already comfortable with recursion when I started this book, it is hard for me to gauge how a reader who has never encountered recursion would find this book's explanation of the concept. The Haskell School of Expression introduces recursion early on, in section 1.4. It is used in examples throughout the book, and if you follow along with these examples, you will most certainly be using it a lot. The introduction seems natural enough to me, but I note that Hudak does not give the reader any extra insight or tricks to help them along. Not to worry, though; recursion is very natural in Haskell and the reader may not even notice that they are doing something a little tricky.
The use of multimedia was a lot of fun for me, and should quickly dispel the myth that IO is difficult in Haskell. For instance, Hudak has the reader drawing fractals by page 44, and throughout the book, the reader will be drawing shapes, playing music, and controlling animated robots.
Any book on Haskell must be appraised for its explanation of monads in general and IO specifically. Monads are a purely functional way to elegantly carry state across several computations (rather than passing state explicitly as a parameter to each function). They are a common stumbling block in learning Haskell, though in my opinion, their difficulty is over-hyped.
Since input and output cause side-effects, they are not purely functional, and don't fit nicely into a function-call and recursion structure. Haskell has therefore evolved a way to deal safely and logically with IO through the use of monads, which encapsulate mutable state. In order to perform IO in Haskell, one must use monads, but not necessarily understand them.
Some people find monads confusing; I've even heard a joke that you need a Ph.D. in computer science in order to perform IO in Haskell. This is clearly not true, and this book takes an approach which I whole-heartedly agree with. It gets the reader using monads and IO in chapter 3 without explaining them deeply until chapters 16 (IO) and 18 (monads). By the time you get there, if you have heard that monads are confusing, you might be inclined to say "how is this different from what we've been doing all along?" Over all, I was pleased with the explanation of monads, especially state monads in chapter 18, but I felt that the reader is not given enough exercises where they implement their own monads.
If you're worried that drawing shapes and playing music will not appeal to your mathematic side, you will be pleased by the focus on algebraic reasoning for shapes (section 8.3) and music (section 21.2), and a chapter on proof by induction (chapter 11).
After reading this book you will be prepared to take either of the two paths that Haskell is designed for: You can start writing useful and elegant tools, or you can dig into the fascinating programming language research going on. You will be prepared to approach arrows, a newer addition to Haskell which, like monads, have a deep relationship to category theory. Arrows are used extensively in some of the Yale Haskell group's recent work. You will see a lot of shared concepts between the animation in The Haskell School of Expression and Yale's "Functional Reactive Programming" framework, Yampa. If you like little languages, you'll appreciate how useful Haskell is for embedded domain-specific languages. It may be even more useful now that Template Haskell is in the works. Andrew Cooke described Purely Functional Data Structures as a great second book on functional programming. In my opinion, The Haskell School of Expression is the great first book you're looking for.
You can purchase Learning Functional Programming through Multimedia from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
If there's no Apache module for it, it's not a real language. End of discussion.
but chugging mountain dews and microwaving hot pockets are things that have to be learned through experience. Books are always a great source, but the lifestyle behind the teachings of the book can't be taught.
I've read this book and think this is a good book for learning Haskell (perhaps the best one) and that it explains monads well.
However, it won't get the reader fully up and running as a productive Haskell programmer, because for that it is basically required that you master the GHC's (Glorious/Glasgow Haskell Compiler) standard library. Otherwise you won't know how to use a fast unboxed array, etc. This library is actually intelligently designed, but it is poorly documented, and there are lots of quirks for people who aren't totally familiar with Haskell yet. The best way to learn still seems to be to read the Haskell newsgroup and look at other people's code.
But Haskell is an extremely interesting language and well worth learning IMHO.
They've got a whole course online! FOR FREE!
REM Old programmers don't die. They just GOSUB without RETURN.
Haskell is perhaps best known for its use of the bottom operator. When parenthetised, its ASCII representation looks kinda like a...
Well, I'll let you be the judge: (_|_)
The day I can use Haskell to compile and output Flash files I'll be happy. Or cry. I'm not sure which at this point.
-Rob
Marriage doesn't have to suck!
Anyone noticed how incredibly unpractical Haskell is? It sacrifices too much by taking the FP purity too far.
;-).
:).
Also, apparently the Haskell people are way too intimately associated with Microsoft (isn't Cambridge some kind of Microsoft stool pigeon these days?). One just *has* to suspect that they are up to no good. We need to inspect this connection further before giving them the benefit of a doubt
Yes, I truly felt like burning some of that Karma of mine
Save your wrists today - switch to Dvorak
lack of SMP support in Erlang and Haskell really makes them hard to choose for enterprise projects.
If you want to see some Haskell code, I have some more concrete examples here:
I have written a lot of little projects in Haskell. You can find some of them in links from my user info page.
Also, one of the best resources on Haskell is the HaWiki: HaWiki.
Do give Haskell a try. It is an amazing programming language.
Easy, automatic testing for Perl.
I just can't understand why it's not used more. Personally I feel I was taught Haskell too early.. I was taught in my first weeks at uni before I even knew C. At the time I really struggled, all I knew about programming was BASIC and Haskell seemed alien and I hated it and dismissed it completely until recently. Now that I have much more experience of programming and functional languages I sometimes wonder why I ever touch C++ or Java. If I'd be taught Haskell in my penultimate or final year of university I'm pretty sure I'd have taken to it far more kindly.
Cure cancer.. and stuff! www.team45.info
They've got a whole course online! FOR FREE!
Wow. That's indeed a good argument to scrap all those undocumented OSS languages we have been using for the past 10-15 years.
Save your wrists today - switch to Dvorak
Today, if you don't have enough flashy multimedia to attract the user to stay and look at what you have to say, you never even get your foot in the door. Chances are that someone who has taken the time to learn to both use the technology and apply it in a meaningful way probably has something to say.
With a generation of multimedia oriented programmers available I expect to see a much higher degree of interactivity in many different areas, from thing like mouse gestures to multi-dimensional navigation metaphores where we can simultaniously demonstrate our interests and our abilities so that we can arrive at the appropriate 'step' in whatever process we are trying to achieve.
"Can there be a Klein bottle that is an efficient and effective beer pitcher?"
Since I was already comfortable with recursion when I started this book, it is hard for me to gauge how a reader who has never encountered recursion would find this book's explanation of the concept.
Who is the target audience for this book? I would assume programmers, of at least moderate experience. It's not like there are thousands of script/VB kiddies jumping over themselves to learn functional languages. Makes me wonder, how many semi-experienced programmers are there out there who aren't comfortable with using/understanding recursive functions?
Functional language are only good in theory. Sure, you can easily write programs in them, but they abstract over how the program is executed. And the programs are going to be executed in an imperative manner; machine code is imperative, remember?
Thus, there's a MASSIVE performance loss when a functional programming language is executed on any of the existing processors. Because the compilers can't think and optimise the code to best fit the imperative model. Where as the human being s can. That's why we should stick to imperative programming languages.
The day someone actually invents a function processor, we could start promoting these fringe langauges. Till then, let's keep Haskell as part of CS811
Thank you for listening. That's the end of my rant.
Indefinitely Detained US Citizen
way back when in college, the most interesting thing was that the program couldn't do I/O during the execution, only as an exit value. That makes useful daily programs difficult to write in a 'purely functional' language. The review talks about monads being a solution, but I can't see that putting something on the screen our worse a printer is something that can be undone. Therefore, I/O must be a side-effect, so how can a real 'purely functional' language like haskel do I/O?
Awesome furniture, accessories and cabinetry in Santa Rosa, CA: http://humanity-home.com/
I think that there is a problem with newer programmers going into a language such as say, java, or C#. When i learned programming i learned C++ in ms-dos. We wrote our own string classes, used pointers, learned ADT's like, linked lists, and binary trees. Nowadays in java you write a program and use everyone elses stuff. there is a linked list class in Miscrosoft's .NET framework. Nothing is ever written from scratch anymore. IMHO you cant learn actual programming without getting into the nitty gritty your self.
Do people think it's a good thing for a C++/Java/.NET programmer to go back to the drawing board for a few months and learn stuff like functional programming? I thought about coming up with a syllabus for myself of C, Haskell, LISP and Perl (which just evades me....)
Vacancy for signature. Apply within.
mod_haskell
I think these guys have you covered.
my sig's at the bottom of the page.
OCaml, which is not purely functional but still closely related to Haskell, is nearly as fast as C. Haskell somewhat acts as a testbed for ideas in the ML language family, and future versions of OCaml are expected to include many features that were first implemented in Haskell. I'd also suggest that Haskell is a good introductory language for future OCaml programmers as it ensures they won't just try and use OCaml like a weird imperative language.
OTOH, it is theoretically possible to automatically multithread purely functional programs, especially if they're lazy like Haskell. So it could end up being a very important language on multi-processor and distributed systems.
Finally, Haskell has an excellent foreign function interface for when you need C-like performance and control.
Above message is especially redundant, and not even funny. It's an exact duplication of a post from a previous functional programming thread on /.
If you liked
"Learning Functional Programming through Multimedia"
be sure to check out our new title:
"Learning Esperanto through Yoga"
Short answer: IO is an exit value, just like you said.
Long answer:
Monads are a pattern for hiding a state that gets passed from a sequence of functions. For example, when you assign to a variable in an imperative language, the value of that variable in the implicit state is updated and all future phrases accessing that variable will get the new value. If you're using a Haskell state monad it works the same way, but you need to explicitly specify which phrases can be executed in the future (using sequencing operators much like C's semicolon). Effectively Haskell monads allow all imperative constructs except for backwards jumps (goto).
The Haskell IO Monad is a purely functional mechanism for ensuring that modifications of the RealWorld are done in the correct order. It is implemented to call system calls which have real side-effects, but wrapping IO in a monad ensures that you can still reason about the order the side-effects will occur in. Since Haskell is lazy, these side-effects won't actually be triggered until necessary, either because the program needs an input value or it exits.
(I can give examples if anyone wants, but the resources at haskell.org may be more helpful.)
I haven't really given it much thought, but I've heard claims that functional libraries are designed very differently from imperative libraries and therefore .NET's (which is, lets face it, designed for C#) will not fit perfectly with CLI functional languages. Of course a functional-style wrapper around the .NET libraries could be written, but then we might as well be using the meager native functional libraries we already have.
.NET API?
Do you have any feeling for how well F# or H# will get along with the
Does Haskal or oCamal have supported production grade ports to Palm OS or other small/embedded platforms?
In my program, the algorithms class was at the start of second year, so many students were still not comfortable with pointers. As a result, most people spent so much time struggling with the implementations that they didn't get a chance to sit back and appreciate the structures.
In Haskell, structures like linked lists and binary trees are implemented with a single line of code. Yes, you don't see the actual memory addresses being used, but these are also barriers to understanding.
I'd advocate algorithm classes completing an implementation of linked lists in C (if this wasn't done in the C introductory class), then moving to a higher-level language for everything else. Because after all, once you've implemented one data structure in C, it's not difficult to implement them all.
I've never done functional programming. The most esoteric I've ever gotten is Scheme:). From what I understand of functional programming you tend to describe what you want to do and let the compiler set up the low-level stuff for you. Am I wrong here? I think many more people would be more inclined to try out functional programming with one of the functional languages that target something like Microsoft's IL. That way they can still use the class libraries. Maybe functional programming doesn't integrate so well with IL(maybe it needs some lower level IL constructs to really be expressive), but if someone wrote a VS.NET plugin it might lower the fear factor in learning something new. I hear there are functional languages that do target IL right now. Any comments?
This statement, from the 'more about Hskell' link:
"Furthermore, malloc is fairly expensive, so programmers often malloc a single large chunk of store, and then allocate "by hand" out of this."
I've seen this type of statement elsewhere in defense of non-C languages. And yet I've very rarely seen this done in code that wasn't either in 1) an embedded system or 2) a device driver or kernel module.
In those cases where I have seen this in application code, it has been accompanied by lots of other newbie gaffes. I'd question the sanity of anyone who thinks that a user-level app will benefit from a hand-coded heap manager.
But perhaps there are exceptions...does anyone actually do this routinely?
Premature optimization is the root of all evil
What's the link between Cambridge and Haskell?
Berkley...Distribution...Software...Model?
What the devil are these *BSD weenies up to?
I thought NetCraft said they were dead?
What is this BDSM thing all about? Is it cool, or is it whack?
I love the smell of a classic troll in the afternoon...it smells like... /. ...
What good are you, if your program segfaul
segmentation violation
comment terminated
Thirty minutes of searching around for it and expirementing with it, with no success, and I put the project on hold. I couldn't believe how confusing it was! And in the sample code, it was broken.
I intentionally limit my time with GTK apps, because it encourages me to forget useful keyboard combinations. "Esc" doesn't close a dialog box.
Not to mention it's slow and bloated, and full of crashes and potential for buffer overruns, since it uses a C object system, with type-unsafe macros, rather than a real object system, where type-checking is done completely at compiler time.
You could use a binding to keep yourself from creating new bugs, but I don't recommend it. What we need is a new GUI toolkit for 'nix, made in a better suited programming language (such as Java or Ada).
Well, I haven't touched Haskell but I read the description provided in the link. The "size of code" example is silly. For implementing quick sort, good programmers would use componentized logic, a good deal of which has been written for you. As for the pointer safety, Java or managed C++ handles that. Haskell curiously reminds me of prolog though. As for performance, it is very much still important in my opinion. Code for the usual ecommerce form and non realtime messaging apps I would think can use Haskell, but multimedia networking, game programming, and any form of high-volume content processing apps has to choose the higher performance language. I'm guessing though that Haskell supports linking C++ code just fine.. someone want to confirm this so I don't have to read more? Thanks :)
Take a look at this one-page TCP port scanner that I wrote in Haskell. Imperative and functional styles mixed together, with neither sacrificing for the other.
To use your time- and frequency-domain metaphor, Haskell is the well-educated EE who can use both kinds of analysis -- and slide between the two with ease.
Easy, automatic testing for Perl.
Lots of other comments, as well as the story, have pointed to a number of good tutorials and introductions. I'd like to recommend also the one I wrote for IBM developerWorks. I believe my tutorial is a bit better for real beginners to FP than are most of the others out there.
Anyway, you can find it at IBM dW(free registration required) or at my own Gnosis Software site.
Buy Text Processing in Python
I guess this is a troll, but I can't resist:
Functional language are only good in theory.
This is totally not true. I build real programs that do real stuff in SML every day.
Thus, there's a MASSIVE performance loss when a functional programming language is executed on any of the existing processors.
This is also completely false. Optimizing high-level languages is often easier, because there is more semantic information to exploit (types, higher-order code). My SML programs typically run about 20% slower than a C counterpart, while being much shorter, more frequently correct, and more secure.
You might want to have a look at HaskellDB which is a Haskell library for writing statically checked queries using a relational algebra-like syntax. It lets you write things like:
Here's a simple C function which finds the inverse of a permutation, in linear time.
void invert_permutation(
int in[],
int out[],
int len
) {
int i;
for (i = 0; i < len; i++)
out[in[i]] = i;
}
Write the same function in Haskell, in linear time. Use whatever representation of a list seems natural for you.
I set this very simple problem to every pure functional programming enthusiast I meet, including several professors at a University known for that sort of thing. I've yet to hear a good answer...
Xenu loves you!
I thought about coming up with a syllabus for myself of C, Haskell, LISP and Perl (which just evades me....)
I'd like to strongly recommend some books. The first is Modern C++ Design by Andrei Alexandrescu. The second is On Lisp by Paul Graham. In conjunction with that, you will need an introductory text on Lisp if you don't already know it and a good book on C++ templates. While I don't know what the best Lisp text currently in print is, I'd be willing to give Graham's ANSI Common Lisp a try on the strength of his other book. And C++ Templates: A Complete Guide by Vandevoorde and Josuttis illuminates a lot of dark corners in templates and explains some new features.
In the end, the goal is to understand how many times Graham and Alexandrescu are talking about the same things using very different languages. C++ templates are in many important ways a compile-time, functional macro language on top of C++ that implement many of the features of Lisp macros. For what it's worth, Bruce Eckel has mentioned this generic programming link in the context of discussing Java generics.
The net will not be what we demand, but what we make it. Build it well.
There are a few possiblities: Nemerle is functional version of C#. Felix is functional version of C/C++. Scala is functional version of Java with .Net version coming.
Schlep translates scheme to readable C.
Cyclone is a safer C with some functional features.
That you prefer this code to the C alternative, in terms of readability, maintainability, error-proneness, etc?
Sure, I don't like using C for general-purpose programming as much as the next HLL programmer, but FP languages are simply mind-boggling, and no - that's not a good thing.
I've seen something like that, as a form of garbage-collection, when C is used in a stateless, quick-cycling system like HTTP. Malloc a big chunk of memory, perform operations wastefully within it (allocate with no attempt to free or reuse), then free the whole chunk at the end of the cycle (eg: after the HTTP response).
This program uses that pattern: http://www.annexia.org/freeware/rws/
IIRC, the reason this was so is because, given the test design, Java incurred a very large penalty for each test, from starting up its environment. Once the shootout's implementor figured out a way to factor this out (use a Hello World benchmark to measure startup time), Java's CPU performance shot up very close to the top.
Are you adequate?
I sometimes suspect that .NET may be the only hope of getting functional programming adopted by the maininstream.
Haskell is available for .NET now, using Mondrian.
Or, you can can access the Framework's libraries with Hugs98 for .NET.
How Politicians Lie: http://www.factcheck.org/
Okay, disclaimer, I barely know any functional programming, and that's in ocaml. But despite that, I think I've made a conceptual leap here that might help clarify what's going on in regard of all this "IO as a return value" stuff.
In C you write programs. C values are values. C functions return a value.
In Haskell, you write program generators. Haskell values are "the capability to, later, if necessary, generate a value" - in other words, a piece of code that can be called. A Haskell function application wraps its operands (which are code) in itself, and returns "the capability to, later, if necessary, compute the application of this function" - more code.
When your "main" in Haskell returns an "IO value", what it's actually returning is a generated program which will finally be called to actually do the IO.
Have I got this right? Functional gurus, please comment.
Thanks for bringing this feature to my attention, by the way. I'd be interested to see if you can use it to solve the next challenge, which was actually the one that inspired this challenge and arose from a real problem in Prolog programming: fairly generating a random permutation, given a source of random integers of arbitrary size. I don't immediately see a way of doing it, but perhaps you do.
Here's source code, in Python this time:
def random_permutation(len):
res = range(len)
for i in range(1, len):
j = random_int(i + 1)
res[i], res[j] = res[j], res[i]
return res
Xenu loves you!
As far as I can tell, that is indeed a very insightful way of looking at it.
At the semantic level: In denotational semantics, a program is a function with side-effects. A Haskell program without side-effects (all the input comes in, then all the output goes out) defines a mathematical function.
At the implementation level: A Haskell program with IO is the specification of a sequence of system calls. A monad with branching and other constructs is an instance of a superclass of straight monads.
However, a C program isn't necessarily that different: it still needs to be called as a function by the kernel. Haskell simply has another layer of abstraction because functions (and therefore programs) are first-class entities. And, of course, it's much easier (although not automatic) to ensure that programs are full rather than partial functions in Haskell.