I am Richard Feldman, author of Elm in Action and instructor of the Frontend Masters Elm Workshop. The main open-source projects I'm working on right now are elm-test
and elm-css
.
I work at NoRedInk, where we have 80,000 lines of Elm code in production. We introduced Elm in 2015, and since then our production Elm code has thrown a total of zero runtime exceptions. We hired Elm creator Evan Czaplicki in 2015 to continue developing the language, and we're hiring!
I'll be here until noon Pacific Time. Ask Me Anything!
Oldest comments (119)
What do you think about such approach to structuring application with Return.Optics toast.al/posts/2016-10-20-optical-...
One of my favorite programming sayings is "I've learned there are worse things than boilerplate."
Over the years I've found that most things promising to "reduce boilerplate" do so in ways that make maintenance and debugging harder. I think back with regret on the times I decided to accept that tradeoff, and I think this falls under that category. I wouldn't recommend it. :)
What do you think about dgriffith/style-elements package.elm-lang.org/packages/mdgr...
I haven't tried it, but I love the idea!
Are there any chances Elm development will become more open? It's easier to get info about future Apple products than to guess what's happening to the Elm language next.
How's Elm Software Foundation doing now? It was publicly announced about a year ago. But it's still not very clear what the purposes are, who's on board and what's the roadmap.
Thank you!
I think Elm doesn't have a concrete roadmap because Evan adapts his plans based on what he learns from the community. If you ask him "what will you be working on 6 months from now?" the answer will probably be "depends on what happens in the next 6 months." He does post periodic status updates on the elm-dev mailing list, if you're wondering what he's working on and how it's going.
My understanding is that the Elm Software Foundation is primarily for organizing money-related things. The main reason it exists is that Evan is friends with Python creator Guido van Rossum, and Guido recommended that he set up a nonprofit a la Python Software Foundation. It's not really for project management or anything like that.
That's great, but how can we get Evan interested in community feedback that have already been crystalized in "meta" issues on github for the virtual-dom, html, elm-compiler? Like this one github.com/elm-lang/html/issues/53
Actually, there is a status report on elm-dev now. Same day as I've asked this question :)
It was almost two months since the previous one.
how can we get Evan interested in community feedback that have already been crystalized in "meta" issues on github for the virtual-dom, html, elm-compiler?
Another way to phrase this is "how can we get Evan to stop working on what he thinks is the most important thing, and instead to work on what we think is the most important thing?"
Ideally everything would get addressed sooner rather than later, but there isn't time for everything, it's impossible to please everyone, and prioritization is hard.
For example, right now there are a lot of people who literally cannot use Elm because it doesn't have sufficient asset management tools to get acceptable performance on low-end mobile devices.
I don't think Evan is wrong to focus on that right now. :)
Another way to phrase this is "how can we get Evan to stop working on what he thinks is the most important thing, and instead to work on what we think is the most important thing?"
No, actually another way to phrase this is "how can we get Evan to start doing frontend stuff in Elm every day".
Your answer on another question about Evan's involvement in NRI day-to-day tasks is practically 0 is the saddest thing I've learned today. I might be wrong, but this is harmful to prioritization.
I think you're underestimating the amount of feedback he gets from all different corners of the community as to what the most important thing is. There are so many people with different priorities who think their particular thing is the most important.
If Evan worked directly on our production code base, he'd probably feel pushed to bump priority for the things that matter most to us, at the expense of all the other voices he hears. As members of this community, that would be a very short-sighted preference for us to have.
Does Evan work on NoRedInk work as well a building Elm or solely on Elm?
He only works on Elm. He's worked here for over a year and he's never touched our product repo. :)
What's your favourite and worst part about Elm?
Favorite part (I'm gonna go with the American spelling, sorry!) is the feeling of invincibility when refactoring. I get some exciting idea for how to make my code cleaner, and I just do it. I don't worry about regressions, and lo and behold, when it all compiles again it still works! That feeling never seems to get old.
Worst part? Being smack dab in the middle of two communities that are almost polar opposites. Many people coming to Elm from JavaScript want Elm to be more like JavaScript, and many people coming from Haskell want Elm to be more like Haskell. I see Elm as its own thing—neither "JavaScript enhanced" nor "Haskell simplified"—and I've sometimes struggled to engage constructively with groups who don't see it the same way.
Where do you see the future of Elm and can you envision Elm becoming more mainstream? If so how do you feel the community can help make this happen?
Where do you see the future of Elm?
Someday I see it being an awesome back-end language too, but that's quite a ways off I think. With respect to the browser, I see the future of Elm being one where Elm's ecosystem becomes one of its biggest selling points.
Right now Elm's ecosystem is much smaller than JavaScript's, so ecosystem is a drawback overall. However, the overall quality of the Elm ecosystem is much higher - in terms of usability and reliability - than the (much larger!) JS ecosystem. I think this quality-over-size trend is likely to continue, because Elm's package manager has a blanket policy of accepting only Elm code, not JavaScript code.
As the gaps in the ecosystem fill in over time, I see the high-quality Elm ecosystem becoming a big selling point. Today people say "Elm's ecosystem is so small, you inevitably have to do some JS interop" but I think in the future people will say "Elm's ecosystem is big enough to meet all the needs of a typical web app, and it is so much nicer than the JS ecosystem."
We're not there yet, but we're headed in that direction. It will take time, but I think it'll absolutely be worth it. :)
Can you envision Elm becoming more mainstream?
Definitely. For any language aimed at industry use, I think success stories among industry early adopters are likely to predict long-term adoption. A very high percentage of Elm's early adopter stories are on the extreme end of positive.
I think the direction JS is moving is helping Elm out a lot. Virtual DOM libraries, type-checking, and functional programming concepts are all becoming more mainstream in JS, each of which narrows the familiarity gap between what people are using on JS teams and what they could be using if they introduced Elm.
How do you feel the community can help make this happen?
Posting experience reports. These are the biggest ways to help things become more mainstream, because people look for data points when making decisions about whether to dive into a language.
"I am thinking about trying Elm. Who else has done that? How did it go? Would the benefits help our team too? Did the costs seem like costs we can accept?" The more data points out there, the more easily people can make informed decisions about these things.
Our story at NoRedInk is out there, but do people know your story? If not, help them out by writing about it!
Can you explain the structure of the main NoRedInk Elm app? With it being the largest Elm app in the world it, would be really cool to know how it was structured and what you've learned along the way scaling up?
Sure! I should emphasize that we don't put a big priority on "getting this right." More than anything we try to be consistent (but don't always succeed), and the compiler makes it pretty easy to rename things if we change our minds, so we don't sweat it. (The biggest drawback to renaming is plain old vanilla merge conflicts.) So I wouldn't take any of this as advice so much as a data point if you're curious. :)
We have a series of pages, e.g. "Teacher Dashboard", "Grading", "Splash Page". Each of these has its own
main
; back when I joined the company we were a non-SPA Rails app, and we have not transitioned to SPA yet. (We have long-term plans to head in that direction, and I don't expect the transition to affect our module structure much - outside ofmain
, of course, butmain
modules are a small fraction of our total modules.)We have a top-level module namespace called
Nri
for things specific to our UI, as opposed to things that we might open-source someday (e.g. theAnalytics
module, theEmoji
module, etc). Here's an example of three related ones:Nri.QuizHeader.Model
Nri.QuizHeader.Styles
Nri.QuizHeader.View
So our Quiz Header has a model, and a view, and some
elm-css
styles. (We've been migrating from Sass to elm-css and it's been sweet!) We don't have aNri.QuizHeader.Update
because the quiz header doesn't have any state. I think this is worth emphasizing, because I see people create a model/update/view any time they want to reuse code, and I think that's the wrong way to scale. Unnecessary state management is bloat! We had no need for anupdate
function here, so it was simpler not to have one.Plenty of times we just have a module to hold
view
, and plenty of others it's not even a separate module, it's just a plain old function inside an existing module, e.g.viewSidebar : User -> Html msg
We also have reusable views that are used across multiple pages, for example:
Nri.Tabs
Nri.TextInput
Nri.Toggleable
Nri.Tooltip
All of these are stateful, and their APIs looks like github.com/evancz/elm-sortable-table - they do not define their own
Msg
types, and callers don't have to useCmd.map
. Their states are super simple, and defining their ownMsg
types would have been overkill - more trouble than it was worth. This is also worth emphasizing; immediately reaching for a customMsg
andCmd.map
any time local state is involved is a surefire way to get needlessly overcomplicated wiring.My rule of thumb is that reusable views where
view
returnsHtml msg
instead ofHtml Msg
are nicer by default, and I only reach for a customMsg
once I have enough state transitions thatCmd.map
would reduce verbosity substantially.Finally we have some reusable data structures, which begin with
Data.
, for example:Data.Assignment
Data.Assignment.Decoder
We debated the right namespace for these and settled on
Data
because what they have in common is that they're about representing and encoding/decoding some piece of data.These are a mix of various union types and type aliases that represent common data structures in our app. Some of them have a lot going on, so it's decently common to have a data structure defined in one module, and then the decoder and/or encoder in a separate module. It's no big deal if they live in the same module, though. Again, we don't spend a ton of time on module structure because it's so easy to change reliably if we change our minds.
Hope that helps!
Very helpful, thanks
Where do you see the pros + cons of TEA? Especially, compared to Redux (used in combination with immutables).
I got into React very early after Facebook open-sourced it, but I switched to Elm before Redux came out...so I've never actually used Redux. :)
I think the following is the most honest way for me to answer the question of pros + cons:
The Elm Architecture in Elm
It's the only game in town. If you want to build UIs in Elm, the Elm Architecture is the only way to do so.
Pros: the entire ecosystem is optimized around it; no fragmentation
Cons: it's not well suited to doing major manual DOM manipulation
The Elm Architecture in JS
I've never tried this. JS is a totally different language, and I don't think it would be useful for me to guess what it might theoretically feel like to use Elm Architecture in JS. A better person to ask would be someone who's tried precisely this, and especially someone who's also tried Redux. :)
If the subtext here is "can I get many of Elm's benefits by using the Elm Architecture in JS?" the answer is unfortunately "not even remotely close." In my opinion almost all of Elm's benefits come from its compiler and library ecosystem, and you can't access either from JS.
Thanks you very much for your answer. No, I do not want to use the Elm Architecture in JS :)
To be more precise, I was wondering how the "update" function scales in the Elm Architecture, since I do not believe that Elm developers are using one big case statement for all possible messages. I think this is solved very well in Redux by composing reducers. I really dig the way all those small (pure) functions handle part of the application state. All the Elm example I saw didn't had that many messages, but I guess if your app grows you will also use some sort of composition to break the updates in smaller parts.
Ah! I posted my thoughts on this over on /r/elm - hope that's useful!
What where the issues you had at NoRedInk with your previous (React) stack that made you switch to Elm?
This was the subject of my ReactiveConf 2016 talk, so I'll defer to that! :)
When you first began using Elm at NoRedInk which parts of the system did you begin to port across first? What were the road blocks you encountered to begin with and any advice for other teams who are thinking of slowly moving away from React like environment to Elm?
We actually started with some business logic in our quiz engine. I wrote a guide for how to do this, but I haven't updated it since Elm 0.16. (This reminds me that I should really get around to that...) I forget where we first used Elm for actual rendering, but it started to snowball pretty quickly after that.
The biggest roadblocks were around build tooling. I didn't do a good job figuring out how production deployments (via Rails - we hadn't started using Webpack at that point) would differ from development builds, and the build tool plugin ecosystem wasn't as far along as it is today. (And it's still got a ways to go.) I guess maybe "roadblock" is too harsh, since we got past it, but even after migrating a bunch of stuff to Webpack we're still dissatisfied with our build process overall—and not just with the Elm parts.
What word is best used to refer to Elm developers and why is it Elmos?
I like Evan's preferred term: "Elm programmers"
I heard a great point once, which is that calling ourselves "Elmists" or "Elmers" or "Elmos" kind of suggests that we're a tribe, that we treat the language as more than a tool we use for a particular job.
But at the end of the day, that's what it is: a tool we use for a particular job! We should choose Elm when we think it's a good fit, and choose other tools when they're a better fit - not because we're part of a tribe. :)
I haven't asked others on the team, but the only times I can recall seeing any in development, they weren't a surprise - e.g. I was mocking something up with Debug.crash with the goal of "I'll finish implementing this later, but for now I just want it to compile so I can try out the rest of what I've done" and then reaching one of the code paths that called Debug.crash as I was playing around with it.
Of course that's what I expected it to do, and naturally I replace every Debug.crash with a real implementation long before making a pull request!
As the ops guy at NRI responsible for Elm, the main source of errors with Elm is actually during builds. From 0.15-0.17, Elm did not correctly handle the caching of artifacts, leading to occasional compile errors that were not reproducable easily. It was simple enough to fix - just wipe the artifacts. But that also slowed the builds down a lot.
I'm also fairly certain I'm the leading expert on runtime exceptions in Elm - it's possible to make them happen, but most of the time you have to really understand Elm to make them happen. Unless you're using Array or Regex, of course. Both of these can lead to runtime exceptions - e.g
Regex.regex "[a"
. However, you'll not likely run into that in production - unless you are taking using input as regex input.. which probably isn't a good idea unless you're escaping things.EDIT: here's a blog post from one of our junior engineers about her experiences learning Elm in her first week! tech.noredink.com/post/15779255223...
We have new hires doing it in their first week, and that includes devs for whom this is their first job out of a bootcamp (and no prior programming experience before the bootcamp). We've done this several times now - we do lots of pairing when ramping people up, and it usually takes less than a week for someone to get productive enough to make production contributions on their own.
Take that with a grain of salt, though; we're talking "can literally contribute something useful," not "can hammer out features from scratch with no assistance."
I will say that I remember when we taught new hires React from scratch (back in 2014), and the learning curve for Elm today feels comparable to React + Flux + an immutability library back then. Yes it's a whole different language, but it's a simpler setup overall, and the compiler helps a TON. (That said, obviously in 2017 more new hires know React on day one, and the corpus of learning resources for React is much larger than it is for Elm.)
is it anti pattern to use Message like: UpdateModel (Model -> Model). When handling of the message is just to update model with function passed as parameter like:
case msg of
UpdateModel f -> (f model, Cmd.none)
.....
That seems overcomplicated, yeah. I wouldn't do that. :)
What is your favorite editor / IDE for Elm development?
I like Atom because its Elm plugin support is fantastic, and its Vim plugin support is among the best you can get outside Vim itself.
In particular the Elm-related plugins I use with Atom are: