"Haskell vs. PureScript:" mmmm? just bad tech journalism

I was looking for something to help me understand strict evaluation in purescript, coming from being so used to lazy Haskell. I came across “the difference is complexity”, published in the past few days.

Firstly, I hate articles pitching language A “vs.” language B. It’s never that simple.

Then I read a load of meaningless gibberish “about” Haskell. To pick a few:

  • “calculate types” – we usually say “infer” or “solve” types, because the compiler needs to figure out the types of every expression at compile time. But then every strongly-typed language does that, including (presumably) purescript. Why’s that in the same breath as “execute operations”?
  • " write control structures like if-then-else" did the dude actually read the comments at the link? In procedural languages if-then-else is a control structure; in Haskell it’s an expression. [Actually ALGOL has both if-then-optional-else as a control structure and if-then-else as an expression structure.]
  • " in Haskell, data structures are immutable by default." errm always immutable from the end-user-programmer’s in-programme point of view. There are packages that behind-the-scenes mutate the in-memory structure; but for an intro article this is too much detail which is then not explained.
  • " programming operations in Haskell often relies on sophisticated levels of functional thinking and mathematics, …" well the dude’s entitled to a point of view; but goes on to contrast purescript … doesn’t rely on functional thinking? … isn’t sophisticated?
  • “The language exposes many underlying details that would otherwise remain hidden from most developers as abstracted library implementation code.” Huh? The purpose of library code is exactly to abstract away implementation detail. How does Haskell “expose … underlying details”? And again, why’s it any different to purescript?

I’d describe that last paragraph before turning to purescript as meaningless word-salad.

  • " PureScript offers straightforward installation and build processes, … easy to refactor, debug and test" so … Haskell’s isn’t so straightforward?
  • (skipping over the bit about record systems)
  • “PureScript also uses a rich type system to downplay some of the complexities associated with functional programming, such as overly verbose code or a lack of abstraction capabilities.” Haskell’s type system isn’t so rich? What complexities in FP does Haskell leave exposed that purescript doesn’t? “overly verbose code”? – contrast earlier “Haskell … features a concise syntax”.

Who is this ‘Kerry Doyle, Analyst’? A journo who’s just repeating purescript ra-ra?

I should say: what puts me off purescript is that everything I find about it assumes you have a background in javascript. And I don’t believe the " straightforward installation and build processes" stuff – perhaps that’s true after you’ve already installed/whatever javascript. But I haven’t, and the javascript environment is exactly the “underlying implementation details” that I want to abstract away from.

Before I click the link, are you getting mad at an LLM’s output?

9 Likes

Heh heh, good catch!

This (alleged) author has articles back to 2018. OTOH to see any of them I have to pay a ransom of my email address.

There’s a similar ‘language A vs. language B’ article which also reads like a puff for B. Or indeed could be an LLM’s output.

Journalists might use LLM to generate article, I think.

1 Like

I think this is a LLM article. They are proliferating like Gremlins under the rain. (eg: SQL vs CSS, Which is better?)

5 Likes

Whoa! That one’s a corker! Fish vs Bicycle: the difference is alcohol tolerance.

Gosh, you don’t say…

6 Likes

… and thus the inevitability of the Enshittification Event Horizon was reached.

(I mean the decline in quality of search has been observable for years and years already, but LLMs are probably going to put the final nail in the coffin for any search based on the public web.)

3 Likes

The article isn’t really that good, but I would like to highlight a key feature that I see could convince Haskell developers to try PureScript: support for different backends.

I know it’s possible to write various GHC backends to target other languages, but the process seems to be easier in PureScript, probably due to strict evaluation by default. Optimizers like purescript-backend-optimizer demonstrate what is possible in terms of compilation optimization. As far as I know, there is some ongoing effort to standardize backend development, which will certainly propel the language even further in that regard and may even assist with the language bootstrap in the future.

2 Likes

I would like to highlight a key feature that I see could convince Haskell developers to try PureScript: support for different backends.

…and there’s probably been plenty of support for different back-sections in e.g. Prolog and (non-strict ) R. But I suspect the intent of that article was to present PureScript to JavaScript users looking for a change, rather that attract Haskell users (e.g. monadic code in PureScript vs monadic code in Haskell: what’s the difference?)

I suspect the intent of that article was to attract clicks.

I agree with AntC2 that it’s terrible. If you would like to read a comparison between Haskell and PureScript from the perspective of someone familiar with the former, we make some effort to keep Differences-from-Haskell.md up-to-date (though this reminds me to get something in there about how our visible type applications, newly released in 0.15.10, are different).

1 Like

Thanks. My original q was very much focussed on the programmer experience/front end.

PureScript rests on Javascript. So isn’t it restricted to whatever back-ends Javascript supports?

GHC can produce LLVM output, so is restricted to whatever that supports?

I can see the optimisation story might be different: lazy functional programs produce probably weird LLVM code that its usual optimisers can’t make sense of.

The PureScript compiler, purs, implements a pipeline that uses an IR called CoreFn. By default, CoreFn isn’t written to disk and is consumed by purs's internal JS-outputting backend. But purs can be told to output CoreFn instead, and there is a small ecosystem of backends that read CoreFn and output code native to whatever runtime the backend targets.

(purs itself is written in Haskell and does not require a JavaScript engine to run. This is also currently true of spago, our equivalent to cabal-install, but a PureScript rewrite of spago is nearing completion and then it won’t be.)

There are caveats and complications for those who would do such things (libraries that do FFI need to support non-JS backends by writing FFI files specific to each one, for example), and much of this is folk knowledge not adequately documented anywhere. But that’s how it works in theory.

Thanks. I think I had read that before (probably an earlier version). Rather than it being aimed at a Haskell audience, the Intro seems to be aimed at a Javascript audience. That’s not me, which is why I was looking for some other docos. (Can I suggest that if that page is aimed at somebody looking for “differences from Haskell” you restructure the material.)

As the evaluation strategy matches JavaScript, interoperability with existing code is trivial - a function exported from a PureScript module behaves exactly like any “normal” JavaScript function, and correspondingly, calling JavaScript via the FFI is simple too.
… overly complicated JavaScript output.

I don’t have any Javascript code/interoperability is no requirement. I have no idea what is “normal” or “overly complicated” vs abnormal Javascript/I don’t care. Indeed I want the Javascript layer to be invisible [**]. (Just as the C layer is with GHC.) So this couple of paragraphs scares me that I’m going to need to know Javascript. It actively put me off purescript.

… introducing laziness on top of JavaScript comes with an unavoidable overhead.

I like laziness. (I spent decades programming in procedural languages, where I had to continually think about order of evaluation. It sucks.) If I can’t approach purescript with a declarative mindset, it’s not for me.

I think for a doco to be persuasive to switch from Haskell, I need assurance my functional-style thinking won’t be disrupted. GHC has too many bells and whistles: what might appeal about purescript is that it keeps things simple. So going on about purescript having as many bells and whistles again puts me off. I’m not a great fan of VTA/it seems like more finnickety syntax for something I can do already. (Or at least I could do if only GHC would support Function Result Signatures like it did a decade ago. Does purescript have that? Yes I know they’re being reintroduced into GHC, but that’s with significantly less functionality than a decade ago.)

[**] So the later message about compiler pipeline is just blah blah I don’t want to be bothered with.

🤷 My elevator pitch for PureScript is ‘Haskell but with strict evaluation, great JS interop, and a take on records that is closer to dynamically-typed languages (but still fully statically-typed)’. If two out of those three things are not selling points for you, then PureScript isn’t for you. Our docs aren’t trying to persuade anyone; if you don’t like the design decisions that PureScript puts front and center, you shouldn’t use it.

4 Likes

Thank you for helping to make that a clear decision.

(purescript’s take on records remains a big appeal. I do like that particular design decision.)

1 Like

Indeed, native row polymorphism + JSON (especially prevalent in the JS ecosystem) is an excellent combination. It also offers notable advantages for variants, thanks to library support.

Regarding laziness, PureScript provides optional lazy evaluation through the Lazy type. Personally, I haven’t missed Haskell’s default lazy evaluation in PureScript. In my opinion, it’s a valid trade-off to enable easier interoperability with foreign languages.

1 Like