Hacker News new | past | comments | ask | show | jobs | submit login
Try Clojure (try-clojure.org)
140 points by raju on May 19, 2010 | hide | past | favorite | 60 comments



Nice work.

Assuming you're trying to advocate Clojure, I'd recommend changing your tutorial to make things look easy (as opposed to highlighting gotchas). I recommend doing math examples first. Show how it makes a good calculator, but avoid discussion of ratios. That's (unnecessarily) confusing.. just like everything in the hello world example starting from the nil output on.

By the time I got to the sequence page, I just hit next to see if there was anything else of interest. I'd already gotten the strong impression this new language would just make my life harder. Worst of all though was when I flubbed up and typed (/4 3) rather than (/ 4 3).


I don't know if you noticed, but I tried to be very explicit about the fact that the tutorial is nowhere near finished. I wrote that up in 1 hour yesterday. I'm well aware that it needs filling in with less difficult stuff. I intend to start serious work on it today.

Also, I'm trying to get Michael Fogus (author of Joy of Clojure) to write the tutorial. If he decides to do so, I can almost promise you quality. ;)


I just meant to be offering constructive feedback. The tutorial was useful for me. It's certainly way better than the tutorial I had before you wrote it! It's pretty impressive for an hour of work.


I appreciate the feedback! I didn't take any offense to what you said. :)

I'm not entirely certain I'm qualified to write a Clojure tutorial anyway, which is why I hope Michael is interested.


The person who submitted this link isn't the author of TryClojure.

http://tryclj.licenser.net/ and http://www.try-clojure.org/ both point to the same IP. And both domains are registered to Heinz Gies - who I assume is the original author of TryClojure.


Actually, I'm mostly the author of try-clojure. Heinz hosts it for me and collaborates, but I'm the majority author.


Raynes and Licenser (Heinz) have both worked on their own version of tryclojure but are collaborating on this version if I understand correctly. I'm not sure how they'll feel about this being posted early, but either way, pretty neat.


Neat! FYI, the editor is fairly busted on FF 3.6.3. Key repeat for arrow keys does not work, and paste is broken. Not sure what they're using, but it would also be nice if it supported readline-style navigation (i.e. M-f, M-b, C-e, C-a, etc).


It uses the same thing that tryhaskell.org uses. I was wondering about paste myself, but I suppose it's better for learning, just not for practicality.

The console works fine on my FF 3.6.3.


Without emacs and its plethora of hellspawn requirements for a decent clojure environment, I just don't feel comfortable!!

Grats on a nice web-based repl though :)


Yeah, yesterday I decided I wanted to do something with Lisp again, and I figured that Clojure was the hot new kid on the block, so I should use that, and now it's tonight and I still don't have SLIME hooked up to Clojure, presumably because there's no actual guide to anything, and any howto that anybody made is guaranteed to be out of date almost before they post it.

Clojure is really appealing otherwise, though, as lisps go.

Edit (2x): I had a statement here of my particular problem at the moment, but then it changed, so I deleted it.


You're going about it differently than I did (haven't gotten around to leiningen yet), but I found the top google results for linking emacs to clojure were woefully out of date. I'm a newbie to both emacs and clojure, so I couldn't figure out what I needed to do to correct for the old info.

I gave up on that route and installed elpa on emacs, which I then used to install slime, swank, and clojure. Works great!


I had a similar problem, and by far the easiest thing for me has been:

1) Add lein-swank to the dev-dependencies of the project I'm working on (i.e., add this - :dev-dependencies [[leiningen/lein-swank "1.1.0"]] - to your project.clj file

2) lein deps

3) lein swank

4) M-x slime-connect in emacs, then accept the default host/port

edit: Blogged it http://increasinglyfunctional.com/2010/05/18/my-swank-clojur...


I'm about to try that (in the middle of trying another thing at the moment), and this isn't to you in particular, but as a general complaint, why do I have to have a project.clj file to get a nice repl in emacs?


if you have slime installed, you should just be able to "M-x slime" to open a clojure REPL. At least that's how it works in my emacs.


Heh. If you have a procedure that's that simple, please blog about it.

Here's what I had to do: - Download the lein script and put it in my PATH

- Download package.el and put it in my .emacs load-path

- lein self-install

- make a project directory, and 'lein new projname .' inside it

- modify the resulting project.clj to add :dev-dependencies [[leiningen/lein-swank "1.1.0"] [swank-clojure "1.2.1"]]

- lein deps in said directory

- Install package.el, and then install slime, clojure-mode, slime-repl, and swank-clojure with it (and fight with it and get confused about why it didn't know about slime-repl until I installed it several times but then noticed it when I restarted Aquamacs)

- lein swank in said directory

- M-x slime-connect from Aquamacs

Am I doin it rong?


1. I installed ELPA from here: http://tromey.com/elpa/install.html

2. Ran "M-x package-list-packages"

3. Installed clojure-mode, slime, slime-repl, and swank-clojure.

Then I rebooted emacs and "M-x slime" just works for me (aquamacs).


This is what I did too. It works, and is simple and easy. The downside is that it sort of "takes over" SLIME and prevents you from easily using other Lisps with it. As a frequent SBCL user, I found this annoying. I ended up putting a switch in my .emacs which I can turn on and off depending on whether I want my SLIME to use Clojure, or some other Lisp. Suboptimal, and someone really needs to fix this Clojure-SLIME integration problem, but it serves my needs.


That's why the leiningen option with lein swank is useful :).


There's a short guide for getting Emacs set up on the Clojure Assembla page:

http://www.assembla.com/wiki/show/clojure/Getting_Started_wi...

The Assembla wiki is a recent attempt at fixing problem of finding up-to-date 'getting started' documentation for Clojure.


Looking better and better. Someone with design chops should fork the repo and give them a good logo and a color treatment.


Having the tutorial right there is a great improvement. Looking forward to working through it as it expands.


Lau Jensen and I worked pretty hard on the new layout. And I'll add your damned logo! Just give me time. ;)


This isn't really a Clojure specific question but is there any benefit to making 'if' a special form? Meaning you can't do:

(map if [true false true] [1 1 1] [2 2 2])

not that I can think of any reason why you'd want to do that (specifically) but Picolisp, Factor, REBOL and I'm sure a couple other languages implement if as a normal function. To take an example from some edition of programming clojure:

(defmacro unless [expr form] (list 'if expr nil form))

in factor:

: unless ( ? quote -- ) swap [ drop ] [ call ] if ; inline

no macro needed to futz with if's.

Does it have any advantages or is it just one of those things that "that's just how it's always been"?


Making "if" a special form means that it can short-circuit, and I'd rather write

    (if x big_expensive_expression y)
than

    (funcall (if x (lambda () big_expensive_expression) (lambda () y)))


You mind it mostly because the Lisp funcall/lambda syntax is complex. Contrast with Smalltalk, which lacks special forms, and does use lambdas to get short circuiting:

    someBoolean ifTrue: [ 'it was true' ] ifFalse: [ 'it was false' ]
Brackets introduce lambdas. I don't find this syntax clunky, and while I've never wanted to map ifTrue:/ifFalse: before, it's nice to be able to write your own special-form-like operators this way.


Factor and Ruby do the same thing. I agree that there's definitely value in having dedicated closure syntax.


[deleted]


Are you familiar with python? Perhaps this will help:

    if cnd:
      return do_big_stuff
    else:
      return do_other_big_stuff
has different semantics than a hypothetical "if" function call:

    def a():
      return do_big_stuff
    def b():
      return do_other_big_stuff
    return if(cnd,a(),b())
Note here, both "do_big_stuff" and "do_other_big_stuff" are evaluated, regardless of the value of "cond".

A short-circuiting if (only possible if "if" is a special form) will ONLY evaluate a() (and thus "do_big_stuff") if "cond" returns a truth-value.

Now, Factor's "if" works like this (in python):

    return if(cnd,a,b)()
That's fine- and it still has the short-circuiting semantics, but there's still a question of taste here.


Yeah okay I got it. I think the funcall/lambda stuff got me confused, it's kind of obvious in hindsight.

In which case I agree it's a matter of taste. I guess I just like the taste of Factor/REBOL always passing blocks to if, having to say t [ 0 ] [ 3 ] if instead of simply say t 0 3 if is the trade off I suppose[1].

I'm guessing it works for picolisp because it's purely interpreted? because it certainly doesn't seem to be passing lambdas to 'if'. Can anyone confirm/deny?

[1]well actually the word ? does that but to make it work for both you need to do:

: myif ( ? true false -- ) ? dup quotation? [ call ] [ ] if ; inline


It works in picolisp because the author foolishly implemented FEXPRs instead of special forms, and rather than fix this problem, spends time trying to convince people that this is actually a feature, and that it offers a certain succinctness that can't be achieved in other ways.


What about for lazy languages such as Haskell? I guess you get short circuiting by default there no?


You could have 'if' as a function, but it would mean you'd have to encase any non-literal condition in a function:

    (if (zero? x)
      0
      #(dec x))
To me, this seems a rather counter-intuitive step with very little benefit. People rarely need to use "if" as a function, so having "if" as a macro optimizes for the common case.


Well, it's actually impossible to write if as a function in Clojure.


I think it's impossible to write if as a function in anything, I'm pretty sure that at some point you need a branching primitive, but the if the VM uses and the if exposed to the user don't have to be the same thing. Like I said though, it's not a Clojure specific question, CL and Scheme both use a special form for if as well. Even if it can't be done in a JVM language it can be done. I'm just curious if there's any particular reason it isn't done, like being way easier for a compiler/interpreter to optimize or something or if it's mostly historical.


The first problem you run into is call by value. As a function the args to if would be evaluated before the function call. You could force the user to quote the branches to the if call to get around it but the special form is less error prone.


This only halfway works in Opera [10.53 on Linux]. You can type, but then if you fill the output area, only autoscrolls down after you press Enter. But otherwise, you can't see what you're typing while you type it. And then focus goes all out of whack if you scroll the tutorial, or use up arrow and down arrow. Sometimes it accesses the readline history, sometimes it scrolls the screen, and seems somewhat arbitrary. Some of this could be blamed on the betaness of Opera, though.


Man that teddy bear scares me off, I'd hate to make a typo and crash someones server.

What kind of precautions against newbie messes are there ?


Looks like it uses this for sandboxing: http://github.com/Licenser/clj-sandbox


Licenser (Heinz) and I have another project called clj-sandbox that provides sandboxing for try-clojure and sexpbot in #clojure. You're safe.


Ok, cool. Especially for newbie clojure coders hitting errm, 'involuntary infinite recursion' is pretty easy.

And I'd hate to cause a melt-down :)


A Clojure REPL that works on iPhone and iPad platforms. Will the wonders of web application delivery never cease? :)


Does it? I couldn't get it to execute anything on my iPhone. Or delete anything I'd written for that matter.

(Not knocking it. A lot of things don't work quite right on touch-only platforms. Try Haskell doesn't work either IIRC. Just a matter of testing and debugging I'm sure.)


TryHaskell is powered by Chris Done's jquery-console. So is TryClojure. Bugs in TryHaskell transfer to TryClojure by default.


Nicely done. Would be nice to support copy/paste into the editor. Get rid of the dark grey background on code snippets in the tutorial -- very difficult to read.

Having REPL inline with the tutorial is great...wish someone would build something similar for Haskell.


I'm keeping a list of REPs and REPLs: http://joel.franusic.com/Online-REPs-and-REPLs - looks like there are 4 for Haskell.



Thanks for that. The missing link here is having the tutorial and the editor together for the maximum user benefit. What would be really cool is if the online copy of RWH had this editor embedded in it. What would be even cooler is if it had some basic menu features that allowed you to save module files, compile them and execute them along with the HUGS/GHCI integration.


Note that try-clojure uses the same jquery-console that tryhaskell.org uses. ;)


I'm still experimenting with code snippet colors.


That's cool, only thing left now; in the tutorial, change the color scheme (from black on darkgray) to something a little more legible, and make the examples clickable, so I don't have to retype them in the repl.


Still working on those colors, but I'm not sure about making examples clickable. It's hard to learn if you don't pay attention to examples. :p


Awesome! Also noticed that it retains your session (at least for a while) even if you close the browser windown. It seems however to give up when trying to write code on multiple lines.


What! No Paredit?


Great work.

Please hook this up to ymacs!

Also, the highlighting in the tutorials makes the code difficult to read.


When hitting the up arrow it should go to the last line, not the first.


That's a problem with Chris Done (tryhaskell.org)'s jquery-console. I believe he's still working on proper history.


Is anyone embedding Bespin for idea's similar to this?


ideone.com has an API. Would be cool to see those two together.


copy-paste broken in ff36 on snow leopard.


Can't navigate with arrows. Frustrating.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: