Interesting new user perspective

http://sandersn.com/blog/index.php?title=two_weeks_of_haskell Has some good thoughts on what tripped him up in his first two weeks of Haskell programming. Anything people want to work on there? :-) Worth a read if you're thinking about how to make Haskell yet more accessible. -- Don

Don Stewart wrote:
http://sandersn.com/blog/index.php?title=two_weeks_of_haskell
Has some good thoughts on what tripped him up in his first two weeks of Haskell programming. Anything people want to work on there? :-)
Worth a read if you're thinking about how to make Haskell yet more accessible.
Sounds like it was written by somebody who's already used to languages like Lisp and Python. As I wrote a while earlier, I recently convinced an hardent C++ programmer to install GHC and start coding. Aside from the endless stream of "minor" things that trip you over when learning any new language, the biggest thing he sited as being difficult is the "implicitness" of Haskell. C++ is a very explicit language. If you want an integer variable, you say "int x". If you want a vector of integers, you say "std::vector<int> x". And so on. In Haskell, you just say "x" and you've got a variable. Maybe it's type is known at compile-time. Maybe its type is polymorphically determined by the caller. Maybe it's dynamically changable at runtime (e.g., if you're using something like existential quantification). And you can write entire Haskell programs with not a single type signature in sight. (Until you grok how parametric polymorphism and Haskell's non-traditional type syntax work, this is probably the easiest way to program.) If you write a class instance, you define a whole bunch of functions who's types are implicitly fixed by the class definition [which could be somewhere very remote]. Define an algebraic data type using record syntax and you just implicitly defined half a dozen value constructors and projection functions. In short, with a few lines of Haskell, you can do an awful lot of work, and it can be a bit bewildering figuring out where all this "work" is coming from. I for one actually *like* the implicitness of Haskell. It's what enables you to write short, flexible, intuitive code. I think it's just the teaching of the language that needs work, not so much the language itself. That reminds me... I really must check out the draft of Real World Haskell sometime soon!

On 9 Oct 2008, at 9:33 pm, Andrew Coppin wrote:
I think it's just the teaching of the language that needs work, not so much the language itself.
As a newer user myself, I'd agree with this statement. I'd like to see far more mundane tasks solved in tutorials. The number of times building a parser or generating prime number is used as an example is out of proportion to the times you'd use these things[1]. Just simple, *really* easy things would be better. Maybe it's just me, but if I wanted to learn perl or ruby or python or C# I'm not sure I'd ever see a _tutorial_ containing a prime number. Haskell is can obviously do some really interesting things, but constantly having wikipedia open so I can look up whatever mathematical doodah has just been mentioned can get draining. Even Real World Haskell suffers a bit from this. Iain [1] In years of programming (other languages) I've never had to generate my own primes or build a compiler or a parser. I may have parsed things, but that's different to building an entire parser, if you get my drift. Actually, tell a lie. I have built a parser, but it's still not stuff for a beginner's tutorial IMHO.

On Fri, 2008-10-10 at 19:08 +0100, Iain Barnett wrote:
On 9 Oct 2008, at 9:33 pm, Andrew Coppin wrote:
I think it's just the teaching of the language that needs work, not so much the language itself.
As a newer user myself, I'd agree with this statement. I'd like to see far more mundane tasks solved in tutorials. The number of times building a parser or generating prime number is used as an example is out of proportion to the times you'd use these things[1]. Just simple, *really* easy things would be better. Maybe it's just me, but if I wanted to learn perl or ruby or python or C# I'm not sure I'd ever see a _tutorial_ containing a prime number.
Haskell is can obviously do some really interesting things, but constantly having wikipedia open so I can look up whatever mathematical doodah has just been mentioned can get draining. Even Real World Haskell suffers a bit from this.
Iain
[1] In years of programming (other languages) I've never had to generate my own primes or build a compiler or a parser. I may have parsed things, but that's different to building an entire parser, if you get my drift.
Actually, tell a lie. I have built a parser, but it's still not stuff for a beginner's tutorial IMHO.
In Haskell it is. Parsec makes recursive descent parsers as easy to use in Haskell as regexps are in Perl. No reason not to expose newcomers to Haskell to the thing it does best. jcc

On 10 Oct 2008, at 7:05 pm, Jonathan Cast wrote:
On Fri, 2008-10-10 at 19:08 +0100, Iain Barnett wrote:
In Haskell it is.
Parsec makes recursive descent parsers as easy to use in Haskell as regexps are in Perl. No reason not to expose newcomers to Haskell to the thing it does best.
jcc
Regex tends to come after things like basic I/O, even in Perl. I've got a Haskell book here (Hutton, 170 pages) that doesn't even mention how to open a file! Just because it can be done, or it's easy(ier) doesn't mean that's where you should start. Iain

On Fri, 2008-10-10 at 19:27 +0100, Iain Barnett wrote:
On 10 Oct 2008, at 7:05 pm, Jonathan Cast wrote:
On Fri, 2008-10-10 at 19:08 +0100, Iain Barnett wrote:
In Haskell it is.
Parsec makes recursive descent parsers as easy to use in Haskell as regexps are in Perl. No reason not to expose newcomers to Haskell to the thing it does best.
jcc
Regex tends to come after things like basic I/O, even in Perl.
Why would I want to do I/O, when I don't know how to do anything interesting with the input yet, or how to generate interesting output? I think the `I/O comes first' attitude is *precisely* the difference between mainstream programmers and Haskellers. The goal should be to create more Haskellers, not just more people whose code happens to be accepted by GHC.
I've got a Haskell book here (Hutton, 170 pages) that doesn't even mention how to open a file!
That short, and you expect minor features like that (that not every program even needs) to be squeezed in? jcc

Jonathan Cast wrote:
Why would I want to do I/O, when I don't know how to do anything interesting with the input yet, or how to generate interesting output? I think the `I/O comes first' attitude is *precisely* the difference between mainstream programmers and Haskellers. The goal should be to create more Haskellers, not just more people whose code happens to be accepted by GHC.
So we need to teach these people not just about the syntax of the language, but the high-level game plan for how to use Haskell effectively. (Since it's SO different from normal languages.) Trouble is, as soon as you attempt to write a chapter like that, guess how many people are gonna actually read it? :-/
I've got a Haskell book here (Hutton, 170 pages) that doesn't even mention how to open a file!
That short, and you expect minor features like that (that not every program even needs) to be squeezed in?
See, now it's things like that which stop more people attempting to learn Haskell. Most programmers would consider this an extremely basic and important thing to know, but Haskellers say "oh, THAT... it's not really important" and the newbies go "wuh? Which planet are you from? I'll go learn something less crazy, thanks."

On Fri, 2008-10-10 at 22:43 +0100, Andrew Coppin wrote:
Jonathan Cast wrote:
Why would I want to do I/O, when I don't know how to do anything interesting with the input yet, or how to generate interesting output? I think the `I/O comes first' attitude is *precisely* the difference between mainstream programmers and Haskellers. The goal should be to create more Haskellers, not just more people whose code happens to be accepted by GHC.
So we need to teach these people not just about the syntax of the language, but the high-level game plan for how to use Haskell effectively. (Since it's SO different from normal languages.)
Right. I think what we're doing now *is* an effective program for doing this --- for programmers who are willing to learn --- and what y'all are proposing *isn't*. I think most programmers, looking at the first chapter of the tutorial you want, would be less inclined to learn Haskell than they are now. If they want to write ugly, unmaintainable code, they can always use C++ or Perl, after all. No need to learn Haskell for that.
Trouble is, as soon as you attempt to write a chapter like that, guess how many people are gonna actually read it? :-/
Presumably, everyone who knows Haskell now, and programs well in it, *has* read such a chapter.
I've got a Haskell book here (Hutton, 170 pages) that doesn't even mention how to open a file!
That short, and you expect minor features like that (that not every program even needs) to be squeezed in?
See, now it's things like that which stop more people attempting to learn Haskell. Most programmers would consider this an extremely basic and important thing to know, but Haskellers say "oh, THAT... it's not really important" and the newbies go "wuh? Which planet are you from? I'll go learn something less crazy, thanks."
It's a simple fact of programming, just one most developers don't know or don't think about. Pretending console or file I/O is somehow fundamental won't make GUIs start calling printf, or database clients start opening disk files. jcc

On Fri, Oct 10, 2008 at 02:29:54PM -0700, Jonathan Cast wrote:
I've got a Haskell book here (Hutton, 170 pages) that doesn't even mention how to open a file!
That short, and you expect minor features like that (that not every program even needs) to be squeezed in?
Uh... yes. Opening and closing files, command-line parsing, etc -- needed by almost every program. Aside from some very simple stdin-to-stdout filters, it is difficult to imagine a program where you don't need to open a file!

On Fri, 2008-10-10 at 18:13 -0500, John Goerzen wrote:
On Fri, Oct 10, 2008 at 02:29:54PM -0700, Jonathan Cast wrote:
I've got a Haskell book here (Hutton, 170 pages) that doesn't even mention how to open a file!
That short, and you expect minor features like that (that not every program even needs) to be squeezed in?
Uh... yes. Opening and closing files, command-line parsing, etc -- needed by almost every program. Aside from some very simple stdin-to-stdout filters, it is difficult to imagine a program where you don't need to open a file!
Again, you need a bigger imagination. My day job is almost entirely DB-centric; code that uses file I/O is very much a special case. jcc

On Sun, Oct 12, 2008 at 06:39:58PM -0700, Jonathan Cast wrote:
On Fri, 2008-10-10 at 18:13 -0500, John Goerzen wrote:
On Fri, Oct 10, 2008 at 02:29:54PM -0700, Jonathan Cast wrote:
I've got a Haskell book here (Hutton, 170 pages) that doesn't even mention how to open a file!
That short, and you expect minor features like that (that not every program even needs) to be squeezed in?
Uh... yes. Opening and closing files, command-line parsing, etc -- needed by almost every program. Aside from some very simple stdin-to-stdout filters, it is difficult to imagine a program where you don't need to open a file!
Again, you need a bigger imagination. My day job is almost entirely DB-centric; code that uses file I/O is very much a special case.
Not saying that it doesn't exist (though of course most databases still use file I/O at some level, even if abstracted). Just that it's very, very common. I wouldn't support at all teaching database interactions or network programming before file I/O. -- John

On Sun, 2008-10-12 at 21:34 -0500, John Goerzen wrote:
On Sun, Oct 12, 2008 at 06:39:58PM -0700, Jonathan Cast wrote:
On Fri, 2008-10-10 at 18:13 -0500, John Goerzen wrote:
On Fri, Oct 10, 2008 at 02:29:54PM -0700, Jonathan Cast wrote:
I've got a Haskell book here (Hutton, 170 pages) that doesn't even mention how to open a file!
That short, and you expect minor features like that (that not every program even needs) to be squeezed in?
Uh... yes. Opening and closing files, command-line parsing, etc -- needed by almost every program. Aside from some very simple stdin-to-stdout filters, it is difficult to imagine a program where you don't need to open a file!
Again, you need a bigger imagination. My day job is almost entirely DB-centric; code that uses file I/O is very much a special case.
Not saying that it doesn't exist (though of course most databases still use file I/O at some level, even if abstracted). Just that it's very, very common. I wouldn't support at all teaching database interactions or network programming before file I/O.
I'm not advocating that. But I do think demanding the teaching of *any* interface issues before you've shown enough Haskell to write interesting logic to tie to the interface is backwards. jcc

On Fri, 10 Oct 2008 11:05:43 -0700, Jonathan Cast wrote:
No reason not to expose newcomers to Haskell to the thing it does best.
This is precisely why newcomers flounder. Yes, there certainly should be a "Haskell for experienced Java/C++ programmers : All of the advanced things you can do more easily than you ever thought possible." But that's not the way to attract Joe Programmer, who has never had to write a parser. Joe Programmer needs to be shown how Haskell can solve _his_ problems. That might mean that you need to start with an extremely non-idiomatic Haskell program, one that has some of the "look and feel" of what programmers from other languages are comfortable with. And then transform that program, step-by-step, into something that takes advantage of Haskell's strengths. Steve Schafer Fenestra Technologies Corp. http://www.fenestra.com/

On Fri, 2008-10-10 at 17:13 -0400, Steve Schafer wrote:
On Fri, 10 Oct 2008 11:05:43 -0700, Jonathan Cast wrote:
No reason not to expose newcomers to Haskell to the thing it does best.
This is precisely why newcomers flounder.
Newcomers flounder because they expect to keep programming the same way they always have. They should be (and *are*) taught better ways of doing things.
Yes, there certainly should be a "Haskell for experienced Java/C++ programmers : All of the advanced things you can do more easily than you ever thought possible." But that's not the way to attract Joe Programmer, who has never had to write a parser. Joe Programmer needs to be shown how Haskell can solve _his_ problems. That might mean that you need to start with an extremely non-idiomatic Haskell program, one that has some of the "look and feel" of what programmers from other languages are comfortable with.
Try it. I guarantee you, it'll turn people *off* Haskell, and they'll never see your more elegant replacement, because they'll never read the fifth chapter where you stop fighting the language and start working with it. jcc

On Fri, Oct 10, 2008 at 2:31 PM, Jonathan Cast
On Fri, 2008-10-10 at 17:13 -0400, Steve Schafer wrote:
On Fri, 10 Oct 2008 11:05:43 -0700, Jonathan Cast wrote:
No reason not to expose newcomers to Haskell to the thing it does best.
This is precisely why newcomers flounder.
Newcomers flounder because they expect to keep programming the same way they always have. They should be (and *are*) taught better ways of doing things.
http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-str... is a brilliant example of a common workaday problem found in other languages, and solved elegantly in Haskell martin

Martin DeMello wrote:
http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-str... is a brilliant example of a common workaday problem found in other languages, and solved elegantly in Haskell
Oh, hey, that's pretty nice...

Andrew Coppin wrote:
Martin DeMello wrote:
http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-str...
is a brilliant example of a common workaday problem found in other languages, and solved elegantly in Haskell
Oh, hey, that's pretty nice...
... and a solution to a problem that you souldn't have in the first place. I mean, if you want to construct XML or SQL statements, you ought to use an abstract data type that ensures proper nesting etc. and not a simple string. Regards, apfelmus

On 11 Oct 2008, at 6:34 pm, apfelmus wrote:
Andrew Coppin wrote:
Martin DeMello wrote:
http://blog.moertel.com/articles/2006/10/18/a-type-based-solution- to-the-strings-problem
is a brilliant example of a common workaday problem found in other languages, and solved elegantly in Haskell
Oh, hey, that's pretty nice...
... and a solution to a problem that you souldn't have in the first place. I mean, if you want to construct XML or SQL statements, you ought to use an abstract data type that ensures proper nesting etc. and not a simple string.
Do you have an example of what you mean? Personally, I use stored procedures with a database as they protect from sql injection attacks (unless you write some really stupid procedures). Iain

On 11 Oct 2008, at 9:02 pm, Svein Ove Aas wrote:
On Sat, Oct 11, 2008 at 9:30 PM, Iain Barnett
wrote: Personally, I use stored procedures with a database as they protect from sql injection attacks (unless you write some really stupid procedures).
Isn't this what parametrized queries are for?
they will also work (at least in MS SQL Server), but you'd lose some of the performance and organisational benefits. And it stops people littering code with badly written SQL statements - at least I can keep track of the procedures! :) Iain

Svein Ove Aas wrote:
On Sat, Oct 11, 2008 at 9:30 PM, Iain Barnett
wrote: Personally, I use stored procedures with a database as they protect from sql injection attacks (unless you write some really stupid procedures).
Isn't this what parametrized queries are for?
Yes. (And it also improves DB performance since it doesn't have to continually reparse the query and rebuild the query plan.) Now consider dynamically constructing HTML and avoiding HTML injection attacks. There isn't an easy machine fix for that one.

Iain Barnett wrote:
apfelmus wrote:
Martin DeMello wrote:
http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-str...
is a brilliant example of a common workaday problem found in other languages, and solved elegantly in Haskell
... and a solution to a problem that you souldn't have in the first place. I mean, if you want to construct XML or SQL statements, you ought to use an abstract data type that ensures proper nesting etc. and not a simple string.
Do you have an example of what you mean?
Ah, yes, let me explain. Tom Moertel's post introduces two use cases, namely generating SQL statements and HTML documents from a template and some parameters (the latter are given as String ). Representing all of them as String is prone to bugs concerning escaping, so he uses a custom string type instead, namely one that indicates whether it was an SQL statement or HTML document. So far so good. Now note that I kept saying "HTML document" or "SQL statement" instead of "HTML string" or "SQL string" because, and that's my point, why on earth would you want to think of them as strings in the first place? I mean, a HTML document is a DOM-tree and an SQL statement is a logical formula. Just like a Haskell module is a set of function, type and class definitions and more. Sure, it's nice that all of them can be represented as a list of Unicode characters, but that's not the primary way of working with them. In other words, the typed way of thinking of these things is as abstract data types "Html" and "Sql" with operations for constructing and deconstructing them, like for instance ulist :: Html -> Html -- enclose with a <ul> tag bold :: Html -> Html -- ~ <b> tag text :: String -> Html -- a text node renderHtml :: Html -> String -- pretty print select :: [TableName] -> WhereClause -> Sql The Text.Html library offers such an API for Html documents, an example would be html << (header (thetitle (text "Web site")) +++ body (h1 (text "Example")) ) It *goes without saying* that text properly escapes its argument string when the final Html is printed. And not only does the library escape things for you, it also ensures that all tags are properly nested. This can be pushed as far as making type system only accept completely valid Html documents, for instance by using phantom types like html :: Html HEAD -> Html BODY -> Html HTML Peter Thiemann has written a library that does just that http://www.informatik.uni-freiburg.de/~thiemann/WASH/#washhtml Note that Html may well be implemented as a string internally, what counts is that the implementation is hidden. Similar things exist for SQL queries. Daan Leijen has developed a small domain specific embedded language for database queries, based on the simple observation that these are basically just list comprehensions. (Chapter 5 of his thesis) http://research.microsoft.com/users/daan/download/papers/phd-thesis.pdf In a sense, Tom's code is just a minimal abstract data type compared to a bare-bones String representation, by doing proper escaping. Regards, apfelmus

apfelmus wrote:
... and a solution to a problem that you souldn't have in the first place. I mean, if you want to construct XML or SQL statements, you ought to use an abstract data type that ensures proper nesting etc. and not a simple string.
Right. And if you have 25 KB of HTML data, you're *really* going to transform all of that into an abstract data type just to avoid injection problems, right?

Andrew Coppin wrote:
apfelmus wrote:
... and a solution to a problem that you souldn't have in the first place. I mean, if you want to construct XML or SQL statements, you ought to use an abstract data type that ensures proper nesting etc. and not a simple string.
Right. And if you have 25 KB of HTML data, you're *really* going to transform all of that into an abstract data type just to avoid injection problems, right?
Yes. "Just" an injection problem is an understatement. And its the implementation of the abstract data type that determines how fast things are. Who said that it may not simply be a newtyped String ? Regards, apfelmus

On Mon, Oct 13, 2008 at 08:43:48AM +0200, apfelmus wrote:
Yes. "Just" an injection problem is an understatement. And its the implementation of the abstract data type that determines how fast things are. Who said that it may not simply be a newtyped String ?
I think the attraction to the SafeString example is that it's simple and effective for the task at hand -- in other words, pragmatic. Suggesting that in order to avoid HTML injection people re-read the HTML spec and invent a complete ADT to represent all the little corner cases they probably won't ever use is exactly the kind of answer that would scare Joe Six-Pack Hockey Programmer away.

Devin Mullins wrote:
apfelmus wrote:
Yes. "Just" an injection problem is an understatement. And its the implementation of the abstract data type that determines how fast things are. Who said that it may not simply be a newtyped String ?
I think the attraction to the SafeString example is that it's simple and effective for the task at hand -- in other words, pragmatic. Suggesting that in order to avoid HTML injection people re-read the HTML spec and invent a complete ADT to represent all the little corner cases they probably won't ever use is exactly the kind of answer that would scare Joe Six-Pack Hockey Programmer away.
/me shrugs. Can't help it that HTML is crazily complex. But what I wanted to say is not that you should create an algebraic data type that exactly represents valid HTML but rather that the basic idea underlying SafeString, namely using an abstract (≠algebraic) data type for HTML should be a no-brainer and the first thing to do. To demonstrate, here's a 27 line HTML module. It's really simple, even simple-minded and still bug-prone, yet it already eliminates escaping and nesting bugs. module HTML (Html, Attr(..), toString, tag, text) where newtype Html = Html { toString :: String } data Attr = String := String tag :: String -> [Attr] -> [Html] -> Html text :: String -> Html tag name attrs body = Html $ "<" ++ name ++ attrs' ++ ">" ++ body' ++ "" ++ name ++ ">" where attrs' = concatMap attr attrs attr (name := value) = " " ++ name ++ "=\"" ++ escapeHtml value ++ "\"" body' = concatMap toString body text = Html . escapeHtml escapeHtml s = concatMap esc s where esc '<' = "<" esc '>' = ">" esc '&' = "&" esc '"' = """ esc '\'' = "'" esc x = [x] Example usage: *HTML> toString $ tag "b" [] [tag "i" [] [text "<>"], text "test"] "<b><i><></i>test</b>" These are just the very basics, extend them ad libitum. For instance by using Data.DList (i.e. ShowS) instead of String for O(1) concatenation. Or reading the HTML spec and doing something about newlines in attributes. Or checking the spec for the format of tag and attribute names. Or making Html a forest of nodes instead of a tree. I don't understand why there are still escaping bugs in this world. Regards, apfelmus

Normally I agree with you, apfelmus, but here at least I have to differ!
On Mon, Oct 13, 2008 at 11:50 AM, apfelmus
*HTML> toString $ tag "b" [] [tag "i" [] [text "<>"], text "test"] "<b><i><></i>test</b>"
I'd say the big problem is that your embedded language for describing HTML is way more complex for a domain expert than doc = renderHTML $(q "<b><i>#{v1}</i>#{v2}</b>") where v1 = "<>" v2 = "test" which, while somewhat error-prone in the HTML string itself, is much more likely to get used than an embedded language. One thing that "ideal in theory" solutions seem to miss out on a lot is usability; SafeString seemed to strike a great balance there, which is why I think it has been brought up as a great example of solving this problem in the real world. There's a reason why Ruby is taking off despite its complete lack of safety; writing code using it is genuinely enjoyable and Rails solves a lot of problems elegantly. I wouldn't want to use it for a big project; I have performance and reliability concerns, but attempts to "ruby-ify" bits of Haskell where safety can be validated via a small amount of inspection are welcome! -- ryan

*HTML> toString $ tag "b" [] [tag "i" [] [text "<>"], text "test"] "<b><i><></i>test</b>"
I'd say the big problem is that your embedded language for describing HTML is way more complex for a domain expert than
doc = renderHTML $(q "<b><i>#{v1}</i>#{v2}</b>") where v1 = "<>" v2 = "test"
How about using Haskell Server Pages[1] and get both? doc = <b><i><% v1 %></i><% v2 %></b> where v1 = "<>" v2 = "test" No more error-prone than apfelmus' embedded language (it *is* an embedded language), and no more complex to write than the SafeString example (less in fact). And a lot more enjoyable than Ruby (ok, I admit, that's not an objective statement). Cheers, /Niklas [1] http://haskell.org/haskellwiki/HSP

Ryan Ingram wrote:
Normally I agree with you, apfelmus, but here at least I have to differ!
/me considers map crushToPurée . filter disagrees ;)
On Mon, Oct 13, 2008 at 11:50 AM, apfelmus
wrote: *HTML> toString $ tag "b" [] [tag "i" [] [text "<>"], text "test"] "<b><i><></i>test</b>"
I'd say the big problem is that your embedded language for describing HTML is way more complex for a domain expert than
doc = renderHTML $(q "<b><i>#{v1}</i>#{v2}</b>") where v1 = "<>" v2 = "test"
which, while somewhat error-prone in the HTML string itself, is much more likely to get used than an embedded language. One thing that "ideal in theory" solutions seem to miss out on a lot is usability;
Ok, syntactic considerations. Why again would I want to bother memorizing HTML syntax? I know the Haskell syntax, in particular the space for function application and lowercase identifiers for variables. I care little about the myriad of other notations for function application and variables that people have invented, for that's - in a sense - what all languages boil down to. How is remembering more arcane syntax more usable? Also, by embedding instead of "enshrining" a DSL like HTML in the host language, I get all the flexibility of the host language. node :: String -> [Attr] -> [Html] -> Html -- renamed from last time text :: String -> Html tag x = node x [] bold = tag "b" italic = tag "i" olist = tag "ol" . map (tag "li") table = tag "table" . map (tag "tr" . map (tag "td")) example = bold [italic $ text "<>", text "test"] dialogue = tag "dl" . map (\(speaker,talk) -> [tag "dt" [italic $ text (speaker ++ ":")] ,tag "dd" talk]) In a sense, I can define my own tags. Regards, apfelmus

Jonathan Cast wrote:
Newcomers flounder because they expect to keep programming the same way they always have.
_Some_ newcommers flounder because they expect Haskell to be just another VB / C++ / Java / whatever. (Do we really want to encourage these people to be learning Haskell in the first place?) Others it seems flounder simply because Haskell completely changes almost all the rules about programming, and they end up not knowing which way is up. I have far more sympathy with these latter people. As I say, teaching the language syntax and the standard library functions it's going to help much on its own. You need to give these people some idea of what the high-level game plan is. I think you need to show people that you can use Haskell to do normal, ordinary stuff before you start showing off the more exotic things. (Obviously, you need to choose your examples carefully. Anything moderately complex is probably going to be approached from a totally different angle in Haskell, so the parallel won't be as helpful.)

On Fri, 2008-10-10 at 22:49 +0100, Andrew Coppin wrote:
Jonathan Cast wrote:
Newcomers flounder because they expect to keep programming the same way they always have.
_Some_ newcommers flounder because they expect Haskell to be just another VB / C++ / Java / whatever. (Do we really want to encourage these people to be learning Haskell in the first place?)
Absolutely not. That's my point.
Others it seems flounder simply because Haskell completely changes almost all the rules about programming, and they end up not knowing which way is up.
Are you sure teaching I/O first (or starting with an ugly, unreadable heavily imperative straight translation of C++/Perl/Ruby) is the best way to help these people? The Haskell community *is* committed to teaching people good functional design. You can see it every day on this list. But I don't really see the relevance here.
I have far more sympathy with these latter people.
As I say, teaching the language syntax and the standard library functions it's going to help much on its own. You need to give these people some idea of what the high-level game plan is.
OK, here's the high-level game plan: 1) Figure out what your program's major types are --- just what the names are. 2) Decide what operations you need on them. 3) Pick a domain (or functor) corresponding to each type constant, together with implementations of your selected operations for them. 4) Derive a set of laws governing your operations, that you're going to expect to hold for your implementation. Now, you have an API, and (implicitly) a class of mathematical models of that API. This class comes with a notion of `isomorphism' (or, technically, logical relation), between models that is required to preserve your type constants and operations. You have one model already (step 3); now you need to create another one (step 5) which will be more efficient when translated to machine code or interpreted on the computer. 5) Design a Haskell data type for each type constant, and implement Haskell functions for each operation. These may or may not be similar to your domains and operations from step 3, but there should be an isomorphism or logical relation between them. Now, you have an implementation, and can start work on an interface. 6) Pick an environment to work in (direct X11 programming, wxHaskell, the console, .NET, HTML over HTTP, etc.) 7) Decide what user-level operations you want to provide. 8) Decide, for each operation, what the effect of that operation should be in terms of your underlying state (from steps 1 and 3). 9) Implement each step as a function from the old state to the new one, using your implemented API from step 5. 10) Combine the steps into a comprehensive UI, using whatever composition methods are available in your environment. At each step, feel quite free to go back and revise your work at previous ones (but be sure to continue making progress!) An ideal tutorial would probably guide the user through these steps, in turn; note that I/O *definitely* comes after most of the code has been written.
I think you need to show people that you can use Haskell to do normal, ordinary stuff
Ordinary in the sense that it's common in programming tutorials, of course. *Real* programming mostly doesn't use printf and fget for I/O, even in C.
before you start showing off the more exotic things. (Obviously, you need to choose your examples carefully. Anything moderately complex
Anything at all, really. You can paper this over by just not explaining what this `IO' type constant is doing in their programs, but I don't think that actually helps. jcc

_Some_ newcommers flounder because they expect Haskell to be just another VB / C++ / Java / whatever. (Do we really want to encourage these people to be learning Haskell in the first place?) (...)
I hope so. One of my most important motivations to try Haskell was that I thought it was radically drived by some ideas that were only beggining to show up in C++, and I'm happy to know I was right :) (And, really, I was scared by how much time is lost with misinformed critics about other languages.) My begginer problem: syntax was a *major* issue, and I only could overcome it with a lot of love for this language. The best reference I was able to find is this: http://www.hck.sk/users/peter/HaskellEx.htm and it's not exactly for begginers. Best, MaurÃcio

On Mon, Oct 13, 2008 at 6:02 PM, Mauricio
On Fri, Oct 10, 2008 at 10:49 PM, Andrew Coppin
wrote: _Some_ newcommers flounder because they expect Haskell to be just another VB / C++ / Java / whatever. (Do we really want to encourage these people to be learning Haskell in the first place?) (...)
I hope so. One of my most important motivations to try Haskell was that I thought it was radically drived by some ideas that were only beggining to show up in C++, and I'm happy to know I was right :)
I would go further than that. To Andrew's question, I say: Yes, we want to encourage "these people" to learn Haskell. We want to smash all their expectations into tiny little pieces. We want their brains to explode. And after that, we want to take what is left, pick it up off the floor, and put it back in as something new and better! People who didn't realize just what it was that they were getting into, once they come around, tend to be even more vocal supporters among their peers. They've finally "gotten it" and want to share that experience with others. We just need to communicate that learning Haskell will make you a better programmer, no matter what expectations you have going in. -- ryan

Ryan Ingram wrote:
I would go further than that. To Andrew's question, I say:
Yes, we want to encourage "these people" to learn Haskell. We want to smash all their expectations into tiny little pieces. We want their brains to explode. And after that, we want to take what is left, pick it up off the floor, and put it back in as something new and better!
People who didn't realize just what it was that they were getting into, once they come around, tend to be even more vocal supporters among their peers. They've finally "gotten it" and want to share that experience with others.
We just need to communicate that learning Haskell will make you a better programmer, no matter what expectations you have going in.
Trouble is, certain programmers expect to master everything in 20 seconds flat ("Learn C++ in 21 days", anyone?), and if they try to learn an "obscure" and "irrelevant" language like Haskell and don't "get it" in 20 seconds flat, they'll go "bah, stupid language" and move on. I'm pretty sure there's no way to simplify Haskell to the point where people can master it in 20 seconds, so these people are pretty much a lost cause. Thus, I would concentrate my efforts on people who are actually willing to make the effort required to learn. Maybe that's just me...

On Mon, 2008-10-13 at 18:38 +0100, Andrew Coppin wrote:
Ryan Ingram wrote:
I would go further than that. To Andrew's question, I say:
Yes, we want to encourage "these people" to learn Haskell. We want to smash all their expectations into tiny little pieces. We want their brains to explode. And after that, we want to take what is left, pick it up off the floor, and put it back in as something new and better!
People who didn't realize just what it was that they were getting into, once they come around, tend to be even more vocal supporters among their peers. They've finally "gotten it" and want to share that experience with others.
We just need to communicate that learning Haskell will make you a better programmer, no matter what expectations you have going in.
Trouble is, certain programmers expect to master everything in 20 seconds flat ("Learn C++ in 21 days", anyone?), and if they try to learn an "obscure" and "irrelevant" language like Haskell and don't "get it" in 20 seconds flat, they'll go "bah, stupid language" and move on. I'm pretty sure there's no way to simplify Haskell to the point where people can master it in 20 seconds, so these people are pretty much a lost cause.
Thus, I would concentrate my efforts on people who are actually willing to make the effort required to learn. Maybe that's just me...
See, now *this* I agree with completely. jcc

If you want to make Haskell more widely used, do pick a name for Haskell Prime that starts with an A. I first heard of Haskell when exploring the list of computer languages that Gedit could highlight. Just imagine going through all those A,B,C,D,E,F,G before I came to Haskell. Those programmers who just want to earn their bread will not care if Haskell tutorials are relevant or irrelevant. They would rather ask how much a Haskell job pays and how many positions are there. The Haskell audience is more likely to be people who are either interested in programming languages in general or greatly dissatisfied with those languages they work with. For them, the stranger the better. My brain hurt a lot at first because of the compiler error messages but I liked the challenge.
Trouble is, certain programmers expect to master everything in 20 seconds flat ("Learn C++ in 21 days", anyone?)
Just couldn't resist: http://norvig.com/21-days.html --A

If you want to make Haskell more widely used, do pick a name for Haskell Prime that starts with an A. I first heard of Haskell when exploring the list of computer languages that Gedit could highlight. Just imagine going through all those A,B,C,D,E,F,G before I came to Haskell.
That is a simple sorting error in Gedit, just submit a patch. As professor 'iggins pointed out long ago, speakers of the English language drop their 'H's anyway, so 'askell should come long before 'A'. Couldn't resist not resisting,-) Claus

Steve Schafer wrote:
On Fri, 10 Oct 2008 11:05:43 -0700, Jonathan Cast wrote:
No reason not to expose newcomers to Haskell to the thing it does best.
This is precisely why newcomers flounder. Yes, there certainly should be a "Haskell for experienced Java/C++ programmers : All of the advanced things you can do more easily than you ever thought possible." But that's not the way to attract Joe Programmer, who has never had to write a parser. Joe Programmer needs to be shown how Haskell can solve _his_ problems. That might mean that you need to start with an extremely non-idiomatic Haskell program, one that has some of the "look and feel" of what programmers from other languages are comfortable with. And then transform that program, step-by-step, into something that takes advantage of Haskell's strengths.
Seconded. On the one hand, "Haskell makes difficult things easy, and impossible things possible". This is what's cool about the language. On the other hand, an introductory text ought to start with something simpler and _more familiar_ to get people used to the language first. Haskell is a simple language, but there's an awful lot of new stuff to learn - new language rules, and new techniques for structuring your code, and even *thinking about* what code "is". And another problem. I've written a few "intro to Haskell" documents myself. These almost always end up degenerating into an exercise in tripping over myself trying to explain everything all at once. Haskell has a lot of very cool stuff in it. There are lots of things you need to know to use it though. The "things" are all pretty simple, but they're all so inter-related that it's difficult figuring out where to start. Countless times I've written an example to demonstrate feature X, and then realise "oh, wait, that requires features Y, Z, K, W, B, M and J which I haven't mentioned yet..." It seems no matter how many permutations you go through, you always end up with this problem. No matter where you start with the language! Maybe I need to sit down and draw a directed graph of related topics and then perform a topological sort or something. ;-) I sat down to read Real World Haskell today. The introduction was great (although it seems to promise far too much). Chapter 1 is really solid. But then Chapter 2... seemed to be a fairly unstructured tangle of features and concepts all dumped on the reader at once. Like, "this is how if/then/else works, oh, but that example program is recursive, so this is how recursion works, oh, but that's lazy, so this is what thunks are..." I can just imagine anybody reading all this going "wuh? Slow down!" OTOH, it's easy to criticise what somebody else wrote. Much harder to write something better yourself... :-/ PS. I'm curios to see what happens when the book gets to the "interesting stuff". The intro seems to promise that Haskell has libraries for all kinds of cool stuff - database access, sound, etc. But IME it isn't true. I have tried and tried to make accessing a database work from Haskell; the necessary libraries simply refuse to compile. Ditto for sound. I yearn to do intricate DSP stuff in Haskell, but none of the sound-related libraries will compile for me. (The libsdl binding even comes with a specially-prepaired Windows package - which doesn't work.) I want to see what the hell everybody else is doing differently that makes this stuff actually work for them when it fails miserably for me!

On Fri, Oct 10, 2008 at 10:35:05PM +0100, Andrew Coppin wrote:
OTOH, it's easy to criticise what somebody else wrote. Much harder to write something better yourself... :-/
PS. I'm curios to see what happens when the book gets to the "interesting stuff". The intro seems to promise that Haskell has
I'm equally curious to see what happens when you get there ;-)
libraries for all kinds of cool stuff - database access, sound, etc. But IME it isn't true. I have tried and tried to make accessing a database work from Haskell; the necessary libraries simply refuse to compile.
Well, it compiles out of the box for me. Which may or may not be saying much. Have you posted your compile errors here so that we can help you?
work.) I want to see what the hell everybody else is doing differently that makes this stuff actually work for them when it fails miserably for me!
Start by showing us what exact commands you're running and what errors you get. Also what version of GHC you have and your platform would be helpful. So anyhow... when I started using Haskell, it was *despite* the state of libraries. I found that I was so much more productive in Haskell in the long run that I could sometimes write the library and solve the original problem in less time than it took to just solve the original problem in Python or OCaml. Obviously this doesn't always hold. But this is part of the reason that I wrote HDBC, ConfigFile, MissingH, hslogger, etc. Small things that were just missing but aren't anymore. I can't pretend that the Haskell library set is as full-featured as, say, Python. But it *is* respectable and it most certainly holds its own with database access. Oh, and you can call Python from Haskell. -- John

Iain Barnett wrote:
On 9 Oct 2008, at 9:33 pm, Andrew Coppin wrote:
I think it's just the teaching of the language that needs work, not so much the language itself.
As a newer user myself, I'd agree with this statement. I'd like to see far more mundane tasks solved in tutorials.
I would agree as well. My own flailings led to Software Tools in Haskell[1], which taught me more about how to actually do things[2] than the textbooks that I have read.
Haskell is can obviously do some really interesting things, but constantly having wikipedia open so I can look up whatever mathematical doodah has just been mentioned can get draining. Even Real World Haskell suffers a bit from this.
The mathematical doodahs are *very* useful, much more so than any other language I have used, but it helps to have some kind of foundation to understand how and why. I am frequently reminded of a "How to Draw" page from the Tick[3] comic, which went something like: Step 1: Draw a large oval. Step 2: Draw the Tick holding the oval. On 10 Oct 2008, at 7:05 pm, Jonathan Cast wrote:
Parsec makes recursive descent parsers as easy to use in Haskell as regexps are in Perl. No reason not to expose newcomers to Haskell to the thing it does best.
Is it wrong to use Parsec to parse regular expressions for a really simple regex engine[4]? [1] http://www.crsr.net/Programming_Languages/SoftwareTools/index.html [2] Even if it is the wrong way. :-) [3] http://en.wikipedia.org/wiki/The_Tick [4] http://www.crsr.net/Programming_Languages/SoftwareTools/ch6.html The engine itself is in Ch. 5. -- Tommy M. McGuire mcguire@crsr.net

On Fri, 2008-10-10 at 15:00 -0500, Tommy M. McGuire wrote:
On 10 Oct 2008, at 7:05 pm, Jonathan Cast wrote:
Parsec makes recursive descent parsers as easy to use in Haskell as regexps are in Perl. No reason not to expose newcomers to Haskell to the thing it does best.
Is it wrong to use Parsec to parse regular expressions for a really simple regex engine[4]?
That looks about right. And, as you point out, it's easier to understand than a direct parser. I would also re-code the engine itself in Parsec, though (probably using a finite state machine implementation, which (I think; I haven't tried it yet) would end up looking rather like a manual unfolding along the lines of Koen Claessen's parallel parsing process [1]). jcc [1] http://www.cs.chalmers.se/~koen/Papers/parsing-pearl.ps

On Fri, Oct 10, 2008 at 1:00 PM, Tommy M. McGuire
I would agree as well. My own flailings led to Software Tools in Haskell[1], which taught me more about how to actually do things[2] than the textbooks that I have read.
I found it really hard to just look up the syntax of the language when I had a question (e.g. how does case work?). I haven't advertised it much yet, but I created a PDF cheatsheet to help in those situations. It's on hackage[1], available via 'cabal install cheatsheet' or direct download. I'd be interested to hear what you think. Justin [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/CheatSheet

Tommy M. McGuire
Is it wrong to use Parsec to parse regular expressions for a really simple regex engine[4]?
I sometimes think it is better, from a maintainability standpoint, to just use Parsec for all that stuff and forget about regular expressions. There are many proficient application programmers and system programmers who are unfamiliar with regexen which, even if they weren't arcane, are still so balkanized. At first, I found writing Parsec for argument/option processing to be almost offensive -- so many lines for so little action! -- but it's clear as day to a lot of people and that is a real mark in its favor. -- _jsn

jason.dusek:
Tommy M. McGuire
wrote: Is it wrong to use Parsec to parse regular expressions for a really simple regex engine[4]?
I sometimes think it is better, from a maintainability standpoint, to just use Parsec for all that stuff and forget about regular expressions. There are many proficient application programmers and system programmers who are unfamiliar with regexen which, even if they weren't arcane, are still so balkanized.
At first, I found writing Parsec for argument/option processing to be almost offensive -- so many lines for so little action! -- but it's clear as day to a lot of people and that is a real mark in its favor.
And for true regular expression problems, we have regex libs, dozens. They're just not the only tool for text manipulation, and Haskell makes constructing true parsers just as easy, so may as well do it right, and do it well. -- Don

Tommy M. McGuire
The mathematical doodahs are *very* useful, much more so than any other language I have used, but it helps to have some kind of foundation to understand how and why. I am frequently reminded of a "How to Draw" page from the Tick[3] comic, which went something like:

On 10 Oct 2008, at 9:00 pm, Tommy M. McGuire wrote:
Iain Barnett wrote:
On 9 Oct 2008, at 9:33 pm, Andrew Coppin wrote:
I think it's just the teaching of the language that needs work, not so much the language itself. As a newer user myself, I'd agree with this statement. I'd like to see far more mundane tasks solved in tutorials.
I would agree as well. My own flailings led to Software Tools in Haskell[1], which taught me more about how to actually do things[2] than the textbooks that I have read.
That looks like a really useful resource, thanks. I've just read the introduction and that is the same experience I've been having, (ending up with bits of programs and nothing really practical). I'm currently trying to write some simple games in Haskell, and learning a lot along the way.
Haskell is can obviously do some really interesting things, but constantly having wikipedia open so I can look up whatever mathematical doodah has just been mentioned can get draining. Even Real World Haskell suffers a bit from this.
The mathematical doodahs are *very* useful, much more so than any other language I have used, but it helps to have some kind of foundation to understand how and why. I am frequently reminded of a "How to Draw" page from the Tick[3] comic, which went something like:
Yep. They're certainly useful, it's just that explanation and knowledge aren't always the fastest route to understanding. Sometimes it's better just to get on with things and just do it - you don't learn how to drive by getting lessons on the combustion engine from a physicist :) On 10 Oct 2008, at 9:50 pm, Don Stewart wrote:
Haskell makes constructing true parsers just as easy,
You're not speaking for me there! :) I really like regex. It's a domain specific functional language, so why rewrite the wheel? Iain

On Fri, 2008-10-10 at 22:24 +0100, Iain Barnett wrote:
On 10 Oct 2008, at 9:00 pm, Tommy M. McGuire wrote:
Iain Barnett wrote:
On 9 Oct 2008, at 9:33 pm, Andrew Coppin wrote:
I think it's just the teaching of the language that needs work, not so much the language itself. As a newer user myself, I'd agree with this statement. I'd like to see far more mundane tasks solved in tutorials.
I would agree as well. My own flailings led to Software Tools in Haskell[1], which taught me more about how to actually do things[2] than the textbooks that I have read.
That looks like a really useful resource, thanks. I've just read the introduction and that is the same experience I've been having, (ending up with bits of programs and nothing really practical). I'm currently trying to write some simple games in Haskell, and learning a lot along the way.
Haskell is can obviously do some really interesting things, but constantly having wikipedia open so I can look up whatever mathematical doodah has just been mentioned can get draining. Even Real World Haskell suffers a bit from this.
The mathematical doodahs are *very* useful, much more so than any other language I have used, but it helps to have some kind of foundation to understand how and why. I am frequently reminded of a "How to Draw" page from the Tick[3] comic, which went something like:
Yep. They're certainly useful, it's just that explanation and knowledge aren't always the fastest route to understanding. Sometimes it's better just to get on with things and just do it - you don't learn how to drive by getting lessons on the combustion engine from a physicist :)
On 10 Oct 2008, at 9:50 pm, Don Stewart wrote:
Haskell makes constructing true parsers just as easy,
You're not speaking for me there! :) I really like regex. It's a domain specific functional language, so why rewrite the wheel?
It's a domain-specific *declarative* language. Turning it into a true functional language makes it something entirely different. jcc

Iain Barnett wrote:
On 10 Oct 2008, at 9:50 pm, Don Stewart wrote:
Haskell makes constructing true parsers just as easy,
You're not speaking for me there! :) I really like regex. It's a domain specific functional language, so why rewrite the wheel?
Because it's a wheel that looks like the wrong end of a dog? :-}

On Fri, 2008-10-10 at 22:40 +0100, Andrew Coppin wrote:
Iain Barnett wrote:
On 10 Oct 2008, at 9:50 pm, Don Stewart wrote:
Haskell makes constructing true parsers just as easy,
You're not speaking for me there! :) I really like regex. It's a domain specific functional language, so why rewrite the wheel?
Because it's a wheel that looks like the wrong end of a dog? :-}
identifier = lexeme $ match "[[:lower:]_][[:alphanum:]_]*" (pretending match :: String -> Parser String is a regex engine). vs. identified = lexeme $ do c <- satisfy isLower <|> satisfy (=='_') s <- many $ satisfy isAlphaNum <|> satisfy (=='_') return (c:s) I'm not sure I follow you here... jcc

On Oct 10, 2008, at 5:46 PM, Jonathan Cast wrote:
identifier = lexeme $ match "[[:lower:]_][[:alphanum:]_]*"
(pretending match :: String -> Parser String is a regex engine).
vs.
identified = lexeme $ do c <- satisfy isLower <|> satisfy (=='_') s <- many $ satisfy isAlphaNum <|> satisfy (=='_') return (c:s)
lexeme $ (:) <$> (lowerChar <|> char '_') <*> (many $ alphaNum <|> char '_') ? or (since we're not really talking about full fledged parsers that need lexemes here or such, but usually interpreting a single string, otherwise regexes will quickly become atrocious) foo (x:xs) | isLower x || x == '_', (xs', rest) <- break alphaOrUnder xs = Just (x : xs', rest) | otherwise = Nothing where alphaOrUnder = liftM2 (||) isAlphaNum (=='_') foo [] = Nothing A bit more verbose, sure, but operating on text functionally makes it really easy to reason about what your parser is actually doing, unlike the mysteries of a regex. --Sterl.

[4] http://www.crsr.net/Programming_Languages/SoftwareTools/ch6.html
Hi Tommy, I had never seen this before. It nicely fills a gap, and I really like the format and the writing. Bookmarked. Thanks! -Simon

If you want quick examples of idiomatic haskell including stdin/stdout
I/O, I like this page:
http://www.haskell.org/haskellwiki/Simple_unix_tools
-- ryan
On Fri, Oct 10, 2008 at 7:08 PM, Iain Barnett
On 9 Oct 2008, at 9:33 pm, Andrew Coppin wrote:
I think it's just the teaching of the language that needs work, not so much the language itself.
As a newer user myself, I'd agree with this statement. I'd like to see far more mundane tasks solved in tutorials. The number of times building a parser or generating prime number is used as an example is out of proportion to the times you'd use these things[1]. Just simple, *really* easy things would be better. Maybe it's just me, but if I wanted to learn perl or ruby or python or C# I'm not sure I'd ever see a _tutorial_ containing a prime number.
Haskell is can obviously do some really interesting things, but constantly having wikipedia open so I can look up whatever mathematical doodah has just been mentioned can get draining. Even Real World Haskell suffers a bit from this.
Iain
[1] In years of programming (other languages) I've never had to generate my own primes or build a compiler or a parser. I may have parsed things, but that's different to building an entire parser, if you get my drift.
Actually, tell a lie. I have built a parser, but it's still not stuff for a beginner's tutorial IMHO. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (20)
-
Andrew Coppin
-
Anton Tayanovskyy
-
apfelmus
-
Claus Reinke
-
Devin Mullins
-
Don Stewart
-
Iain Barnett
-
Jason Dusek
-
John Goerzen
-
Jonathan Cast
-
Justin Bailey
-
Martin DeMello
-
Mauricio
-
Niklas Broberg
-
Ryan Ingram
-
Simon Michael
-
Sterling Clover
-
Steve Schafer
-
Svein Ove Aas
-
Tommy M. McGuire