Microsoft has posted version 184.108.40.206 (whatever the heck that means) of their F# compiler, which gives me an excuse to discuss the book Practical OCaml by Joshua Smith.
Practical OCaml is a new release from APress. My favorite technical book of last year was Practical Common Lisp, by Peter Seibel, and I hoped that Smith could duplicate the feat. It looks like the book has a different editorial team, but follows some similar structural advice. Even if nothing else, both books are reasonably sized (\~400 pages, not \~1,000) and divided in a manner that makes them very appealing for those interested in learning a programming language.
My main motivation for reading this book (other than the hope that APress had discovered a way to bottle the lightning of language evangelism) was that "pure" functional languages are inherently parallelizable. That is to say, the language semantics are such that a sufficiently smart compiler could correctly take care of threading the computation over multiple cores/processors. Since I am of the belief that the manycore era is going to require a sea-change in programming approaches, I think it behooves those interested in the future to gain experience with such languages. Concurrency is treated only tangentially in Practical OCaml and I am under the distinct impression that OCaml is not inherently parallelizable (I believe this to be the case with F# as well). Nonetheless, it's certainly true that concurrency is "easier to think about" when using functional approaches, so there're still things to be gained.
What I didn't realize was that OCaml is a very, very good language for writing domain-specific languages. It's pattern-matching semantics are quite advanced and lex/YACC libraries (ocamllex and ocamlyacc) are part of the standard distribution. While I feel that tools like ANTLR and concepts like Parsing Expression Grammars have the potential to displace lex/YACC, there's no questionthat lex/YACC is the dominant "species" in the world of compilers.
Having said all that, I'm afraid that Smith's book is not nearly as persuasive as Seibel's. I abandoned LISP long ago and Seibel made me reconsider that decision. I wanted to learn OCaml but could hardly sustain my enthusiasm through the first chapter. The first sentence of Practical Common Lisp is "If you think the greatest pleasure in programming comes from getting a lot done with code that simply and clearly expresses your intention, then programming in Common Lisp is likely to be about the most fun you can have with a computer." That's a good opening and I think accurately captures the undeniable aesthetic appeal of LISP. The first sentence in Smith's "Why OCaml?" introduction is "It's a fair question." That's a bad opening. At least, it's a bad opening when followed by five paragraphs whose greatest substantive claim is "OCaml helps the programmer to easily express normal concepts and actually express difficult concepts." If that doesn't take the wind out of your sails, rest assured that it is preceded by "Returning to the title question, if I were to answer the question in more mundane terms, I would say that...." That's the type of opening that calls into question the author's precision.
The tutorial that follows is structured well-enough, but the concepts are not presented as well as they could be. Here is the complete discussion of the I-would-think-important concept of mutable variables:
It can be tempting to use mutable references, but I suggest that you resist that temptation. I have generally found that, except in a few cases, the use of a mutable reference could be removed by fixing my designs. This is not a rule in any sense of the term because sometimes a mutable reference is really the best choice. File input/output (I/O) is a good example because file I/O is often a nonfunctional chore. Some other functional languages deal with these nonfunctional chores by using monadic computation, but that might not always be necessary. You can hide mutable references in OCaml classes to make their use less problematic (this is discussed in more detail in Chapter 19).
This is on page 23 and is not preceded by a discussion of why mutable references are undesirable or what monadic computation is...I can't resist: the index has only 1 reference for "monadic computation" and that leads to page 251's explanation that:
Monadic computations and monads in general are creations that open up a small loophole for purely functional languages. Although a purely functional language cannot have functions with side effects, it can have values that describe and contain side effects. This boils down to computational sleight-of-hand that comes with a cool-sounding name.
Oh. Alright then. I started the book under the impression that issues of mutability might be fairly important to understanding a functional language, but apparently they aren't.
APress is 1-for-2 with their Practical... series, I hope Practical Haskell comes up to bat next.
In the meantime, if you want a really good book I suggest: Practical Common Lisp.