What Purescript needs

We had some discussion around increasing Purescript’s adoption at the recent Purescript semi-monthly meetup. Continuing with that I wanted to put down my thoughts in a document which can be collaborated upon.

This is just the beginning and a very rough outline off the top of my head. People of course may not agree and I would be happy to incorporate those arguments into this doc. Of course any other additions/modifications are also welcome.

EDIT: This thread should not be used to collect grievances against Purescript. If you are facing any issues getting started it’s better to open a separate thread. The purpose of this thread is to collect suggestions of projects the community should work on which would help Purescript be usable in more situations.

8 Likes

I personally think the main barrier is this strict pure type of FP. That’s why it took Haskell so long and is still used in very specific cases.

I have no idea how you’d make the FP entry bar lower, since I’m a n00b myself, but maybe someone smarter can think of something :).

Even purescript-halogen-realworld app which is a great starting place is really off-limits if you have no idea about FP syntax and concepts. Whereas vanilla realworld app is at least understandable cause you just follow the instructions given to the computer - i.e. imperative coding.

Second is ecosystem, be it JavaScript or Python or any other backend. If you can’t find the libraries you need in order to build something it’s low chance that someone would actually implement a library from ground-up just to make an app in PureScript when you can just use the library in that backend directly. There’s a lot of hassle for more complex stuff that is, I’m not talking about a couple of FFIs here and there.

5 Likes

Even amongst the narrow category of FP languages that compile to JS, Purescript has a pretty small mindshare. The order roughly goes as follows -

Typescript >>> Elm > Reason/OCaml/Rescript > Clojurescript > Purescript

I don’t think FP is a barrier here.

A brief comparison from my limited knowledge -

  1. Typescript lacks purity and typeclasses. It’s type system is unsound, and it has any and unknown. However on the plus side it’s basically bare JS + types (hence has good JS output). And its type system has some novel features like union/intersection types, flexible tagged unions, and its support for records and unions almost matching Purescript’s row typing capabilities without runtime overhead. It makes it very easy to add safe(-ish) interfaces to existing JS ecosystem.

  2. Elm lacks typeclasses and associated novel features like monads and do-notation, and it’s harder to interop with native JS libraries. However on the plus side it really focuses on ease of use, has a large ecosystem, has good tooling, generates good performant code, and has great documentation providing the canonical way to do everything.

  3. Reason/OCaml again lack typeclasses etc. But like Elm, they generate good performant code, and have great integration with React.

  4. Clojurescript is lisp. However people like lisp?

With Purescript the situation is inverted. It has great FP features (it’s basically Haskell), better than all of the above. However, it does not generate great performant code, does not easily interface with external JS code (it needs good support for auto currying and untagged unions), and it does not have a large ecosystem of JS library support. And those things are holding it back.

Hence my assertion that Purescript needs to -

  1. Focus on the JS ecosystem.
  2. Focus on generating better code.
6 Likes

Not sure if you noticed but I do see some history of the post when clicking edit

2 Likes

Focus on the Javascript backend.

Isn’t that the case just now? For the core team at least, that’s all we work on. The only thing that could be at all seen as working against that point is we avoid things like:

Annotations that control the JS output

But that’s only partially because that would make it impossible to fully support other backends. Even aside from that I wouldn’t really be in favour of this kind of thing anyway - it’d be going backwards; the FFI was inline at one point, but it was a pain. Being able to use JS linting tools and stuff is a major benefit of having the code separate.


Tool for typescript defs -> Purescript generation

This has been talked about since 2015. There are so many problems to solve here (type system mismatch, effects) that I’m very dubious it’s ever going to happen! :wink:


Focus on performance and improved code output

I really don’t think this has much to do with why PS doesn’t have more adoption. There’s definitely a ton of room for improvement, but it’s not slow enough that it typically stops people from being able to build what they want to build.

But don’t get me wrong - I’m not saying that fixing all the points you raise here would have no impact. It’s just unfortunately I think @razcore-art’s points are closer to the truth of what stops people from picking up PS.

I think the “killer app” thing is probably the closest point listed that might have an effect on driving adoption, since that’s probably why Elm is more popular than PS… it’s as much an app/framework as it is a language. That and Elm has a significantly lower abstraction ceiling, making things appear simpler.

Sorry this is all rather negative, it seems I only have problems for this stuff, no answers.

16 Likes

It’s funny - i feel very optimistic about the possibilities for wider adoption, but i may be being delusional about it, i dunno. I’m not talking about widespread adoption, i think that’s a stretch in both commercial and academic programming given the state of the those worlds right now.

But i have a strong intuition that there are a lot of small affordances that can be given to make on-boarding easier. There are a number of virtuous circles that can arise with more people, especially in regards to lessening the burden on core developers to answer basic questions (it can go the other way too, influx of new people all asking the same questions).

I think one almost can’t overstate the importance of something like the Cookbook - de-risking the question of “could i do this in PureScript?” is a massive, massive win for adoption.

I’d also note that my impressions are that PureScript is a lot more user-friendly than Haskell already. Both at a community level (just MHO) and at a cohesiveness of the ecosystem level. Having all of Hackage to choose from is not always an advantage, since it’s a marketplace with no real ratings except downloads.

Progressive adoption is another big win for PureScript, something that’s much harder to do with Haskell, and maybe explains some of Scala’s success in the enterprise world?

edit: oh, and the IDE work and Spago have been just amazing additions, gotta feel that those smooth the path a lot for people…there’s some more things that could be done there to help total FP beginners, i’d say.

9 Likes

I personally think improving error messages should be right at the top of the list if the goal is widespread adoption.

17 Likes

…this might be a minority viewpoint but I’m actually reluctant to make widespread adoption an explicit goal. I’m very happy to see work going into things like improving compiler ergonomics (such as error messages), documentation, resources, and other similar things which undoubtedly do help with adoption, but I think we should be doing that work for its own sake, not because we want tons of people to use PureScript. I think we could have a situation where there’s a big influx of new users and not enough of a community structure there to support them properly, which might end up having the opposite of the intended effect with more people feeling more sour about PureScript than we would have had otherwise. At minimum I think we should wait until the new registry is up and running and ES modules are done before we start approaching people like ‘hey this is ready for prime time’.

22 Likes

I use PureScript because I want a Haskell layer over JavaScript. If I wanted a functional language that happens to compile to JavaScript then js_of_OCaml or Ur or Opa or Elm were available before PureScript (see also https://chrisdone.com/posts/clientside-programming-haskell/ for a complete retrospective). Today there’s TypeScript or Reason too. They all have one thing in common: they’re not Haskell.

Elm is almost Haskell, but its lack of type classes and resulting unprincipled techniques for dealing with equality, ordering, numbers etc are all unattractive. The BDFL model also isn’t my jam.

Haste/GHCJS are literally Haskell, but their output requires a runtime and that runtime needs to be maintained, and mismatches with the native JS.

PureScript fills a clear and distinct niche for me. It’s a thin enough layer that I don’t need massive community buy in or to take over the world; I can always find a JS package if I really need one, or write a few snippets myself. The strictness and FFI hit a sweet spot. It also talks to me like a grown up who is comfortable with traversable and monads. If the PS maintainers give up tomorrow, I’m not S.O.L. because I could confidently fix small bugs in the compiler if I needed to. The only real library I use in earnest is Halogen.

In other words I personally reject the “let’s market PureScript and take over the world” stance. It’s not needed, but I wouldn’t discourage others who find value in doing so. :nerd_face:

16 Likes

I agree with quite a lot of @chrisdone’s point. I use PureScript because I want to do pure functional programming and I need JS code output, and PureScript is by far the best option. All of Chris’ points about Elm, Reason, GHCJS, etc. ring true for me and I’d bet most developers that are looking for pure functional programming for JS. So I think PureScript is already well positioned there.

I think @razcore-art and @garyb hit it on the head that PureScript isn’t more widely adopted because not that many devs understand/use/like pure FP. But I really don’t think it’s a good idea for the PureScript community to try to tackle that particular problem. I think in general that’s probably best handled by the new Haskell Foundation, and in web particularly probably best handled by Elm. If the PureScript community tried to tackle it too, I feel as though it would drain significant resources without really making much more of a dent than HF and Elm already are.

So I guess my humble opinion is PureScript is better off focusing on the audience of FP programmers and making sure that PureScript continues to be a joy to use and the obvious best choice, rather than trying to focus on broadening the audience to include JS devs unfamiliar with FP. Let Elm do the hard work in that space, and then steal 'em when they get fed up with Elm’s lack of abstractions and FFI :wink:

And of course I’m not opposed to anybody putting effort into better error messages, better performance, or better interop with JS (like graceful, canonical solutions for stuff like untagged unions, JS objects with optional fields, etc.), just not as part of a larger effort to target those unfamiliar with FP as a broader audience.

12 Likes

Perhaps my point came across the wrong way. I also agree that Purescript’s FP strength should remain as is, and that should be the number one goal. I am also not advocating that the core team devote time/resources to JS interop.

This list is basically my effort to collect a wishlist of things that I think will help Purescript gain adoption, and perhaps the community can rally around and achieve some of these things. More adoption should definitely be a goal - having more people using Purescript means having a larger ecosystem, having more companies adopting it and contributing foss code, having more jobs and candidates available, having more help if you run into errors. It basically makes my job as a Purescript programmer easier.

Lack of good JS interop means that it is that much harder to interface with external libraries. That has been a big problem for me. I would love for the Purescript community to maintain type definitions for major JS packages like Typescript. Also I have worked in Purescript projects where performance and code size has been a concern. I don’t think focusing on fixing those things is incompatible with the existing things that make Purescript good.

6 Likes

I updated the github repo with some of the suggestions from this thread. I appreciate the discussion!

2 Likes

In my opinion Haskell | Purescript will be there forever, because there is no more understandable and “terse” way to express a piece of code.

Haskell | Purescript will cease to exist but the syntax will prevail in some new programming language. On the other hand
It would not make sense to let Purescript die to create a new language that implements the same syntax and neither would a new syntax make sense because we already have the most understandable and terse possible.

If you ask me for a unique feature that keeps me in Purescript I would say the “Sum Types”

And finally Purescript is desperately missing from version 1.0. If you spend some time exploring the magnificent ecosystem that the Purescript developers have created you will realize the immense work done but the eternal 0.x. releases can give the impression that Purescript is almost abandoned when all of us who pass by know that it is not.

2 Likes

Sum types are standard in FP languages these days. I was surprised to see that even Typescript has an interesting and flexible implementation of them - https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions. If you have a union A | B | C then they allow, for example, to narrow on a field that’s present only on A and B, or A and C etc.

1 Like

Chiming in here in hopes that it’s helpful!

tl;dr error messages, speed, tooling

I’ve done a fair bit of demos showing folks klank.dev & helping them use it, and there are three bits of feedback I get pretty regularly that are intertwined:

  1. The error messages often don’t provide an answer to “how can I go about fixing this?”. This is especially the case for newcomers & people without FP experience.
  2. The compilation time is too long - a 2000-line tsx file compiles much faster than a 1000-line purs file, which makes editing in VSCode/vim take a while when files get large.
  3. There’s a lack of autocompletion & hotkeys.

I think all 3 of these are useful, and I also think all 3 of these come from what people have gotten used to when working with JS/TS, Python, and to a certain extent Kotlin/Swift.

One of my colleagues asked “why would I use purescript when stuff like eslint exists” and it took me by surprise as a question because I had never compared typing to a linter. But they have a lot of overlap from a workflow perspective, and linters like eslint have gotten so good that they rival strongly typed functional languages for certain domains/programs.

9 Likes

One way to allow that without committing to a specific backend is by letting users create compiler plugins like GHC - https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/extending_ghc.html#compiler-plugins. I would love to see that in Purescript!

1 Like

What PS needs is not to be like Elm and ReasonML. After investing a lot of time learning these two languages and the libraries around them, I left them because of the unrealistic desire by some of those who steered the communities to drive more adoption from the JS community.

First it was Elm with its toxic 0.19 update and recently the rebranding of ReasonML. In both cases, features were removed or in the process of being removed to lower the barrier. The JS community will never be pleased and no FP language could ever be as successful as TS (I don’t think popularity is a good measure of success anyway.)

PS, on the other hand, has one of the best quality libraries, very open community, stable roadmap, and a good balance of features (although I miss GADTs from Ocaml lol.)

But I agree with @hdgarrood and @mikesol about error messages.

Finally, I think @ntwilson was spot on. Let’s attract developers from Elm/ReScript/ClosureScript who are thirsty for all the nice things PS offers.

12 Likes

I tend to agree with @Mediterraneancoast. It has never been a design goal of PureScript to be a better JavaScript. It is nice that it compiles to straightforward JavaScript, but I don’t think it will ever be a goal of PureScript to specifically add language features for working in or transparently with JavaScript .That’s not to say that there aren’t general language solutions for tackling problems like that. I just really don’t think it will ever be a core goal to be able to type any JavaScript API as-is. For me personally, It’s just not really something I’ve wanted to do. Most JavaScript APIs suck, and even if I am writing bindings, I’d much rather write that so that they are nice for PureScript. I want more stuff written in PureScript, not just more bindings to existing JavaScript.

18 Likes

I posit that PureScript will be significantly more popular if it had first-class React and GraphQL support. Over the last few years, I was the tech stack decision-maker and wanted to use PureScript, but couldn’t. Building complex web apps without GraphQL is a disservice to the business since it significantly slows down both backend and frontend development.

The React story in PureScript has gotten better, but it’s still missing pieces. On the other hand, it’s impossible to use client-side GraphQL or Relay with PureScript for production apps. On a recent project, I evaluated how hard it would be to write a relay compiler plugin to emit PureScript, but I couldn’t get far. The Relay team is rewriting their compiler, so I’ll try again with the new architecture once it’s ready.

I understand the technical benefits of Halogen over React. But I think building ambitious apps in React is significantly better. React concurrent mode solves real UI and UX problems. A lot of apps require code splitting and server-side rendering. I can easily use all that with React. I’m also excited about React Server Components. The React community produces some fantastic high-quality react components that would take engineering teams months to replicate. The Elm community has at least reproduced a minimal viable stack for building web apps. That’s why Haskellers often reach for Elm instead of PureScript despite all the shortcomings of Elm.

Sorry if this reads like a rant. I know many tech leaders who went through the same evaluation that I did and couldn’t pick PureScript despite their love of Haskell and FP.

6 Likes

My 2 cents.

I do feel we need to make a distinction between PureScript the Language and PureScript the (web development) Ecosystem. When I hear things like "it’s impossible to use client-side GraphQL", that isn’t really something that should be addressed in PureScript the Language. What is missing here is the fact that developing web solutions in PureScript is “more difficult” than in JavaScript because this or that particular library is missing.

In my opinion PureScript the Language should be improved as a language, things like better error messages. But doesn’t need drastic changes in order to compete with the JavaScript the EcoSystem. In needs to stay general purpose, with a possibility to support multiple backends in many different domains. Because I believe that is the strength of PureScript.

In order to compete with JavaScript it is required to improve PureScript the Ecosystem, cause that is where JavaScript’s strength lies, not in its language. Stuff like libraries, frameworks, tooling, documentations and examples, with a focus on building web related applications (browser and node).

Unfortunately this will be an uphill battle, unless there is some “killer app”. JavaScript has an enormous head-start here, it had the monopoly of web development (in the browser) for 2 decades. That is why TypeScript is so widely adopted, it can use the gigantic ecosystem of JavaScript straight out of the box (just use any).

15 Likes