

Try Haskell: An interactive tutorial in your browser - chrisdone
http://tryhaskell.org
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).<p>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.<p>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.<p>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.<p>I am also interested in hearing about general ideas on what you think would just be cool to see.<p>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.<p>Cheers!
======
chrisdone
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.

Cheers!

~~~
phob
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!

~~~
chrisdone
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!

~~~
sdp
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

~~~
dkersten
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.

~~~
sdp
_...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.

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

------
zbanks
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.

~~~
chrisdone
Hi, TryHaskell actually uses mueval underneath. See here
[http://chrisdone.com/posts/2010-04-05-haskell-json-
service-t...](http://chrisdone.com/posts/2010-04-05-haskell-json-service-
tryhaskell.html) 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!

------
DenisM
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.

~~~
chrisdone
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!

~~~
DenisM
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.

------
tumult
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?

~~~
chrisdone
[http://tryhaskell.org/?input=%3a%74%20%69%64%20%3e%3d%3e%20%...](http://tryhaskell.org/?input=%3a%74%20%69%64%20%3e%3d%3e%20%69%64)

Tada!

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?

~~~
tumult
You, sir, are the man.

------
cx01
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.

~~~
chrisdone
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!

~~~
cx01
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.

~~~
chrisdone
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.

~~~
cx01
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.

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

~~~
cx01
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.

------
paulgb
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?

~~~
chrisdone
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.

~~~
paulgb
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.

------
vrode
Great, I always wanted to try these languages But

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

is a big turnoff.

~~~
chrisdone
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!

~~~
vrode
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.

~~~
chrisdone
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.

