Hacker News new | past | comments | ask | show | jobs | submit login
Elm and Phoenix/Elixir in Production for France TV (jousse.org)
291 points by tbassetto on Oct 16, 2016 | hide | past | favorite | 76 comments

Elixir and Phoenix are stable and by now they're a solid choice (more than enough warranted praise on HN), but I'm still skeptical about Elm from a "platform" perspective. From what I can tell, Elm apps are a single blob of JavaScript that either loads or doesn't (e.g. you can't read the Elm site without JavaScript enabled), while the JavaScript ecosystem is moving towards server-rendering, dead code elimination, and "progressive web apps" so to speak. PureScript for example has dead code elimination—you can make a <1kb PureScript "Hello World" app.

I know the Elm team is capable of all of these—I just haven't heard of anything yet. While they're "nice to have" now, these features might become crucial and important.

Another interesting thing about Elm is its progressive removal of features (I think the infix operator was or is going to be removed soon) in order to make the language more approachable. I actually support this because if you need "true" ML/Haskell features, there's PureScript.

Anyway, glad to see Elixir and Elm being used productively!

You can do progressive web apps quite easily. Your Elm code is included as always with <link..> and you pass the id of any container to initialize it.

The container can be <body>, but you can just as well attach to some <div> in the footer and the rest is rendered independent of Elm.

Regarding dead code elimination: yeah, elm doesn't do it yet. But the code generated by elm-make is very predictable and therefore easy to process. I just tried uglifyjs:

raw elm-make output; 196kb

uglifyjs -m -c: 68kb

tar czf: 20k

The inventor of elm is very deliberate in the project's development. I believe his argument is that including dead code elimination now is premature, because it adds a lot of maintenance work, especially at a time where the language is still evolving. Once the raw js is no longer a moving target it shouldn't be too difficult, and until then uglify and similar do a good job.

Right, I get the last part. Just saying I wish I could have it now with little to no configuration :-) Not blaming Elm, it's still quite young and evolving.

> Elm apps are a single blob of JavaScript that either loads or doesn't

This is what bothers me about Elm. In the next few months, I'll be starting on a site project, and I've been fiddling with Elm and I don't see how I can create progressive web apps with it. It doesn't seem to play well with service workers for an offline mode, and there's no fallback if Javascript is disabled. Either it loads or it doesn't.

I want to use Elm, I don't want to use JavaScript, but I also want a progressive web app that will offer some functionality offline. I guess there's a way to do some server-side stuff with Phoenix, but then the front-end / back-end division isn't so clear and I'd end up using JavaScript for the service workers anyway.

I've not looked super deep into this, so I'd be happy to be corrected if I've got the wrong end of the stick here.

Its true that you can't currently write a service worker in Elm. However, in practice for any decent size app you are going to end up with a mix of Elm and Javascript with communication happening through ports. Therefore you can write the service worker in JS and then talk to it from Elm.

Of course it would be nicer to be able to write everything in Elm, but I find having the majority of your app in Elm with a bit of JS is significantly nicer than having the whole app in JS.

You can make it nicer still by using Typescript instead of Javascript, and defining interfaces for the data going through the ports, giving you type safety across the whole stack.

I'm using this approach right now in a mobile Elm/Typescript app with great success.

I'm a huge TypeScript fan.

Yet I worry about adding Elm to new projects, mostly because it raises the level of developer I need to hire to maintain it. I'm not in SV or in a tech hotspot at all, so maybe I have to think about this more than the average HN reader.

I just helped a relatively junior developer—sharp but with no real functional programming experience—get started with Elm for a small internal tool. He got something up and running almost entirely. I think I spent around ~1.5 hours helping him get things set up and understand the basics.

Personally, I'm actually not the biggest fan of the design philosophy behind Elm, but I do have to admit it's easy to learn with some great introductory learning materials. Getting somebody motivated up to speed on maintaining Elm is not an issue.

For what it's worth, I think the same is true of Haskell-style languages in general: with a bit of guidance, it's not hard to make new programmers productive. That's the experience IMVU[1] had when switching several internal projects to Haskell from PHP, if you want a case study. I met the lead engineer who wrote that post once and he explained that it actually took about as long to train an incoming developer (with no FP experience) in Haskell as it did to train incoming PHP developers on IMVU's in-house PHP "flavor" (frameworks, code organization... etc).

Picking up Haskell or Elm is a bit difficult by yourself for a few reasons: there's no clear path on what to learn, the learning materials are a bit hit-or-miss and there's a lot of incidental complexity. However, if you provide a bit of guidance (ie curate libraries) and help overcome some of the incidental complexity (ie install the compiler and tools) it's surprisingly accessible.

[1]: https://engineering.imvu.com/2014/03/24/what-its-like-to-use... (see "Training" section especially)

If you don't mind using remote developers, then your location doesn't have to matter. It's true that it might be a bit harder to find a developer (although Elm is getting more popular day by day), but the other side of the coin is that your application is likely to have less bugs and need less maintenance. My experience is that Elm takes a bit longer to write than JS/TS, but once written it tends to work correctly the first time.

You can solve this nicely with Polymer. When elements load they are just new HTML tags and they get "upgraded". Polymer gets way less love on HN than it deserves in my opinion.

At the very least, Elm code should be compatible with Google's Closure compiler (just like Clojurescript). There is no reason the Elm folks should try to re-invent the wheel on this, just harness the power of the Closure utilities by making your emitted JS standardized and compliant. Then you get all sorts of things for free, like dead code elimination, just for starters. The Clojure team realized this from the start and it has done a lot for the cljs ecosystem.

The way Elm outputs JS today, it doesn't really have much to gain from being Closure compliant. Even uglify manages to remove most dead code from an Elm "blob", because Elm outputs javascript with a single scope. An Elm app is smaller than both a Cljs+React(om, reagent) and a JS+React app.

Dead code elimination is only part of the benefits of Closure. The advanced compilation mode does a lot to optimize the final JS.

I haven't had much luck the the advanced setting for Elm - seems to optimise too much away, and I get undefined field errors when I try to run the code.

That's because Elm does not output JavaScript in the standardized format for Closure.

Closure doesn't really have a standardized format. It does, however, not like that you mix string and dot access for object (obj['str'] vs obj.str), which Elm does a couple of places.

I disagree. Google Closure is antiquated and complicated to configure and adds a lot of unpleasant baggage to cljs.

I love Clojurescript as a language, but using it alongside existing js libraries is awkward and error-prone, and getting the build process to work smoothly takes way more time than it should. Cljs gets a lot right too, but it shouldn't be held up as an example in this regard.

Do you know about cljs-js ? https://github.com/cljsjs/packages

Nope, I hadn't seen that. Definitely helps!

Closure's advanced compilation mode really optimizes the final JS, no?

Elm compiler knows more about the code than Closure compiler. It can safely remove more and do a bunch of other optimizations facilitated by the types.

There was a DCE branch at one point but it never got finished.

Elm is working on server side rendering and it will come once it's ready.

When it comes to dead code elimination, it is true that the compiler currently does not have that. Luckily, the compiled js is just a series of functions (namespaces is a part of the function name, like namespace$functionname) and so a tool like uglify has no problem removing dead code. A minified Elm app is smaller than a minified React app.

Server side rendering doesn't remove the need for loading js on the client.

The idea is to render as much of the app (usually the "shell" or the static content) through the server and then the client-side JavaScript takes over. As of right now support ranges from excellent (Ember FastBoot, out of the box), okay (React with some configuration), and nonexistent (Elm).

A rare few people are using Elm server-side in production already with lukewestby's worker stuff. Check the Elm subreddit. Elm's JS interop is much more interesting than your understanding of it: it's a pub-sub system which allows you to embed small Elm components in otherwise "normal" web pages very easily. More info here:


I'm sorry to be so negative but I really hope your comment doesn't remain the top comment as it's not very well-informed at all.

>while the JavaScript ecosystem is moving towards server-rendering, [...] and "progressive web apps" so to speak.

Hardly. Server rendering remains at best a novelty, and "progressive web apps" are not coming back anytime soon.

Nice writeup. Elixir definitely seems like a solid language for web dev. For the frontend, I prefer Scala.js since I'm kind of a Scala fanboy, but I've heard great things about Elm.

One little comment. At the beginning of the post, you make it seem like the app needs to scale with the number of viewers, when in fact it doesn't. I think you should clarify this to avoid confusion.

We are doing a fairly large Elm app right now. And especially the refactoring reasons and static type system are appealing to us when you work in a team.

Also being a functional language it is easy to crank out features in an afterthought, e.g. we added an Undo/Redo feature for operations the user does in this single-page client app. And being side-effect free this "merely" boils down in wrapping function calls in an "undo/redo" function.

So Elm is really exciting stuff. But still the Api is not completely stable, yet. So you have to invest some time to adapt to these (small) Api changes. Also interoperablility with so-called "Native" JavaScript browser functions, e.g. JavaScript typed arrays is possible but not finalized, yet.

Are you using ports much? The examples in the documentation aren't very clear, and I'd be interested to know how much plumbing is required to talk to external Javascript in real life.

It's not much.

On the Javascript side, the Elm `app` is like an event emitter where you listen for updates and send it data.

    var app = Elm.Main.embed(...)
    app.ports.gameState.subscribe((data) => ...)
    app.ports.tileClick.send([x, y])
On the Elm side, you subscribe to incoming ports and map them into Msgs. And you emit to ports with Cmds from your update function.

    -- Ports.elm
    port gameState : Json.Encode.Value -> Cmd msg  // Outgoing
    port tileClicked : ((Int, Int) -> msg) -> Sub msg  // Incoming

    -- Main.elm
    update msg model =
      case msg of
        Tick ->
          -- Define `encode` to Json.Encode the game state
          (model, Ports.gameState (GameState.encode data))
        TileClicked (x, y) ->
          -- Handle tile clicks sent in from Javascript
    subscriptions model =
      Ports.tileClicked TileClicked

Yes, but just like the ones in the docs, that's a nearly trivial example, and so doesn't demonstrate the complexity.

What I'm concerned about is the case when I want to call a Javascript function from deep down inside, say, a computation function. Do I have to split my computation into two halves, one which sends the event which calls the Javascript function, and another which receives the result of the function? How do I pass the in-progress computation state from one to the other? Normally in a functional language I'd get around this by simply passing a function reference into the Javascript function which the handler would then call, so allowing me to have both parts of the computation in the same place and operating on the same data, but apparently in Elm function references don't survive being passed through Javascript.

Plus, each port only has a single incoming event, so if I'm calling the Javascript function from multiple places I can imagine it can very easily turn into a labyrinth of state passing code.

How do you avoid this?

Some interactions with 3rd party libraries (like rendering stuff, leaflet.js, pixi.js) fall along natural event-driven faults, like the game update tick finishing, something managed by Elm being clicked, that sort of thing. In these cases, ports (events) are the obvious fit.

Then there's synchronous 3rd party library stuff where you just want to execute a Javascript function, like a math function that you aren't going to reimplement in Elm. In that case, I wrap the function with a native module and call it like an Elm function. Since you talk of computation, is this what you're talking about?

The Elm community highly discourages native modules. For one thing, they aren't very well documented and the API seems to have recently changed. But I'm not sure what the alternative is.

Ah, right --- I have heard of native modules, but only in the context of things I shouldn't using. I'll look more closely. Ta!

From what I can tell, basically all of the reasons you state for using Elm are also present in Scala.js.

Elm has a sound type system, no compromise and is purely expression based. Scala, not quite. You can still have runtime exceptions in "normal" situations, you can still have statements that aren't expressions, etc.

Scala gives you the options to do it right, but Elm enforces it. Heck, because of how the application type works, its pretty much impossible to make an Elm app that doesn't follow proper architecture. It just won't compile.

Definitely, but I see that flexibility as a good thing. I can either depend completely on the type system at compile time, or I can move some things to runtime, depending on what I'm writing and how much time I have to complete it. The boiler plate introduced by immutability and pureness can become unwieldy in large projects from what I've read.

Another cool thing is the option to use either a pure expression-based functional approach or a OOP approach, or even a mix between the two.

Yup, I know :) it's a matter of opinion. I was just saying that that's a significant difference that will make a segment of engineers pick something like Elm. Elm is also more minimalist and easier to pick up if you're not into FP. Even knowing Haskell, some Scala types make me go cross eyed.

On my side, if i have the choice between boilerplate or having to debug runtime errors, I'll pick the boilerplate any day. If my product manager thinks its worth it to push a feature earlier (and risking having it blow up), well, I'll go work for someone else ;)

> Also being a functional language it is easy to crank out features in an afterthought.

I am a big fan of functional languages, but I don't take for granted that they allow us to crank out any additional feature easily. The ease of adding of undo/redo functionality is a common selling point, but it seems to fall out directly from a preference for immutable data.

> We are doing a fairly large Elm app right now. And especially the refactoring reasons and static type system are appealing to us when you work in a team.

Do you miss this in the backend with Elixir?

The backend is not done in Elixir, but Go.

I would love to do it in Elixir with Phoenix, but this would mean the team has to learn another tool. Go is really easy and fast to pick up. Here the Go Toolchain/Ecosystem matters, which is easy to grasp, and you get a type system, which is not as sophisticated as in Elm, but fits the job.

