Front-end frameworks: Flame, Concur, Halogen or something else?

Hi

Coming from React + TypeScript land and getting increasingly interested in functional programming I started looking into fp-ts, ReScript, Elm and now PureScript as a possible replacement for TS.

Since I’m only in the initial research phase to evaluate if this language is feasible for me to switch to, I’m trying to figure out whether the way to go would be Flame, Halogen or Concur - or maybe some other front-end framework I’ve entirely missed?

I’ve seen Halogen getting compared with OOP, and my whole reasoning for switching to PS is of course to keep it as “pure” functional as pragmaticly feasible, while still being productive to be able to use it professionally.

Next there is Concur, which also seems to have some downsides regarding type safety and subscribing to events and more. It doesn’t seem like it’s production ready just yet, at least that’s the impression I got.

Finally I noticed some of the critics of Halogen mentioning Flame as their choice of front-end framework. Definitely looks interesting however it’s more or less also just 1 guy maintaining it, so he really has to be onto something…!

So I’m just curious what is the most popular way to make large, scalable and complex single-page applications in PureScript?

4 Likes

It would be helpful to know why you want a replacement for TS and what your thoughts are on the other things you mentioned. Based on that, I think it would be easier to offer targeted advice.

I’ve seen Halogen getting compared with OOP, and my whole reasoning for switching to PS is of course to keep it as “pure” functional as pragmaticly feasible, while still being productive to be able to use it professionally.

As someone who has written PureScript full-time professionally for the past 6 years, and contributed aggressively to the ecosystem, this is complete nonsense, and anyone trying to tell you something is arbitrarily “more functional” than something else is totally full of it. The idea that the Elm architecture (which is rebranded MVC) is “more functional” than something like Halogen (which is rebranded MVC) is a hilariously bad take. Don’t trust anyone who says this. Mini-rant aside, Halogen is totally fine, and can get you very far. As far as I know, it’s still the only 100% PS UI library used by companies to make money. Otherwise the vast majority of people using PureScript professionally are using React bindings of some kind (such as react-basic/react-basic-hooks). At Arista NDR we still happily use the ancient purescript-react bindings (albeit with our own hooks bindings).

5 Likes

Hi,

using Halogen here (well probably not in the large, scalable and complex range sorry).
Don’t know why it’s labeled OOP and to be honest: This is the first time I heard that opinion.

I can somewhat see why someone would label it that way (if you understand OO as passing messages - so not in the “modern” sense) as you have components where parents and children can pass messages (instead of sharing state) by default (which is done in a type-save manner which is the both the great and complex part about Halogen I guess).

Having said that: I’d encourage you to try out some frameworks to get a feel - right now I’d recommend the react-bindings (as you know react already) and Halogen (as you seem to know Elm) - Flame if you like (it’s more “elmish” than Halogen I guess).
Concur is something a bit different and might need more time to get going but why not have a look?

2 Likes

Halogen.

Unless you want to incrementally migrate from TypeScript-React, in which case purescript-react-basic-hooks - Pursuit

2 Likes

I’ve heard it quite a few times, and, I mean, it’s not wrong. As someone who has contributed heavily to Halogen in the past, I would argue that it’s as close to “pure OOP” in a typed setting as you can get (and I don’t think that’s a bad thing). But if that’s the case, then Erlang is not a functional language, and if you’re writing Erlang, you aren’t doing functional programming. It’s like someone arguing that let bindings are “imperative”, and if you want to do “real functional programming” you should write everything point-free. It’s just unfortunate gatekeeping, and has no interesting pragmatic implications at all. This goes doubly-so if said person is advocating for a TEA framework.

There are many reasons to criticize Halogen or TEA, and none of the interesting or useful criticisms fall into “more functional” or not.

2 Likes

@natefaubion i really appreciate your feedback. However, I fail to understand one thing. My reason for wanting to explore PureScript is that I was generally not satisfied with the “impurity” allowed by certain other languages e.g. ReScript. When people mention pragmatic, imperative, OOP it starts itching… If i was to start writing in a more verbose language such as PureScript my whole motivation would be to write as purely functional as at all reasonable, if we also give just a little bit of weight to productivity and performance of course. However code quality for me is largely adhering to the functional principles as much as possible… Many other things plays in as well of course. I know code quality can start a huge discussion and is very subjective, but at least to me I’d not expect to hear pragmatism from PureScript developers… I thought purity would be more important for this language because there’s so many mixed, messy and pragmatic languages out there.

1 Like

Purity is orthogonal to OOP vs functional. To be clear, we should breakdown why Halogen gets the OOP criticism.

  • Halogen has a concept of a “component” which is defined as a record with some fields (render, initialState, eval).
  • Halogen component state is existential (encapsulated and invisible to the outside world).
  • Halogen components can be embedded in a parent component and that parent can send messages to the child, and a component can bubble messages to the parent.

That’s it. Notably, this has nothing to do with: purity, unconstrained effects, mutation, referential identity, inheritance, subtyping, etc. Components are a unit of encapsulation/abstraction, and a way to get data into and out of it.

If you look at a typical TEA framework in PureScript, what do you usually have at the root?

  • The concept of an application, which is defined as a record with some fields (render, initialState, update)
  • The application state is usually not existential because there is only one.
  • Mounting the application usually gives you a way to feed messages to your application.

At a high-level, the only difference here is that TEA does not provide a unit of encapsulation/abstraction. You build UIs by writing glue code between a conceptual parent and child if that’s your thing, and that’s totally fine as it’s a different tradeoff. It may totally be to your taste to eschew some attempt to provide that for you, and stitch your application together yourself (simpler types usually). You could write a Halogen application using only a single root component, and you basically just have TEA.

However, at no point in this overview did the question of “functional” come up. If your primary concern about “functional” is purity than you can use either! Halogen is just as pure as TEA. You can write a component in Halogen and enforce that it has no effects at all (other than ambient component effects). You can also abstract over your effects and ensure that it only uses effect interfaces, restricting effects locally.

When I say “pure OOP”, that’s really what I mean: there is none of the usual baggage that comes along with OOP languages and design specifically because it’s embedded in a purely functional language. Both Halogen and TEA are just MVC, with largely equivalent expressivity. So in my mind, using OOP as a criticism here just doesn’t hold water. Note, I’m not really here to convince you to use Halogen or anything (I don’t personally use Halogen professionally). Just that there are other much more interesting considerations to explore when picking something like Halogen or Flame (for example) for professional use, and I wouldn’t worry about the functional moniker.

Hope that helps!

5 Likes

Since you say you’re not using Halogen professionally, what are you / would you be using and why? You seem very experienced so it would really be interesting to hear your opinion on Flame and the other front-end frameworks for building large Single-Page Applications.

It sure does. Thanks!

We have a large PureScript+React codebase at Arista NDR. For us in particular, there was already a very significant React application (written in plain JS), and interop was a hard requirement. Decision made! Over the past few years all new development has been in PS while the old JS portions of the application were left largely as-is or replaced when needed.

So I don’t think there’s a one-size-fits-all here and I can’t really make a recommendation for a specific library. You have to consider:

  • How much knowledge do I have as a PureScript user? Do I know how to fix things if I run into blockers?
  • How effectively can I onboard other developers to my project?
  • Is leadership (or a client) willing to invest in a potentially niche UI framework?

Using PureScript in a professional setting will likely require some compromise to avoid blowing the novelty budget. As a niche language, PureScript itself occupies a large part of that budget. In some cases, adding a whole new UI library or paradigm to the mix may be too much, and that’s OK.

6 Likes

If you are new to FP, then I’d recommend Elm as a starting point for experiments. Because it has a “standard” way to start, least amount of decisions to make, very simple language with least concepts that you’ll have temptation to learn. Then if you are comfortable with that style, but feel some lack of abstractions to be more productive you’ll easily continue in PureScript and will be able to make reasonable choice of framework.

1 Like

Thanks @stiff , but I already ruled out Elm for a number of reasons. I don’t like the fact that Elm was made so specifically for the frontend. I don’t like how it dictates that you build apps using the Elm architecture. Imo a language should not be that opinionated an locked on implementation details to that extent, but be more flexible. Also i don’t see a bright future ahead for Elm as the author had been focussing on his next language for more than 3 years now. There are many more reasons why i don’t find it interesting compared to PureScript. Interoperability with js packages is one more thing, and the PureScript core team and community gives me a reason to believe PureScript will be around much longer than Elm.

I’ve already decided I want to learn PureScript. For long I’ve disliked how most languages are mixed languages supporting both OOP and FP and imperative and declarative ways of writing code. PureScript seems to be for people who are interested in writing better code while still allowing you to be productive. At least that’s the impression i get after my first week with PureScript.

6 Likes

If you already made up your mind then surely go with PS, it’s a very nice and flexible language. Compared to Elm, JS interop is indeed way less strict and limited. Initially I just thought you were looking for something for quick and easy start to get some hand on experience, but now your point is clear.

1 Like

I don’t really maintain this anymore (it probably still compiles fine), but if you want a reference for a TEA setup that can be read over in a weekend, you can also check out GitHub - natefaubion/purescript-spork: Elm-like for PureScript which I created to feel like an idiomatic PureScript TEA variant. It’s all in PureScript and shows how you can implement the nitty-gritty details without dropping into FFI.

2 Likes

Are there any comparisons on efficiency in change detection, redraws, etc. between React and Halogen? Let’s say you were to effectively go with the "Let’s do TEA in Halogen/purescript-react-basic-hooks (+ useReducer), would one hold an advantage over the other in terms of VDOM efficiency, smaller redraws based on localized state differences leading to redraws of a sub-tree in the HTML, or anything like that?

1 Like

So it’s just as a reference? Looks super clean and simple, but tbh I’m not specifically looking for what’s easy, but the frontend framework the most experienced PureScript devs are using or recommending for new projects that potentially can get big and complex. So it’s more what’s powerful and promotes best practices (and well maintained ofc).

Why did you stop maintaining it, if I may ask? Is it just to serve as an example on how you can mimic Elm to build a minimal framework on top of PureScript?

And just to be sure, by TEA framework you basically just refer to being productive (productivity framework), right?

1 Like

I think TEA is used here as the elm architecture - it’s the app-architecture style often called Model View Update as well - where you have some kind of Model (that holds the apps state), a View to display a model (usually as HTML in the browser) and a Update that (well) updates the model due to some actions/events/messages that happened.

The framework part usually handles the details (storing the model, updating it via Update, displaying it, details concerning sideeffects etc.) - most frameworks are more or less in this style (including at least the old style of React/Redux).

I think Elm made this “pattern”/“architecture” popular for functional-oriented communities so we stick with TEA or in some cases “elmish” :wink: - Most “mainstream” developers seem to call it MVU though.

3 Likes

Hey sorenh, welcome. I hope you find PureScript fun and as rewarding as I have!

I’m on a team that uses Concur in a production project and we have recently started using Halogen for another project, both commercial boring line-of-business apps (but quite interactive!)

I initially shied away from using Halogen, mostly because the type signatures involved in making a Halogen app felt complex and confusing. But I think Halogen had a refactor to make some things simpler (especially components) a year or two ago, and it’s a lot better, plus I got over my fear and just used it.

I have to say it’s been very pleasant, even in an application with a few sub components. I also learned It’s not necessary to understand Halogen’s entire type stack to use it, so maybe the types haven’t become simpler but my attitude has improved.

So I would say, unless you have a good reason to use something else: Halogen is the most used, best supported UI library for PureScript (IMO).

As for Concur, it does have a bit of a not-production-ready vibe to it. However, we are using it in production as we have a use-case that Concur works particularly well for, and it’s fine!

How that not-production-ready vibe manifests: you’ll find corner cases that no-one has thought of, for example there’s no obvious way to have widgets communicate across the app with each other, unless they return values all the way up the callstack and sync at a higher level, which is often not desirable.

But with every library someone had to be the first to figure out those corner cases, maybe that someone will be you? :smiley:

3 Likes

I thought the Wire API was made explicitly for what you mention above. Did you try it? Example from the Concur React repo below:

2 Likes

Nice, I’ll give that a try, thanks! I see in our codebase we’re not using that anywhere so it’s likely we just missed it.

As someone who has worked on a Halogen app sporadically for the past few years, I can recommend it. It’s fully featured and can do pretty much anything you need. One thing I don’t like about it though is that defining components feels ceremonious, which is why I highly recommend Halogen Hooks. It’s still Halogen, but nicer.