
Daniel Mlot wrote:
Heinrich Apfelmus wrote:
I concur. In my opinion, the second part about generalized folds and maps does not even belong to the beginner's track; it should be moved to a chapter "Generic Programming" in the "Fun With Types" section.
In that case, the part about "Trees" would stay more or less where it is now, while the final sections would be moved forward to "Fun With Types/Generic Programming", which would replace the existing red link to "Datatype algebra"?
Yes, exactly. (Generic programming = doing things 'generically' for many data types, like generalizing the fold function to every data type.)
My vision for the 'Haskell Basics' section is to present a minimal subset of the Haskell syntax and language that still enables people to write pretty much any program they want. This way, readers don't have to wade through all the syntactic variety before getting to the core concepts. [..] [..] I have a few doubts about your subset, though. Firstly, even if you are probably thinking of a full-scale reassembling of the modules and chapters that might nullify my concerns, I wonder if a minimal subset which "enables people to write pretty much any program they want" wouldn't cause too much material to be placed in a single book segment/chapter, in detriment of the other chapters in the Beginner's Trail.
True, the Beginner's track could lose one segment, but that's not necessarily bad; the number of segments is not set in stone, after all. That said, I envision a separation like this: * Haskell Basics => write any functionality * Elementary Haskell => write idiomatic Haskell code, full syntax * Intermediate Haskell => write libraries, i.e. modules and type classes So, Haskell Basics is really just a subset of what a full Haskell programmer should know, but it's enough to write small programs in a rather limited style that can nonetheless express pretty much anything. For example, I imagine that Haskell Basics teaches only squares n = map square [1..n] where square x = x ^ 2 while a full Haskell programmer would write this as squares n = map (^2) [1..n]
Also, with regards to the list-related material, pattern matching looks like such an integral part of day-to-day Haskell usage it seems natural to present initial examples without getting into details of how it actually works. Of course this is just an impression from a newbie haskeller, and that there may be conceptual problems I might not be giving due weight to - for instance, it could well be that many people, after seeing pattern matching in action without a proper explanation, think it is some kind of magic and develop wrong ideas about how the language works (such a situation could make a good reason for stimulating "whole-meal programming").
There's nothing wrong with pattern matching. If anything, the problem is this: With pattern matching and recursion, you can define any function on lists. But then, it is also tempting to do exactly that and forgo the vocabulary of functions offered in the Prelude, at the detriment of good Haskell style. For instance, consider the following task: you are given a file that has a number on each line and you have to add them all up. A direct, recursive, and utterly unintelligible solution would be to go character by character and accumulate the sum example :: String -> Int example s = go 0 "" s where go sum 0 [] = sum go sum number (c:cs) | c == '\n' = go (sum + read number) 0 cs | isDigit c = go sum (number ++ [c]) cs whereas the proper Haskell way to think about this task is example = sum . map read . lines Okay, I created this example for this very purpose, but it does happen in practice: "Memory usage problem" http://thread.gmane.org/gmane.comp.lang.haskell.beginners/3842 (read the original question and my reply)
Finally, a note about exploration of "many Prelude functions involving lists". One of the things I enjoyed about the initial modules of the book was how it presented the essential concepts with minimal "clutter" of alternative syntax and, specially, systematic study of the standard library. I realize that this slower, less practical style probably does not work for everyone, and is occasionally overdone (for instance, by waiting an eternity to introduce type classes), but still I feel such an approach has merit - and furthermore, it would help to distinguish our basic modules from, say, LYAH. There are a few subtler ways of working with Prelude in the book, which is already done semi-intentionally in some parts of the book, such as slipping new Prelude functions in examples and exercises and stimulating readers to be curious (for instance, by using GHCi to immediately query the type signature of every and each unknown function they happen to meet).
In the light of the above, conveying a good grasp on the vocabulary is necessary, but I agree that a diligent study of standard libraries is not necessarily a good idea. The thing is that the reader can only memorize so many things at once, and it would be a waste to squander this on uninteresting syntactic variations and library functions that he doesn't need right now. I imagine the best way to solve this is to present a subset of the Prelude in style of a "cheat sheet", i.e. as documentation that the reader should consult whenever he needs new vocabulary. Astonishingly, such a thing does not exist yet, at least not how I imagine it. There is * Bernie Pope - A Tour of the Haskell Prelude * GHC doc - Prelude but the former has no thematic categories like the latter while the latter does not restrict itself to the Haskell Basics subset. I've given some private lessons recently and I was surprised to find that it's really tricky to find the show function if you only know that you're looking for something that will convert stuff into a String . Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com