An older project was done with Grails/Groovy. This was fun and fast to iterate. But after a while, when you come back to the old project code, it is hard to get the dynamic types into your head. So actually I would prefer a static type system. I know there is some tool for Elixir to handle this. But I did not look into this.

Elixir is a fantastic platform for apps, and using Phoenix for the web interface makes things super easy.

I love it.

> As a business owner/recruiter, I wanted something with a low entry barrier for my future hirings. Elm has a low entry barrier, the JS ecosystem/fatigue/mess doesn't.

This is nonsense. There's a much greater pool of talent familiar with javascript than Elm.

Using Elm might be marketable ("come work with Elm here!"), but it's a riskier bet for a developer given it's relative immaturity and adoption.

At this point the "come work with Elm" only works at places that have long-term Elm experts and fans (e.g. No Red Ink which hired its creator, has their lead evangelist, and probably more than half the top Elm people in the world).

Have not had time to try Elm yet but Elixir is such a pleasure to use, it's painful going back to JS :)

It really is. We're rebuilding our entire backend in Elixir and it's just been incredible every step of the way. I can't recommend it enough.

The language and ecosystem are an amalgamation of industry lessons from the past three decades on what it takes to build robust networked applications. It's the most painless programming experience I've had.

These days other languages feel like museum pieces when I have to jump back into them.

Not to mention being able to run dozens of services, background jobs, and API in a single box as one "umbrella application"!

Good to see industry uptake is picking up. Gives me hope that one day I can have a job programming in Elixir :)

Haha, what's more: through a series of coincidences I found out that the guy who built our competitor's product also did so with Elixir!

(Well... not quite competitor. A similar product to ours, but which deals with the management of electricity.)

So yeah, there's quite a few startup using Elixir already :) and a handful established companies as well. -- Pinterest, for example: http://venturebeat.com/2015/12/18/pinterest-elixir/ :

> The notification system runs across 15 servers, whereas the old system, written in Java, ran on 30. The new code is about one-tenth of the size of the old code.

I guess time to start looking then :) Thank you for the info

Hopefully something grows out of https://github.com/bryanjos/elixirscript so far it seems very actively developed.

If issues such as source maps are figured out, I would feel better about people using it. Also, I would like to work on its user friendliness.

Saying all of that, Elm is pretty nice and I really enjoy using it for some of the same reasons I enjoy Elixir.

Source maps does seam to be the biggest issue to solve before people can start truly experimenting. But huge congrats on starting and moving forward this amazing project.


Yep hope it becomes production ready at some point, but you obviously will loose isolation and all soft real time properties when running transpiled JS.

Even if you don't like JavaScript, it's really surprising to me that a CTO picks something like Elm that nobody uses and only a few know or are interested in [1].

I'm curious to know how the author will recruit developers, specially in France. My last company migrated all its backend in Node this year, ONLY because it was the easiest option to recruit full-stack developers. The market is completely saturated here (there are a lot more offers than developpers), you spend months to recruit a front-end developer or a full-stack developer with front-end knowledge, and I don't see how you can attract someone with Elm. Having 1 or 2 years of xp in Elm on a resume is not really usefull when all the companies use JavaScript. You don't even know if Elm will still be there in 2 years.

[1] http://stateofjs.com/2016/flavors

It's no different than listing a Java job vs listing a Scala job. There are many great developers who would jump at the chance to be hired to write Scala (Elm), so you might just end up with better developers who self-select to work on the shiny, new technology.

As he said, it was going to be used live and he wanted to be sure that it wouldn't blow up on set, whilst still allowing for rabid development in a small time window. Seems like a perfect use case.

Are your statement not a tad bit prejudiced? How is Elm a Javascript flavor? it's not surprising that it gets a bad rap from a stateofjs flavors survey. Elm is very much a competing language and ecosystem, it happens to be much better. I am certain I will still be interested in elm two years from now, the productivity gain is there to stay.

Recruti someone that do not know it and teach. It takes at most a week. And probably productive in a day.

This was great to read and it inspired me to give both a try soon.

Question: Did the app receive millions of visitors or was it basically 1 visitor with millions of viewers via the television showing a recorded screen?

At first I thought Phoenix was used because of scaling reasons but now I'm not so sure.

Either way, nice work and thanks for the write up!

In my experience, Phoenix is used because a) it's easy to get started with b) isn't a monolith like Rails (e.g. Phoenix could be one part of your complete application) but it has good conventions and c) it leverages the Erlang VM's performance and concurrency through Elixir.

I know HN gets a lot of hype for X new tech every month, but I'm really liking Phoenix. Ignore the "Phoenix is the future/saved our lives/best thing ever!!" Medium posts and try it out. It's actually pretty good.

