Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I am a Ruby guy torn between diving into Haskell or Clojure. Help! Every time I get excited about one feature of one (ClojureScript) I learn the other has something equivalent or potentially better (Haste).

One thing that has put me off on Clojure is 1) the ugly as hell JVM stacktraces, 2) hitting the wall of the number system results in nasty JVM errors if you are used to Ruby's trivial (to the developer at least) handling of numbers of any size, 3) the time it takes to fire up the JVM itself (I like really fast really instant unit tests)

On the other hand, what has put me off on Haskell is that 1) all its users seem like mathematics professors, 2) a lot of its libraries will fail to compile when combined with each other without a lot of hand-holding and carefulness



I'll try to dispel some of the concerns about Clojure.

1) Stacktraces in JVM may be ugly, but the amount of insight into runtime issues that the JVM offers you is generally way higher than in runtimes like cpython or MRI.

2) Clojure gives you a rather elegant way to work with the different JVM number types as it offers literals for those. I think Java Longs (the integer default) should be long enough as it's a 64 bit value. And on the floating point side the default is a double, which also seems nice to me. See: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/dat...

Above this Clojure offers BigDecimal literals and native ratios.

3) The startup time is gigantic. However, while developing you usually should not have to restart the JVM as you can update the JVM with new bytecode through the REPL. This should also dispel the concern about unit tests (although I'm not sure you can reach the necessary speed, if you talk about < 0.5 second unit tests, because the code needs to be compiled to JVM bytecode 1st. There's definitely still potential there.


One thing I've noticed is that the JVM startup time is actually pretty small. What's slow is waiting for Clojure to bootstrap itself.


Detailed discussion on startup times at http://nicholaskariniemi.github.io/2014/02/11/jvm-slow-start... (and subsequent articles by the same author).


JVM Feature Request: The ability to preserve a complete JVM state (in this case with loaded Clojure stuff) and quickly start from there.

Does anybody know if something like that is possible/already exists?



I have used http://criu.org/ on Ubuntu 14.04 to checkpoint and restore a Java process running a Clojure nREPL server. It took 480 ms to checkpoint a 128MB process and 213 ms to restore on a 2.4ghz E5645.


Not quite what you asked, but I found people recommending this.

https://github.com/ninjudd/drip


> Does anybody know if something like that is possible/already exists?

The majority of commercial JVMs that tend to be ignored on HN, provide JIT cache between runs and AOT compilation.


That's true, but it's generally like this with any Java application. The JVM starts in 0.3 seconds, but loading all your classes usually takes seconds. I don't know the arcitecture well enough, but I think it's because it looks for classes in a lot of places and unpacks JAR files etc.


That of course depends on the number of deps that you have, but you have to have a _lot_ to reach into the second range.


Yep. A JVM doesn't take more than a about 100ms to start up. But Clojure takes a long time, and Leiningen is slow as hell.


2) Clojure has sensible math with auto promotion to bignums, you don't have to worry about overflows like in Java.

3) You don't pay the price for the JVM startup time when running unit tests. When developing Clojure you have a JVM active at all time for your REPL. The JVM startup time is really only a problem if you want to write scripts.

Your first issue with Haskell is a plus! Everyone in #Haskell on freenode are incredibly helpful, and well, if they're all professors you likely to get some quality help, right?


> Your first issue with Haskell is a plus! Everyone in #Haskell on freenode are incredibly helpful, and well, if they're all professors you likely to get some quality help, right?

Eh... The Haskell community is amazing and always willing to help. They get an A for effort, but they often have the curse of knowledge[0].

> The curse of knowledge is a cognitive bias that leads better-informed parties to find it extremely difficult to think about problems from the perspective of lesser-informed parties.

[0]: http://en.wikipedia.org/wiki/Curse_of_knowledge


So the two languages have all their strength and weaknesses. I start with Haskell, and I try Clojure, time to time.

After working a while, I finally give a clear advantage to Haskell. Yes, Math people are chatty in Haskell, but you can do _a lot_ with very few Math.

In fact, with Haskell, the more your project growth, the more time you spend on interesting things. While in Clojure (and most dynamic languages), you'll lose your precious time with undetected syntax errors, and all standard unitype errors.

But for _very_ simple projects, Clojure is great in term of productivity.

So in general, I try to use the right tool for the right job.

- If you want to make a dirty thing, use a shell script or Perl. - If you want to make a prototype, Clojure is great. - If you want to make a project for production, then Haskell is the clear winner here (in term of bugs/efficiency/time).

One thing I get with Haskell I didn't got with Clojure is "code scalability". In Haskell, my code tend to be more reusable than in Clojure.


I'm curious how Haskell could be a clear winner for production code, particularly as it pertains to efficiency and time.

Clojure sits on top of the JVM, and as such, has the benefit of interop with some of the most robust software packages in the world.

Unless I'm missing something, you'd need to roll your own packages in Haskell for all this functionality.

I would argue that the most efficient code is well maintained open-sourced code that you don't have to write.

I don't use Haskell, so there may be lots of libraries I don't know about, so forgive me if this question is naive.


One of little secret of Clojure is that you almost never use Java based library. Because it forces you not to use idiomatic Clojure. So, most library you'll use in Clojure are in fact Clojure made. From this point of view of number of libraries, Haskell and Clojure are in fact at the same level.

I was sold in part by the JVM argument. But in reality, in practice, I found it to be more a burden than a delight. First, the stack trace errors. To deploy your application, it is not just a "copy your jar in Tomcat". You have to serve using Clojure. So in reality, you don't get all advantages provided by the JVM environment, only some.

Clojure is fast, but, Haskell is at least as fast as Clojure.

Up until here, I had all packages I needed. There are all here[1]. I made mostly Web oriented programming, but using MongoDB worked extremely well for example.

And the most important aspect (from my experience):

When your program growth, in Clojure the time you spend to add another feature growth rapidly (it is better in clojure than most other languages thought), but in Haskell, each new feature doesn't cost so much, even in a medium to big project.

So when you need to change something fast without breaking something (the without breaking something is the important part), nothing beat the Haskell type system (or may be Idris, but I didn't played with it enough).

Furthermore, the ability to minimize the number of bugs, gives me a good feeling about the quality of the libraries. Of course, Haskell is not magic, you still have to pay attention to bugs, to test your code. But Haskell helps a lot in not falling into dumb bugs.

[1]: http://hackage.haskell.org


> One of little secret of Clojure is that you almost never use Java based library. Because it forces you not to use idiomatic Clojure. So, most library you'll use in Clojure are in fact Clojure made. From this point of view of number of libraries, Haskell and Clojure are in fact at the same level.

In a production server I'm running right now, I've used three java libs, wrapped them very nicely and neatly, and they work great.

> I was sold in part by the JVM argument. But in reality, in practice, I found it to be more a burden than a delight. First, the stack trace errors. To deploy your application, it is not just a "copy your jar in Tomcat". You have to serve using Clojure. So in reality, you don't get all advantages provided by the JVM environment, only some.

For my current app, I just need to do: lein ring uberwar, copy to tomcat directory. done.

The rest I can't speak towards as I don't know Haskell. Also, it should be noted, I'm only offering counterpoints because I don't want people to not use clojure because of some of the incorrect claims. I guess we've had different experiences with clojure. :)


> One of little secret of Clojure is that you almost never use Java based library. Because it forces you not to use idiomatic Clojure. So, most library you'll use in Clojure are in fact Clojure made. From this point of view of number of libraries, Haskell and Clojure are in fact at the same level.

This isn't really true.

Yes, directly using a Java library forces you to use Clojure that is not idiomatic but 1) this isn't always the case 2) there are idiomatic wrappers over some libraries already.

More importantly, at least you have the option of using Java libraries. Having to use Clojure code that is not idiomatic still will be much more productive than writing the library yourself in Haskell.


Haskell does have a pretty good C FFI, so it's not as if you're necessarily going to have to reinvent the wheel. I know precisely nothing about Clojure's C FFI - I'd guess it has a fine one, which of course means that this isn't an edge for Haskell per se but it does make the Java interop slightly less important.


Just a minor point, some of the build tools allow you to make a .war file, and that you can just copy into Tomcat if you want.


Which kind of libraries are you thinking of that are missing?


imap library with idle support. haskellnet and imapget don't mention idle from what I can see. javamail does.


haskellnet looks like it does polling, but i gather its not quite the same thing. looks like you're right. I wonder how hard it would be to implement such a thing.


General advice: don't let the desire to learn the "right" thing prevent you from learning, period. Eventually, it's better to just make a choice and dive in, then to spend more time trying to figure out which one is "better".


Absolutely learn both! Make sure you learn macros well (I suggest Let Over Lambda) and Haskell's powerful type system. I know Clojure and macros pretty well, but learning Haskell the last couple months has been incredible. And then learn Forth, J, Prolog, do SICP in Scheme, etc. ;)


Agreed 100%. I can learn both, given enough time.


They're both amazing languages that are simultaneously very fun to use and very powerful, not to mention great with concurrency, but here's the grossly oversimplified gist of when you'd want which language:

Clojure has a beautiful dynamic type system. Haskell has a beautiful static type system. If you're working on a project with changing requirements (which for me means most nontrivial applications), Clojure will be much easier to work with and, as with most Lisps, is very well suited to what pg calls exploratory development. If you're working on a project whose requirements are largely static and known in advance (compilers, interpreters, parsers, static analyzers, mathematical tools, etc.), then you won't have to worry about coding yourself into a corner and Haskell's insanely powerful type system becomes a positive.


Wow. I came to the exact opposite conclusion you have. Changing requirements is really where Haskell shines. The ability to make a change in the types and have the compiler tell you everything that needs to be updated is an enormous aid to refactoring. As for exploratory programming? Haskell has powerful tools to do that as well. GHCI, type inference and typed holes[0] work extremely well for exploration of what's possible and can even give you solutions to your problem that you hadn't even thought of.

[0]. http://www.haskell.org/haskellwiki/GHC/TypedHoles


I agree, though one has to compare apples and apples. experienced programmer vs inexperienced programmer is not fair. Of course if one is unfamiliar with how to build a flexible type safe systems, (newbies), there could be these sorts of issues. But for experienced programmers, not really.


though one has to compare apples and apples. experienced programmer vs inexperienced programmer is not fair.

Oh, definitely. I just feel that far too many people focus on programming languages that are good for beginners without really thinking about them from an experienced programmer's perspective. What may be good for a beginner can often be terrible for an expert. What may be hard to understand for a beginner can be extremely powerful and simplifying for an expert.

I think the question people should ask themselves is: "Do I want to stay a beginner forever? If not, why am I using tools that are designed for beginners?"


Excellent point.

We regularly extol the virtues of expert-friendly text editors, but don't talk much about the appeals of expert-friendly languages and frameworks. Also worth thinking about: a huge amount of hype gets allocated towards beginner-level languages/frameworks that solve beginner-level problems (todo lists) more easily.


I'd guess that is because most developers ARE beginners, right up till they retire/career shift.

If we were even half experts, maybe that would change, but in a field where "anyone can be a developer" you will see a long tail of low skill.


Not sure why you were downvoted.

Industry routinely degrades skill and experience in favor of "just ship." New frameworks are continually churned out with the implicit promise that they'll fix everything (except their own lack of composition). Custom development is viewed as expensive when someone else can come along and paste several libs together, then apply duct tape to hold it all together. Domain modeling is viewed as esoteric. Testing is still hotly debated.

...I don't want to go on.


I could argue that for most people, it is only when they start bumping into the limits of the beginner's tool that they see the point of the more advanced tool.


I think this is a very limiting approach to life. It leaves one open to the Blub Paradox[0] (or more generally the Dunning-Kruger effect[1]). My personal approach is to keep an open mind and assume that there's always a better way to do something than what I am doing now.

Edit:

[0] http://www.c2.com/cgi/wiki?BlubParadox

[1] http://en.wikipedia.org/wiki/Dunning-kruger_effect


As a new programmer I'd say there's an aspect that you're ignoring. The need to take reasonable steps, and to know if not your limitations at least where you stand.

You want to take the next step that has enough familiar aspects that you can acclimate reasonably quickly and build non-trivial programs (the fun part) in a reasonable amount of time. But also different enough that you're exposed to new concepts and new ways of thinking about programming, and also to have access to a more powerful language.

Simply diving head first into a powerful but completely foreign language might not be the best way. Coding can be as frustrating as it is rewarding. And there's something to be said for trying to maximize the rewards and minimizing the frustrations.


What better way to know your limitations than to seriously challenge yourself? I taught my friend to program in Haskell and while he struggled early on he found it incredibly rewarding. Since then he's found it extremely easy to learn other programming languages, despite their extensive differences from Haskell.

There's also a lot to be said for habit-forming. Imperative languages teach you a lot of habits and cause you to develop assumptions that might actually make it harder to learn a language as different as Haskell. This makes the concept of "taking steps" in your growth as a programmer a nonlinear one. Some languages might even hurt your ability in the long run.


Although 'coding yourself into a corner' is definitely possible, I would rather hope that one makes good decisions, there is plenty of space to type things and allow re-usability and flexability. You could make a similar but different negative statement about clojure, about having to maintain a large project when the requirements change, if you're not careful you may find a change in one part of the code breaks another part of the code.


I shared your worries about the turnover time for unit tests. But if you use something like [Midje][1] with the 'autotest' feature on, your tests will run in the background after each save. It typically takes a fraction of a second to run the full suite, so by the time I'm done hitting save and switching over to the midje console, the test results are already there.

[1]: https://github.com/marick/Midje


I went for Haskell. I think Clojure is too close to Ruby in the respect that there is not much safety build in. And I --like you-- am JVM-averse. :)


Here's a serious downside of Haskell:

https://github.com/jwiegley/github/issues/25

Experienced and skilled developers (wiegley's open source work includes ledger and great contributions to emacs org-mode), and the task is to make the API client's base URL configurable. Should be trivial. And yet it descends into farcical stuff about whether they need to introduce a new github monad or to "abstract over a type class". It seems like the purity was really getting in their way. The issue was never solved. I may be cherry picking an example which serves to parody Haskell, but for me that example is really off putting.


Hey, I'm a Rubyist in the process of learning Clojure and Haskell. Shoot me an email sometime. I'd love to bounce some ideas around nick dot mcd at gmail


bitemyapp seems to have pretty clear opinions on Haskell vs Clojure: http://bitemyapp.com/posts/2014-04-29-meditations-on-learnin...




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

Search: