News for hackers. Stuff that matters.
Re:Why Clojure? (2018) by johnday on Sunday January 03, 2021 @12:09PM (#25623061)
Now I'm somewhat biased, but that complete list of advantages also applies to Haskell. [^1]

In fact, nearly all of the claims made about Clojure here can be made about haskell more strongly.

I've half a mind to do a direct comparison on every point. I'd be interested to hear the author's thoughts on the similarities and differences.

[^1] With the obvious exceptions of s-expressions, java/js interop, and "subjectively good design".

Re:Why Clojure? (2018) by teodorlu on Sunday January 03, 2021 @01:25PM (#25623713)
I really appreciate both Clojure and Haskell. I agree that

> nearly all of the claims made about Clojure here can be made about haskell

, but I'm not sure about `more strongly´.

## DX with Haskell (and ML friends) I miss in Clojure:

- Harder to do sound, up-front design with data types and module interface, where implementation becomes almost trivial after when the type signatures make sense

- Consistency checks from compiler / type checker

## DX with Clojure I miss in Elm/Haskell:

- REPL ergonomics, where every action I could think of makes sense as a REPL command, leading to very small incremental pieces.

- Excellent default data structures with literal representation and serialization (EDN)

I'd love to read a point-by-point discussion of the article sections comparing Haskell and Clojure, though that's much to ask for in the comments field.

Re:Why Clojure? (2018) by JackMorgan on Sunday January 03, 2021 @05:30PM (#25625835)
I've done a non trivial amount of both Haskell and Clojure, and this comment really hits the nail on the head. Each has non-overlapping strengths that I miss when switching. However, I've lately found F# to be my nearly perfect blend of enough things that I regularly use that I mostly just use that or Haskell when I'm messing about with katas.
Re:Why Clojure? (2018) by teodorlu on Sunday January 03, 2021 @05:43PM (#25625933)
As someone who hasn't written any F#, I'm curious about F#'s advantages over Haskell.
Re:Why Clojure? (2018) by JackMorgan on Sunday January 03, 2021 @06:48PM (#25626431)
I've had bad luck with Haskell's laziness causing hard to debug performance issues. Also the lack of libraries really hurts when it comes to even basics like queue and database interactions. Many times there's a few libraries that are all half finished. Don't get me wrong, I really like Haskell a lot, I just find that F# brings a lot of well-thought out compromise between Haskell and the wealth of libraries in .NET for production code. If it was my money in my startup, I'd have no qualms betting on F# to get me to market as soon as possible. If it was my personal OSS project that I work on for personal edification and enrichment, I'd choose Haskell nearly every time.
Re:Why Clojure? (2018) by mumblemumble on Sunday January 03, 2021 @09:38PM (#25627422)
If I had to pick one single advantage of F# over Haskell, it would be the general lack of partial functions. F# also does some really neat things with pattern matching. (See, for example, active patterns.)

The C#-style object model is arguably an advantage for certain purposes. I always feel guilty doing it, but object oriented domain modeling really does feel more natural for certain classes of problem.

On the downside, F# lacks higher kinded types, and you're absolutely on your own when it comes to making sure things that should be pure are actually pure.

Re:Why Clojure? (2018) by johnday on Sunday January 03, 2021 @01:30PM (#25623768)
Really nice insight, thank you! Clojure has always been a bit of a mystery to me, so this is interesting to read.

- REPL ergonomics, where every action I could think of makes sense as a REPL command, leading to very small incremental pieces.

This is the only point I would dispute. The GHC interpreter `ghci` is very powerful and offers a lot of the same upsides. Beyond this, the language server offers in-code evaluation with "-- >>> expression" syntax, which is a cool new step towards fast looping UX. Clojure is certainly great at this, but I'd say Haskell is not far behind.

Re:Why Clojure? (2018) by teodorlu on Sunday January 03, 2021 @01:49PM (#25623974)
I've only dabbled with GHCI. I've used it as a standalone REPL for trying out small things, the same way I'd use a Python or Javascript REPL. I haven't used the REPL /the/ developer interface to the program. In Clojure, I would (1) start a REPL server, (2) connect to it from my editor, and (3) send expressions to it. I didn't develop Haskell that way, though I think it was possible with Intero[1].

Within the Clojure community, there's a perception that the Clojure REPL is one of its strongest selling points[2].

Are you using the REPL actively when developing?

Edit: really curious about the "-- >>> expression " syntax! I might have to give Haskell another go.

Edit 2: Example of this interaction in practice with VSCode[3]

[1]: https://github.com/chrisdone/intero#readme [2]: https://clojure.org/guides/repl/introduction [3]: https://github.com/haskell/haskell-language-server#features

Re:Why Clojure? (2018) by d2v on Sunday January 03, 2021 @02:20PM (#25624283)
Have you tried out ghcid? It basically just runs ghci on your program every time you save, and gives an updated list of errors and warnings. Not interactive in the sense that you don't manually test your functions with it, but like 95% of debugging in Haskell is just fixing errors at compilation time. I find it to be a very nice developer experience. Just need a text editor and a terminal with ghcid open and you get immediate feedback as you program.

https://github.com/ndmitchell/ghcid

Re:Why Clojure? (2018) by teodorlu on Sunday January 03, 2021 @05:37PM (#25625891)
Haven't heard of it before, but this looks super interesting! Thanks for the recommendation. I really like the fact that my whole development workflow could be a text editor and a terminal.

I enjoyed developing Elm with TCR[1] a while back; also with an editor + a type checker (plus the revert part). I recompiled my whole source on each save; incremental recompilation should scale better.

[1]: https://medium.com/@kentbeck_7670/test-commit-revert-870bbd7...

Re:Why Clojure? (2018) by remexre on Sunday January 03, 2021 @02:10PM (#25624166)
This is definitely weaker than a SLIME-like REPL, but I use ghcid --warnings --test My.Module.Tests.runTest, where runTest is tasty's defaultMain, to get near-instantaneous test running on changes to files. (Since it's GHCi instead of GHC, waiting for a full compile is unnecessary, and it still has the necessary smarts about what needs reloading to avoid reloading the whole project every change.)
Re:Why Clojure? (2018) by marcosdumay on Sunday January 03, 2021 @07:40PM (#25626758)
I program in Haskell much more than in any Lisp.

But AFAIK, GHCi doesn't have any state saving functionality (I don't think the dev environment is even integrated enough for any to work), and the little code edition available is entire function only. The Haskell REPL is entirely oriented into the "you write the code on the editor -> you evaluate it on the REPL" way (again, AFAIK, the GHCi manual is huge).

That said, yes, it's a really seamless cycle of you write your code on the editor -> you evaluate it on the REPL, and yes, Haskell requires doing that very little, most problems stop at the type checker. Haskell does really not afford interactive programming, but I wouldn't classify that as a problem.

Re:Why Clojure? (2018) by cdmckay on Sunday January 03, 2021 @12:23PM (#25623163)
The JVM interop is a huge positive for Clojure, in my opinion.

Being able to consume any JVM library makes Clojure usable in many more professional settings than Haskell.

Re:Why Clojure? (2018) by johnday on Sunday January 03, 2021 @12:41PM (#25623317)
Yeah, that makes sense. If the killer app is JVM interop, nothing but JVM based languages should even be on the table. The "why Clojure?" question just becomes "because Clojure is the best language on the JVM," which is not too interesting of a topic IMO.

Haskell has decent interop with C/C++ languages, but certainly nobody uses haskell because of that.

Re:Why Clojure? (2018) by BoiledCabbage on Sunday January 03, 2021 @01:06PM (#25623545)
If the killer app is practical usage than Clojure clearly comes out on top.

The problem with function language adoption is people keep pushing Haskell likes it's anything more than at its essense a language exploration research project.

The fact that you'd have a comment that ignores a language because it wins by default because it practical is more proof that people evaluating languages are speaking two different... well languages.

Some are looking for what they feel have the coolest ideas, others are looking for languages with very cool ideas, much better than what they're using today, and can still be effective/ productive in. Haskell is cool if you want to think about or play with ideas. Clojure is cool ideas, and can still be productive in (ie full modern library support).

As well if you don't know, F# falls into that same bucked of cool ideas, better than your avg imperative language and can still be very productive due to language and .net library.

We're trending to a point where any non-systems language is just an exploratory language unless it's build on JVM or .Net.

Otherwise the produvtivity loss from lack of libraries is almost impossible to overcome from any possible produvtivity gains from the language.

Re:Why Clojure? (2018) by mumblemumble on Sunday January 03, 2021 @03:01PM (#25624695)
> We're trending to a point where any non-systems language is just an exploratory language unless it's build on JVM or .Net.

I certainly hope this does not turn out to be the case.

Both the JVM and .NET impose a certain type system on all their client languages. Those languages have an option to embrace it, like F# or Kotlin have, or to struggle against it, like Scala has, but they don't have the option to truly pull free of it. Not without shutting out effortless interop with the rest of the platform, and, in doing so, undermining the whole purpose of being on those platforms in the first place. And, since most the interesting developments in programming languages center on type systems, that implies that huddling together on the Big Two bytecode VMs stifles a lot of really interesting innovation.

Re:Why Clojure? (2018) by BoiledCabbage on Sunday January 03, 2021 @04:49PM (#25625576)
> since most the interesting developments in programming languages center on type systems, that implies that huddling together on the Big Two bytecode VMs stifles a lot of really interesting innovation.

Not disagreeing at all. Interop with a library means interop/conformance with its type system. Which means if you want languages with new / innovative type systems, someone will need to build a library system to resolve this.

Either an untyped library system as large as the .NET or Java library systems, or a library that has a trivial way to tack on type transformation of some form so that each language that interops with it can minimally add a type translation layer between the two. What that looks like, I'm not certain.

But as long as engineers need to be productive, they need a robust modern library system. No new lang will get adopted if the lang author also needs to build up a complete library system, so it must be a general component.

Re:Why Clojure? (2018) by mumblemumble on Sunday January 03, 2021 @05:31PM (#25625845)
I'm hopeful that Rust will lead in a good direction.

A C-style ABI, by virtue of being the least common denominator, is probably the best bet for re-usability across paradigms. Higher level languages would want to write idiomatic façades, but they already habitually do that anyway, even on higher-level platforms like Java and .NET.

And I think that deterministic memory management is probably also a pretty important feature. You don't want your libraries all bringing their own clever ideas about object lifetimes and such. But you also need it to be very reliable; a real danger with inviting libraries written in C and C++ into your process space is that they are liable to corrupt your memory. Rust's affine type system seems like a big step in the right direction here.

Similar thoughts for the error model. I don't have any particular complaints about exceptions, except that you don't want to be bleeding them on an external API, because that ends up being another spot where languages can fail to mesh.

What's missing, though, is that there is no good cross-platform standard for libraries that work with the C ABI (neither in source nor binary form) for other languages to plug into. So that's where I get to thinking that Rust might be closer to (if not exactly at) the mark than C is.

Re:Why Clojure? (2018) by thu2111 on Monday January 04, 2021 @07:33AM (#25630494)
I don't think that's really the case anymore. You have to separate three things:

1. Using the JVM for its capabilities, like the JITC and GC engines, which are very powerful.

2. Using the JVM for Java interop.

3. Using the JVM for generic cross-language interop.

The nice thing about the JVM especially now with Graal/Truffle is it lets you explore and choose almost any point on the spectrum between "we're totally alien and the JVM is just our runtime" and Kotlin-esque "we are basically Java v2 with perfect interop". Modern JVMs are capable of running languages as diverse as Haskell, JavaScript, Kotlin, Ruby, WebAssembly, LLVM bitcode etc. Obviously if you're coding in C or Rust and running it on the JVM via Sulong, your interop is going to be limited to creating objects and invoking simple functions on them. If you're in Ruby or Python your interop gets better: you can expect automatic translation of things like Java-world collections to a vaguely native-language like collection via the Polyglot interop layer. And if you're Kotlin then you don't even create your own collections at all, just use the JDK standard library.

The point is, you don't have to use the Java bytecode type system to interop with Java or other languages anymore. Graal has fixed that. Your language can have any arbitrary semantics and it will still be JIT compiled, GCd and it can still call into other languages. The closeness of the type system is now a choice you make that trades off ease of use of Java libraries vs whatever divergence you want to have.

Re:Why Clojure? (2018) by mumblemumble on Monday January 04, 2021 @08:34AM (#25631069)
> Modern JVMs are capable of running languages as diverse as Haskell, JavaScript, Kotlin, Ruby, WebAssembly, LLVM bitcode etc.

As long as you don't mind either poor performance, or paying Oracle a bunch of money for good performance.

What all the fancy marketing takes pains not to say directly is that GraalVM is shareware. The open source version is just a basic version with some teaser features to get you interested, and, in classic Oracle fashion, the price of the full version is, "If you have to ask, you can't afford it."

I have no real objection to that model for other products, like BerkeleyDB. But I wouldn't want to build an entire open source ecosystem on a foundation like that.

Re:Why Clojure? (2018) by thu2111 on Monday January 04, 2021 @11:31AM (#25633573)
The open source version of Graal does not have poor performance, by any means. It's more or less as good as regular Java, or better for some languages, but it's not really worse except perhaps on a few specific microbenchmarks.

Moreover, GraalVM is open source. Please don't try and redefine basic terms, as otherwise by your logic Linux would be shareware because Red Hat sell a better version of it, Android would be shareware, Chromium would be shareware etc. Making an open source product and selling a better version that isn't is perfectly legit. If you don't believe that, how do you envision platforms be funded?

As for the pricing, it is or was on their online shop. You could buy it with a credit card. Seems they have a problem with their store right now, but I've seen public price lists in the past. It's expensive but not at all "if you have to ask you can't afford it".

Re:Why Clojure? (2018) by mumblemumble on Monday January 04, 2021 @01:39PM (#25635923)
From what I've seen, it's only the small benchmarks where the open source version of Graal is on par with regular Java, because their short run-time ensures that all the bits that give HotSpot its name don't have a chance to kick in.

I think my point stands regardless of any quibbling about terminology. I've got no objection to some sort of free-however-you-capitalize-it-but-with-paid-premium-features model in general. But baking such a business model into something as fundamental as a cross-platform ABI standard sets a really bad precedent. Having lived through the late '90s, that sort of thing immediately brings the phrase, "embrace, extend, extinguish," to mind.

I'm glad to hear they've started publishing a sticker price. My memory isn't what it used to be, but I believe that wasn't the case when I evaluated it.

Re:Why Clojure? (2018) by thu2111 on Tuesday January 05, 2021 @08:52AM (#25645474)
Are you mixing up Graal the JIT compiler with Native Image the tool that spits out ahead-of-time compiled executables? When I say "Graal" I mean the JIT compiler that can run on regular HotSpot and is just an ordinary Java JITC implemented in Java.

You have to distinguish between technical standards and implementations.

JVM bytecode is a technical standard for a portable, cross platform, strongly typed ABI. Anyone can implement it based on the docs.

Truffle is an open source API with a clear specification for creating interpreters. Anyone can implement it based on the docs, although there's no reason to do so given its permissive licensing.

Beyond that it's all implementation: the Graal JIT recognises when it's compiling Truffle interpreters and does it in a fast way, but it doesn't have to and Truffle interpreters can run on any JVM including those that pre-date Truffle's own existence. They just won't be as fast. GraalVM EE is a for-pay version that does an even better job, well beyond state of the art, but the open source free version is no slouch and Scala code can go faster by e.g. 20% or more even with the open source version.

There is ALSO the native-image tool that compiles things to native code ahead of time. Many people use the word Graal to mean this, because it's the most eye-catching thing in the suite, but that's not correct. It's called either native-image or SubstrateVM. The open source version of this produces code which is slower than regular HotSpot runs but has no warmup time and starts instantly. The speed drop is due to losing profile guided and speculative optimisations, it's not a pricing issue. The EE version of native-image that you pay for has various other features like the ability to gather profiles using HotSpot and then use them when compiling to win back some of the speed, but not all of it - you can't really beat Graal JITC on HotSpot for peak performance. The EE version also has some other useful features for security and sandboxing.

In other words, the Java/Oracle guys seem to be doing exactly what you'd want to see: there are standards, specifications and then implementations - all clearly separated. There are open source implementations, and better ones with support contracts that fund the development of the whole shebang.

Re:Why Clojure? (2018) by Scarbutt on Sunday January 03, 2021 @02:49PM (#25624558)
While all of this is true and interop can save you from being completely stuck in a problem on many occasions, the interop is not as seamless as many advertise, at least not in Clojure, don't know about F#. Many times in Clojure is easier to write two wrappers, one in Java (to make the Java lib access tolerable from Clojure lol) and the Clojure one. And I'm talking about ad-hoc wrappers for your use case/functionality needs, not general wrappers, which take much more time. Productivity goes down in this translation, you start to wonder why are you wasting all this time wrapping Java libs. Kotlin is much better in this area of course.
Re:Why Clojure? (2018) by thu2111 on Monday January 04, 2021 @07:35AM (#25630511)
Can you elaborate on this? What do the two wrappers need to do - where is the primary pain points?
Re:Why Clojure? (2018) by andrewem on Sunday January 03, 2021 @01:08PM (#25623567)
I think there are at least two cases where JVM interoperability is relevant. The first is when a company is already using the JVM and so knows how to deploy and monitor it; in that case, it’s easy to choose because it presumably imposes limited burdens on the company’s operations people. The second case is when you want access to some mature environment, so that all kinds of packages and services are available to support it, but don’t have a commitment to any one in particular yet, and Clojure qualifies because of the JVM; in that case, a non-JVM language like Python, PHP, or Ruby might also work.
Re:Why Clojure? (2018) by didibus on Sunday January 03, 2021 @02:14PM (#25624202)
It's not just killer JVM interop, it's killer all around interop. Clojure relies on interop more than any other major language, the language has inherent syntax around it and even its standard library is designed with it in mind. That makes it very easy to adapt over different runtimes, giving Clojure more reach than most. That's why you have Clojure JVM, Clojure CLR, Clojure Unity, ClojureScript, Clojerl (Clojure on BEAM), etc.
Re:Why Clojure? (2018) by fiddlerwoaroof on Sunday January 03, 2021 @12:29PM (#25623217)
Yeah, I worked at a company where several Haskell projects crashed and burned because of interop issues with existing JVM systems, but the Clojure project I worked on did really well.
Re:Why Clojure? (2018) by city41 on Sunday January 03, 2021 @12:51PM (#25623411)
ClojureScript is another plus. I'm unsure what Haskell's story is for frontend dev (I have no Haskell experience).
Re:Why Clojure? (2018) by teodorlu on Sunday January 03, 2021 @01:32PM (#25623794)
As someone who tried out GHCJS, then Purescript, then Elm, then Clojurescript:

- GHCJS and purescript are powerful, but the learning experience might be steep[1]

- Elm is an excellent entrypoint into ML programming in the browser. Solid story for new users, and a great standard library for interactive web applications.

- ClojureScript differs from Elm in that it embraces its host, with all its power and all its wrinkles. Writing Elm is mostly a smooth experience. Read the guide[2], then you can actually build a web app.

I've spent the most time with Elm. Other people might have different experiences.

[1]: a few years since I tried, might be better now. [2]: https://guide.elm-lang.org/

Re:Why Clojure? (2018) by johnday on Sunday January 03, 2021 @12:56PM (#25623456)
The GHC compiles Haskell either directly to assembly or via LLVM. There is a GHCJS project, which works fine, but personally I've not used it. There's not much of a story in terms of frontend Haskell.

On the other hand, there are two "child" languages of Haskell for the job: Elm, which is a frontend-focused language, and PureScript, which compiles to JS and is designed for that use case.

Re:Why Clojure? (2018) by vnorilo on Sunday January 03, 2021 @01:17PM (#25623643)
I actually don't want to get into the argument over which is better, but dynamic and static types do change everything, also with regard to how those features in the list feel in a language.
Re:Why Clojure? (2018) by johnday on Sunday January 03, 2021 @01:32PM (#25623783)
Agreed! Asking which language is "better" is a fool's errand. But talking about specific upsides, especially in comparison with other languages, is a useful reductivist tool in determining how we can improve the story for each language.
Re:Why Clojure? (2018) by fulafel on Sunday January 03, 2021 @01:27PM (#25623729)
Compared to Haskell, Clojure, like Elixir and Erlang and Scheme, is a much smaller and simpler language and is easier to learn especially for people without a theoretical CS / math background. This is due to Haskell's ambitious and powerful static type system.
Re:Why Clojure? (2018) by mac01021 on Sunday January 03, 2021 @01:33PM (#25623800)
I'm not sure Clojure is _simpler_. I think Haskell may have more regularity and less variety in language constructs.

I won't dispute that it is more alien to most programmers, though, and that laziness and monadic IO require a bunch of work to get used to.

Re:Why Clojure? (2018) by didibus on Sunday January 03, 2021 @02:09PM (#25624154)
Interop, REPL driven development, s-expressions, and great support for working with maps seem to be the ones that don't apply to Haskell from my quick glance.