Hacker News new | comments | show | ask | jobs | submit login
Try Haskell: An interactive tutorial in your browser (tryhaskell.org)
39 points by chrisdone 2698 days ago | hide | past | web | 42 comments | favorite

This is already on haskell.org and I know it was posted here in the early stages, but maybe a few maybe-interested-in-trying-Haskell-ers haven't heard of it and would like to try Haskell. As of this week there are 30 tutorial steps / 7 lessons, finishing at the type system (so far).

There's a lot more potential for this project (adding a CodeMirror editor with "loadable" code, allowing uploading of tutorials like a pastebin... but a tutorialbin, asking exercise questions which are then quickcheck'd, etc.), but I like to incrementally add and then get feedback.

For newbies to Haskell I would like your feedback/comments, if you have any. I'm hoping to reach fresh Haskell newbies here on Hacker News for an unbiased experience.

I asked a non-programmer friend to try it out a while ago and got some invaluable feedback. Send it to your friends, just to see how far they get! Post what they say! Anyone who's read something like Rocket Surgery Made Easy will be familiar with how invaluable feedback is.

I am also interested in hearing about general ideas on what you think would just be cool to see.

If you want to let me know about bugs please post them here: http://github.com/chrisdone/tryhaskell/issues Granted there are some browser/OS oddities but I can only test on so many! Bugfixes welcome! PM me on github.


I thought it was great, except the way "let" was introduced was a little shocking. You just assumed what it was doing was intuitive (which it was, coming from a lisp background). I look forward to more!

That's definitely a pattern I'm seeing; people don't like the way "let" is introduced. I think in writing it I hoped it would be intuitive. I think, actually, someone suggested that I spend a few examples demonstrating it to ease the idea into the reader's brain. It seems people don't mind weird things as long as you explain them. Interesting lesson. Thanks for the feedback and thanks for trying!

I like everything up to but not including step 7. (http://tryhaskell.org/#7)

The syntax

  let villain = (28,"chirs") in fst villain
is not obvious to me, and the tutorial doesn't explain what each piece of the new syntax means, and quickly moves on to something new in step 8.

Only through experimentation, I find:

  fst (28,"chirs")
  => 28
  snd (28,"chirs")
  => "chirs"
So I gather the let is equivalent to:

  (let ((villain '(28 "chirs")))
    (first villain))
But without parens, line breaks or semicolons I have difficulty determining where one expression ends and another begins.

Plus, the arbitrary shortening of "first" to "fst" doesn't help, and should probably be clarified.

You seem to only check the return value to determine when to skip to the next step in the tutorial, since in step10, you want me to type:

  ['a','b','c'] == "abc"
But it skips ahead when I play around and return True from a different expression:

  'a' : 'b' : [] == "ab"
  => True

I have exactly the same complaint. Also, the use of "let" seems completely superfluous here. No motivation for writing

  let villain = (28,"chirs") in fst villain
rather than the much shorter

  fst (28,"chirs")
is given.

I think the lack of any sort of typographical indication of when one expression ends is really a Haskell issue, not an issue with the tutorial, though perhaps newlines could be inserted for readability. (Or does Haskell care where newlines appear?)

I've read a number of Haskell tutorials in the past, and despite having no problem with a variety of syntax types, including C-family, Lisp-family, and even having done some coding in ML way back when, I find the Haskell syntax really hard to read.

I don't think this is something a tutorial can "fix", per se, but it'd be nice if there was a tutorial that took this into account and explained how to actually decompose Haskell code without just throwing code snippets at you and hoping that you'll intuit their meaning. "Haskell Parsing for Humans" is what I want. The part at the beginning of this tutorial where it explains numbers, strings, lists and tuples is actually a good start, but "let", "=", and "in" are never explained, nor is "fst".

Hey, thanks for the feedback! Definitely let's syntax is a bit ambiguous to the newbie. I'll take a couple steps in the tutorial for explanation and experimentation. I think I'll take your advice and just go with

    fst (28,"chirs")
and then do a "small detour" (2 steps) to explain the "let" syntax, because it gets used in later chapters. Unlike the math stuff which is intuitive, I agree it needs explicit description.


It's definitely better. You might want something longer to type than 4 in the example, though.

Explaining the let syntax only after the user has had to use it once felt a bit funny to me, though I guess that's the pattern of the rest of the tutorial. I'm one of those people who tends to learn more from references than tutorials, so that might be saying more about my learning style than your tutorial.

Hey, I've updated the tutorial from your feedback. Hopefully my explanation is more fuller now! Give it a go?

Are fst and snd the standard haskell functions? It doesn't seem worth saving a few characters for how awkward it makes it to read the code, but then again, if we can get used to car, cdr and so on, I guess its not bad. Though in the case of the tutorial, it should definitely state what fst and snd are.

They are standard. There's also `first` and `second`, but they do something different:

    Prelude> :m + Control.Arrow 
    Prelude Control.Arrow> :t first
    first :: (Arrow a) => a b c -> a (b, d) (c, d)
    Prelude Control.Arrow> first (2 +) (1, 4)
In this case the Arrow instance is just (->), the function type constructor, so you could read that strange type signature as `first :: (b -> c) -> ((b, d) -> (c, d))`. But I've said too much.

...if we can get used to car, cdr and so on, I guess its not bad.

Common Lisp (and MzScheme) users can use first (and second, and third...) and rest, and probably should do so when using simple lists.

My Lisp of choice is Clojure, which also uses first, second and rest.

Hey, I will explain fst and snd. In fact I go into them in some detail in later chapters, but I'll mention their use and why they're short at this step too!

Cool. Good work on the site anyway, I had a quick look at it and it seems like a nice and easy way to learn haskell.

Hey, cheers! I've updated the tutorial to explain fst, let, etc. hopefully it's a bit more friendly now.

OK, if I explain the let syntax with some examples before demonstrating with fst and snd, will that be OK?

Actually it just checks the type of the result on that step! I'll do a syntactic check to make sure you have to type it out in that step.

Thanks for the feedback, I'll fix this today!

You might want to use mueval (http://hackage.haskell.org/package/mueval) in order to prevent evil people from being evil (at least to your server.)

It works pretty well at keeping crazy stuff out. Hopefully you added some sort of limiter to your page... but if you haven't, this is a great start.

Nice UI & stuff, though. Seems to work pretty well. It would be nice, like paulgb said, to be able to enter a block of code and execute it. I know this currently behaves a lot like ghci, but it would be nice to test larger sections of code.

Also cool job with the lessons. Sure it's pretty light, but it provides a good, quick introduction.

Hi, TryHaskell actually uses mueval underneath. See here http://chrisdone.com/posts/2010-04-05-haskell-json-service-t... for more details about how. The JSON service supports state (code loading), with restrictions on imports (e.g. no importing unsafePerformIO), it's just that I haven't added a box to TryHaskell to enter the code. Definitely, it seems people would like to write bigger sections of code, which I like! I'm still pondering how to alter the layout to support this!

1. You're trying too hard with the joking tone - it gets in the way. Jokes are funny in tutorials when they contrast with something, but if the whole thing is a long-running joke there is nothing to contrast against.

2. Inverted contrast of instruction text makes it hard to move the eyes from tutorial to command window and back.

3. There isn't actually enough explanation for what's going on. For example here "let villain = (28,"chirs") in fst villain" it's never explained what the actual syntax is. Which is where I stopped reading.

4. You have a hint that tells you how to get to current page. But I am already on the current page! What I need instead is a shortcut to get to previous page.

1. Admittedly I am just trying to be friendly and the later lessons don't really have any joking tone. If others think this detracts from the experience I'll take the jokes out.

2. I haven't heard that complaint yet! I can try lightening it up in the stylesheet.

3. I hope that's not throughout the tutorial. That one has been flagged up (my non-programmer friend had no idea what it meant, but even he persevered! Shame on you! >_-), and I knew it when I wrote it; the basic issue is there is no support for saving variables in the session state for later re-call, so you have to write out your "let x = .. in .." expression every time. As mentioned in other posts, hopefully with the introduction of loading code, this problem will be solved and I can rewrite that part of the tutorial.

4. I added that hint by request, people want to know how to get back to where they were. I can add a 'back' command and mention it within that sentence, perhaps?

Thanks for your feedback, nicely laid out and constructive!

Hey, I removed the jokes, a full explanation of let with examples and fst, etc. and a shortcut to go back. Can't change the colour yet on this machine as it's done with sprites and I need the right editor. Let me know if you try it further!

Sorry, I moved on to other things now.

I'm very impressed with your follow-trough however, and I think you will do quite well for that. It's similar to how a cruise missile can adjust the trajectory, and thus is infinitely more precise than a ballistic projectile. Good luck.

Cool. Is there a way (or can you add a way) to link people to expressions? For example, if I want to show someone :t (id >=> id), could I just give them a URL somehow?



Type something in the console and hit enter. Then type "link" and hit enter. Or type "link :t id >=> id".

How's that for a slice of fried gold?

You, sir, are the man.

There isn't a way, but I can add a way! How would you like to do it, as a user? That's a great idea, by the way!

Sorry I didn't reply earlier; working. Your chosen method is perfect.

Whenever I press "[" it actually inserts "8[" into the editor. I use Opera 10.5 and a German keyboard (on the German keyboard layout you get an "[" by pressing ALT+"8", if that's any help).

I think you might want to look at how Opera handles keydown and keypress events in Javascript. I had a similar problem working on my own project a few days ago.

Ah, I haven't tested with a German layout. I have OS X and Ubuntu available to test on. What operating system are you using? Indeed, I had to add some special support for Opera in places with the key codes. For example, it's impossible to tell, on Opera, when someone presses the End key and when they press, say, 'h', because Opera sends 'h' for both keys. (Or whatever letter.) Actually it is possible with some hackery but it is a pain!

I'm on Win7. Actually I made a slight mistake on my original comment. You get "[" by pressing ALTGR+"8" not ALT+"8". Don't know if it makes a difference.

OK, I'll try to get hold of a Win7 machine at work. Can't make any promises though! (Nearly everyone at my workplace uses Linux.) Hopefully a kind soul of German persuasion with JavaScript know-how and a penchant for Windows will come along and fix it.

I noticed that Opera sends two keypress events when I press "[". The first event (that generates the erroneous "8") has e.altKey==true.

So a simple solution might be to add the following to the keypress function "if(e.altKey) return;". I've tested this locally and it works for me, but don't know if it might interfere with other keyboard layouts.

Hmm. I think we can take the risk and if others complain we can deal with their layout too. Someone else also suggested ignoring e.altKey with this patch: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=25853#a25859

I will try applying this patch and let you know.

Ok, I applied the patch mentioned in the other post. Please try now and let me know if the issue still exists!

When I go to tryhaskell.org, it still doesn't work. I believe the patch that you've mentioned only applies to when the user presses ALT+TAB, which won't help here.

I'd suggest you either do "if(e.altKey)return;" or "if(e.altKey && e.ctrlKey)return;". Both work for me.

EDIT: Hm, my suggested changes work in Opera, but they break Chrome... This is driving me crazy.

Cool! Try Ruby was what convinced me to learn Ruby. Hopefully this will do the same for haskell.

Is there a way to bind variables? I can do things like "let a = 3 in a", but it seems that no state is stored between expressions?

I do hope this will get you into Haskell!

Hey Paul, that's correct; there's no state stored between expressions. It's planned that there be a text editor where you can put top-level definitions, kinda similar to DrScheme, if you know of it. You may notice parts of the tutorial that would've been better (e.g. having to write `let .. in ..`) with state between expressions. I will rewrite those once this is implemented.

Actually, I'm already into Haskell; my comment was poorly worded but I meant I hope it does the same for other people :-).

> It's planned that there be a text editor where you can put top-level definitions

Good to hear, I like the way Dr. Scheme does it and it makes for a good learning environment.

Great, I always wanted to try these languages But

let villain = (28,"chirs") in fst villain

is a big turnoff.

Yep, that seems to be everyone's main complaint! I should've known it wouldn't be intuitive. Oh well, lesson learned. Hopefully this is the only step like that! Cheers!

Maybe you can break up queries in keywords, where each keyword triggers a JS-balloon or title="" with explanation of its function. This way people unfamiliar with the language won't need to look up what fst is and why it is there (how rigid the syntax is).

Otherwise it is the languages fault, not yours. Sad that issues like keyword naming and syntax is often not taken seriously enough by language authors. Popularity really puts languages under a constrain of development towards the intuitive.

Would you agree with me that we need a very transparent and human readable super-language, that other languages can be easily translated into? This way it can exist exclusively for the definition of algorithms and learning purposes. This way speed and re-usability will never be an issue, and developers of this language won't need to keep its weaknesses for the sake of forward compatibility.

Hmm bubbles/titles on syntax sounds like a good idea, thanks!

I suppose if you want a super-language, you would have a language which starts from very simple constructs and one straight-forward way to define new syntax and semantics to fit a given problem, within that language itself; so that for any given problem, someone can read the solution, and if they don't know the syntax/semantics, they can read the definition which is in turn written in this really simple language. Lisp is mostly ideal for this.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact