RE: Learning Haskell and FP

On Wed, 3 Jan 2001, Simon Peyton-Jones wrote:
I'm sure that's right. Trouble is, we're the last people qualified to write one!
Here's a suggestion: would someone like to write such a guide, from the point of view of a beginner, leaving blanks that we can fill in, when you come across a task or issue you don't know the answer to? That is, you provide the skeleton, and we fill in the blanks.
I read your paper on taming the Awkward Squad several months ago as my first exposure to Haskell. I think it is an excellent paper and really convinced me that Haskell was worthwhile to learn and use. There are aspects to the paper that are like a tutorial, but I think it would be overwhelming for a programmer not used to reading papers from academia. I think a really good beginner's tutorial on I/O could be started from this paper: - Start immediately with using the 'do expression' and don't worry about the history that led to its development. - Avoid mentioning 'monad' and other mathematical terms until much latter in the game. It is better to see the system in action and then find out it has a nice solid foundation. Many people are also annoyed by an author using new vocabulary even if it is well defined. It's better to get them comfortable with the system first. - Take advantage of the 2d syntax rules to avoid the unneeded braces and semicolons. Syntax with little punctuation seems to go a long way with many programmers. Pointing out the similarities to Python here could be appropriate. - After working through several examples, show that the 'do expression' is short hand for some more basic primitive operators. These can be more appropriate to use in some circumstances. - Conclude with explaining the difference between executing an action and building a value to execute the action. There is no need to point out that this is a requirement of being a lazy language. Instead point out the benefits such a system provides to back up the claim that Haskell truly is "the world's finest imperative programming language." Some points would still be difficult to get through: - Explaining the type system. There is no avoiding this, and users will have to learn it. - Working through the difference between 'unit' and 'void'. Perhaps this can be avoided in a beginning tutorial. A possible confusing example in the paper is that of composing putChar twice while throwing away the result. People used to C or Java might immediately think "but it doesn't have a result to through away!" - Some amount of understanding for Haskell expressions is going to be needed to understand examples. An I/O centric tutorial would want to explain as things go along as needed. I would avoid other parts of the paper for a first attempt at some new tutorial material. Any thoughts? I could take a first stab at this if people think it would be a useful direction. Patrick

On Fri, 5 Jan 2001 10:26:19 -0500 (EST)
Patrick M Doane
[snip]
I think a really good beginner's tutorial on I/O could be started from this paper:
- Start immediately with using the 'do expression' and don't worry about the history that led to its development.
Actually, the history, especially from a comparative programming languages standpoint, can sometimes be useful for motivation. For example, many Java textbooks motivated study of the language by explaining the need for a C-style language without explicit memory allocation or explicit pointer casting. Similarly, an on-line document for C# motivated it by explaining the history of how it grew out of a need for a language similar to C and C++ (the document somehow left out the Java comparison :-( ), but that allowed programmers to develop more efficiently in it. Even for a "Haskell in a Nutshell"-style textbook, a couple of paragraphs comparing Haskell to other languages from a historical viewpoint and describing the advantages and disadvantages of Haskell in particular could prove quite useful.
[snip]
Many people are also annoyed by an author using new vocabulary even if it is well defined. It's better to get them comfortable with the system first.
That depends on which new vocabulary is being mentioned, though. That may true for unnecessary new vocabulary, such as "monads" for the first chapter. However, e.g. in the following example (borrowed from Chapter 3 of _A Gentle Introduction to Haskell, Version 98,_ by Paul Hudak): add :: Integer -> Integer -> Integer add x y = x + y it is hard not to introduce such vocabulary as "has type," "arrow" (or "mapping"), and maybe even "currying."
[snip]
- Conclude with explaining the difference between executing an action and building a value to execute the action. There is no need to point out that this is a requirement of being a lazy language. Instead point out the benefits such a system provides to back up the claim that Haskell truly is "the world's finest imperative programming language."
Forgive me if I am ignorant, but who claimed that Haskell was an "imperative" language? Also, in order to take full advantage of Haskell, it would seem necessary to get used to functional programming style (the Haskell school of expression, in particular). It seems that using Haskell as an "imperative" language is a bit like thinking in C when programming in C++; only worse, since the imperative habits are being brought into the functional, rather than the OO, realm. --Ben -- Benjamin L. Russell russell@brainlink.com benjamin.russell.es.94@aya.yale.edu "Furuike ya! Kawazu tobikomu mizu no oto." --Matsuo Basho