I'm enjoying working with phoenix, but when comparing it with Rails, it would be fair to say "it's basically rails" and add a few footnotes about the differences.

People who started after Rails was released don't see it because they haven't seen how it was done before. But it's incredible how many conventions DHH created with rails that have since entered the basic repertoire of all web frameworks: migrations, its take on MVC, :belongs_to, the router DSL, the asset pipeline, generators – while you can probably find prior art for all of them somewhere, it's the implementation in Rails that, 10 years later, is still the blueprint for new frameworks.

Rails was also the best teaching tool ever invented in the space. Code quality was atrocious, people were reinventing "clever" solutions for every project, testing was probably rare (I never saw it, but it must have been around, right?) I distinctly remember a templating system that turn .xls into a perl script that would write php. If you changed projects, you'd usually be greeted by a directory tree 8 levels deep with the main config.php in /[..]/tmp-2008_b, along with config.inc, main.html.php.old and construction.gif~2.

(Not that Phoenix doesn't add lots of refinements that make it a pleasure to use)

I'd add that Rails was also hugely influential in its focus on developer productivity. A lot of it was magic and incredibly difficult to debug or modify when it went wrong, but it raised the bar for how you market a framework to developers.

Yep. The Dev productivity area is where Rails really set the bar high. All the other "win the benchmark" stuff that everybody goes to to try to dethrone it is a fair example of people missing the point. :)

Fwiw, I'm writing a Phoenix is the Future post at the moment that I hope to publish in the next month. :) Might have to revise the title.

So I saw Elixir+Elm, Elixir+Elixirscript, Elixir+Scala.js here so far.

Chiming in with Elixir+Clojurescript. It's what I've been using for most of my projects these days and absolutely love it. Pure functional programming on both, server and client, with the server concentrating on well distributed concurrency and parallel processing with GenServers and the client on immutable front-end code while using Go-blocks for async stuff.

> Elm has a low entry barrier

Sorry Vincent, you lost me there. Elm is interesting for sure, but it's far from having a low entry barrier. Something has basic has having a button play a sound takes forever to figure out. You almost have to learn everything all over again. It's a cool project and I'm glad it's working out well for you, but Elm has a serious learning curve.

Just my 2c:

Paradigm wise: Yes functional programming can seem strange and hard if you haven't done it before. But that really isn't the fault of Elm, elm makes FP as simple as it can.

Language wise: Yes, the Elm architecture takes a bit to grok, but for me it was just an afternoon. Once you grok it, there isn't really much else you need to learn - you can hit the ground running, look up what you need when you need it.

Tooling wise: Just some basic tooling you get will get you very far, no setup either, just install and use.

If you do js interop, yes that can be cumbersome, but it is intentional. Elm strives to keep js out and write libraries in Elm. This is so we can have more of the guarantees that Elm provides. (no runtime exceptions!)

I'd rather say: "Elm has a low entry barrier for a FP language". One of it's main goal is to bring FP to the masses after all. :)

Elm is one of the simplest languages you will ever stumble across. I realise the simple is subjective, but you must be having some kind of mental roadblock, because it really does almost ALL the work for you.

I hope Elm doesn't get too closely tied with Elixir. It's a great language no matter what backend you choose.

I also don't get why they're coupled a lot... they're very different once you get past that they're both "functional" (and Elixir really just has HOFs and immutability by default, it's very practical). If it makes you feel better, I only see this coupling online. Most people just use server-rendered pages or regular JavaScript.

It's really just a weird overlap in the communities. There's nothing tying Elm and Elixir together aside from the anomaly where many people who started experimenting with one also started experimenting with the other.

Most people seem to be coupling the two together based on getting into functional programming. It also doesn't hurt that the Daily Drip, a great Elixir "Railscasts" clone also has a section for Elm.

I see a lot of interest in Elm in Elixir community but if you take actual production projects written in Elixir very few use Elm on FE.

Damn, look at this European protectionism /s.

(I'm a functional programmer, so yay for them!)

the guests were Nicolas Sarkozy (12 millions viewers), Arnaud Montebourg (9 millions) and lately Alain Juppé (13 millions).

I would like to see the results of the two other guests.

There has only been three shows so far IIRC.

As a French trying Elixir these last few months (don't have much time for Elm) it's great seeing the language picking up some hype.

At work I don't see it happening though, we're a PHP shop now addind nodejs (to my despair) and maybe some Go. I think there is a Haskell fan and that's it.

Applications are open for YC Winter 2023

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact