For what it’s worth, the lack of Typeclasses is why I gave up on Elm. For an otherwise fairly usable language, it was just too inconvenient.
Purescript is very promising. Unfortunately, I think the learning curve may be too high for many people. Elm has a simple and straightforward UI system that you’re basically required to use, whereas purescript gives you some options, and the one I found first (Halogen) uses concepts that are well beyond the experience of your average programmer. Elm’s nested tree system is relatively very approachable.
Do you have some example code of where you found it too difficult to go without typeclasses? In the majority of cases I come across, it is usually solvable in a different style than the person is used to. A lot of people come from languages like Haskell, and expect Elm to have all the features Haskell does – and therefore end up trying to solve problems in a Haskell manner, which can be very frustrating once you realize that Elm doesn’t have typeclasses. I’d be very interested in seeing what you came up against :)
it is usually solvable in a different style than the person is used to.
All of these languages are Turing Complete. It’s always doable, but not always convenient.
The most prominent example I remember is wanting sets and maps with keys of arbitrary types.
I actually discuss that exact problem in the blog post, including linking to the solution, a package called elm-all-dict which I wrote a long, long time ago and still maintain.
It’s pretty convenient - just use EveryDict anywhere where you might’ve put a normal Dict. There’s a small hit to performance, but nothing you would notice unless you’re processing info from Hubble or something.
So you’re basically emulating typeclasses by explicitly passing the relevant functions. Like I said, that works, but completely eliminates any of the convenience or safety afforded by unique global typeclasses. It also doesn’t really generalize well to things more complicated than, say, Ord or Hashable. Soon you have to start passing around giant objects full of lots of functions, and now you’re just doing typeclasses by hand.
Actually, EveryDict doesn’t require you to pass in relevant functions. AllDict does, but EveryDict hashes things for you. So no, not quite.
But also: the point is that typeclasses, for most things, are a nice-to-have. If you write your code in a different manner, then it’s not a need-to-have. Very few people have these problems in production - I’m among the people who have written the most Elm and have rarely thought “oh typeclasses would help me write this view in a better way”. Other things are more important to increasing Elm adoption and ease of use over typeclasses.
So I’m not trying to say that typeclasses don’t have a place - they definitely do, and they should be added in. But they need a lot of thinking about first, and there are other things to address first. Hence why the yet
I wonder if they are going to try to do some kind of ML module thing.
I personally find ML-style modules to be a stricter, but stronger abstraction for libraries than typeclasses.
Also, I don’t quite understand the final point in the post: needing to look up viewSomething to understand viewCity etc. Isn’t the whole point of writing modular code that you don’t have to really care about what the implementation details are? If you need to understand the implementation entirely (as you might for a rendering function), having typeclasses vs modules vs some other abstraction mechanism becomes mostly irrelevant.
Yeah, maybe I didn’t explain that last bit so well. I think my point was that you can already write things in a type-class style (by ensuring each record has a contract of record -> Html msg), but that that style does not give you much extra in terms of readability nor in boilerplate. Boilerplate is the problem that most people are facing with Elm right now - and the introducing of typeclasses may be either harmful or overkill for that problem
record -> Html msg
It’s been discussed, and actually effect-modules have a syntax inspired by OCaml’s parameterised modules.