Forgive me if I am ignorant, but who claimed that Haskell was an "imperative" language?
Also, in order to take full advantage of Haskell, it would seem necessary to get used to functional programming style (the Haskell school of expression, in particular). It seems that using Haskell as an "imperative" language is a bit like thinking in C when programming in C++; only worse, since the imperative habits are being brought into the functional, rather than the OO, realm.
Nope, I also think that Haskell is the world's finest *imperative* language (and the world's best functional language as well). The beauty of monads is that you can encapsulate imperative actions as first class values, ie they have the same status as functions, lists, ... Not many other imperative languages have statements as first class citizens. Erik

Erik Meijer wrote:
Nope, I also think that Haskell is the world's finest *imperative* language (and the world's best functional language as well). The beauty of monads is that you can encapsulate imperative actions as first class values, ie they have the same status as functions, lists, ... Not many other imperative languages have statements as first class citizens.
It may be the only imperative language that doesn't have mutable variables as a standard part of the language. :-) I do agree that Haskell has a lot of nice imperative features, but it is also missing a few that are fundamental to imperative programming. Personally, I'd love to see a language that is imperative from the ground up, that has some of the design features of Haskell (especially the type system), but I don't think that Haskell is that language (yet?). A question for the list: Is there a book that gives a good introduction to Hindley-Milner typing theory and practice, and that delves into its various extensions (e.g. imperative programs, type classes, record types). I have Mitchell's book out from the library, but it seems a bit limited with respect to extentions (I think it deals with subtypes, but not type classes and mutable variables, for example). Cheers, Theodore Norvell ---------------------------- Dr. Theodore Norvell theo@engr.mun.ca Electrical and Computer Engineering http://www.engr.mun.ca/~theo Engineering and Applied Science Phone: (709) 737-8962 Memorial University of Newfoundland Fax: (709) 737-4042 St. John's, NF, Canada, A1B 3X5

Erik Meijer said:
Not many other imperative languages have statements as first class citizens.
I don't have the details here (e.g., an Algol 68 report), but Michael Scott reports in his "Programming Language Pragmatics" text (p. 279) that: "Algol 68 [allows], in essence, indexing into an array of statements, but the syntax is rather cumbersome." This is in reference to historical variations on switch-like statements (and consistent with a running theme, typical in PL texts, about the extremes of orthogonality found in Algol 68). -- Fritz Ruehr fruehr@willamette.edu

On Tue, 16 Jan 2001, Fritz Ruehr wrote:
Erik Meijer said:
Not many other imperative languages have statements as first class citizens.
I don't have the details here (e.g., an Algol 68 report), but Michael Scott reports in his "Programming Language Pragmatics" text (p. 279) that:
"Algol 68 [allows], in essence, indexing into an array of statements, but the syntax is rather cumbersome."
Well, there are two ways it allows this. 1) The case statement is little more than array indexing case <int> in <stmt1>, <stmt2>, ... out <other statement> esac 2) You can create an array of procedures returning void results, for which if I remember correctly you have to write VOID: <stmt> to turn the <stmt> into a proc void. You can certainly index an array of these and the relevant proc will be called as soon as the indexing happens (you don't need to write () or anything). So (VOID: print ("a"), VOID: print ("b"))[2] would print "b". I can't remember if you need to specify the type of the array, though. The statements aren't first class, though, because their scope is restricted by the scope of variables that they reference. So begin [10] proc void x; # declare an array of procs # begin int n := 42; x[1] := void: (print (n)) end; x[1] end is invalid because at x[1] it would call the procedure, which would refer to n, which is out of scope (and quite possibly because of sundry syntax errors!). So Algol 68 isn't a counterexample to Erik's claim.
This is in reference to historical variations on switch-like statements (and consistent with a running theme, typical in PL texts, about the extremes of orthogonality found in Algol 68).
Although if they'd really wanted to be extreme they could have left out integer case clauses, because they are the same as indexing a [] proc void! Jón -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk 31 Chalmers Road jf@cl.cam.ac.uk Cambridge CB1 3SZ +44 1223 570179 (pm only, please)
participants (6)
-
Benjamin L. Russell
-
Erik Meijer
-
Fritz Ruehr
-
Jon Fairbairn
-
Patrick M Doane
-
Theodore Norvell