Hey folks, I hope it’s OK to post this here. I made an Elm-to-Bucklescript compiler to help us move from Elm. I hope it’ll be helpful to help people take a risk on Elm. Would love any feedback that people have!
What was your reason for moving away from elm?
Did you do anything special to handle anonymous records? For example in https://package.elm-lang.org/packages/ianmackenzie/elm-geometry/latest/Arc2d#with, an anonymous record is used to emulate named arguments, but there’s no corresponding
type alias that could be used to determine a name for an OCaml record type (as far as I understand, OCaml requires record types to have names).
I’m not personally looking to move away from Elm, but that’s one of the problems I’ve encountered when I’ve looked at (for example) making a version of
elm-geometry for Haskell or OCaml to use on the backend, so I was curious how you’d addressed it.
We felt we needed the ability to call Native code, and that went away in Elm 0.19. We initially tried moving to Elm 0.19, found it exceptionally hard, and felt that moving to Bucklescript was more certain than rearchitecting our whole app. It didn’t hurt that our backend was in OCaml.
What kind of problems did you encounter that ruled out using ports?
I don’t think we do. philip2 at the moment I would describe as semi-automated - you may have to make some changes to your Elm source for it to transition nicely, such as removing anonymous records. We’d definitely accept PR on this.
Nothing ruled out using ports, I’m sure we could have made it work. But we had a bunch of different areas where native code made exploration simple, and Elm’s structured approach made it difficult to get a first working version. I had put them in the Elm slack but they got lost cause there’s no archive, but from memory we use native code to:
- cache generated HTML
- introspect the DOM to see what is “next to” the user
- introspect the DOM to see the width of some text
- create random integers (without passing the random state throughout the whole app)
- (there’s at least 2 more, I’ll add them here if I remember)
We’re in a really early stage of our app where it’s really important to us to quickly try things and see if they work in the product, and Elm got in our way by making us do it “the proper way”. Doing it the proper way is great long term, but it can be a real drag on experiments.
Sorry if this is a bit off-topic, but are you writing servers with OCaml? if so, is it nice?
It’s nice but not as nice as elm: syntax isn’t as good, libraries are less well done, docs aren’t as good. The language has some cruft that certainly could benefit from the axe. The main trouble for us has been the lack of a good concurrency story.
Looks this was more a case of not knowing Elm yet? Ports are extremely easy to use. And most of the stuff I’ve seen other libraries doing. I’m an Elm beginner as well, but have found helping people out on Elm libraries very helpful to learn Elm better.
I don’t think it would be possible to write a tool to convert from one language to another without understanding both.
mod note: I see a couple threads of discussion here! Let’s stay on topic. If you have a question you want to ask the OP about Philip2, this is the place. If you have something else to say or want to ask the OP an unrelated question, new threads are great.
I saw @Paul_Biggar 's reply about anonymous records but just wanted to add that OCaml does support structural object types which can map pretty cleanly to Elm anonymous records. E.g. the function you linked to could theoretically be translated as:
val with : < centerPoint : point2d; radius : float; startAngle : float; sweptAngle : float; .. > as 'a -> arc2d
The angle brackets are the object type delimiters and the
.. means ‘possibly other fields’. The
'a means 'since there are possibly other fields and we don’t know the exact type, treat the overall type as a generic type
I encountered the same issues, after elm 0.19 came out and we spend several days trying to “fix” our code base, we simply rewrote it with react-redux.
Although it helps your backend is already written in OCaml, ever though about using PureScript? It has very powerful type features (higher kinded types, constraints, type level programming), the ability to use foreign (aka native) code, a Haskell like syntax (like Elm), and a very consistent set of libraries (opposed to the OCaml StdLib / Jane Street Core / BuckleScript Belt discussions).
Fascinating! I also read your manifesto on “darklang”.
We have yet to move to Elm 0.19, mostly because 0.18 rocks so much and hey, if it ain’t broke.
We had a dev spend some time in Bucklescript. Impressed at first, but then not so much and moved back to Elm.
I have admit that I would 100% agree with your manifesto, until I stumbled across the magical trifecta of Elm/Elixir/Nanobox. The combination of the three are incredible, and would for sure build anything on top of that platform in the future.
Best of luck with darklang!