Why We Care About Elm

We discuss our backstories, our core values and beliefs as developers, and why Elm speaks to us.
July 3, 2023


Hello Jeroen.
Hello Dillon.
Well today I think it might be time to pull back the curtain a bit and expose some of
our opaque types for our listeners.
Oh no!
No, we want to keep those things hidden!
But they need to know how we got here.
They need to know our supervillain backstories Jeroen and why we care so much about Elm.
Alright, should we not say like supervillains that stay opaque?
That's our superpower!
Yeah, but like if you discover the villain, then he's not a villain anymore.
He's just a troubled person with problems that he's trying to solve.
Then we'll just be Batman.
Okay, you be Batman and I'll be Robin.
You could be Superman.
We'll just reveal your kryptonite.
Alright, that's fair.
So I think it's fair to say Jeroen, we do care a lot about Elm.
That might even be an understatement.
Slight understatement.
Yeah, probably.
I think we've both invested a lot into Elm and really I feel a sense of wanting to invest
in this community because I think at the core of it there's something I really believe in
and I want to like fulfill this vision of this thing that I think is really important.
So I thought it'd be cool to like get at that.
What is that thing that's so important to us and like how did we get here?
What made us care about this so much?
Yeah, absolutely.
So Dillon, why do you care?
What is your origin story?
My origin, so I, my first job out of college was doing Ruby on Rails development and throughout
college I was, you know, we learned, my first college class was in Python.
And that was quite a nice experience learning in Python.
It felt very high level and it was great for being introduced to some like basic computing
Then we started doing Java and C and C++ for the rest of my college courses.
And you know, I have mixed feelings about Java.
It's quite powerful, but, and the editor tooling is incredible.
But when I discovered Ruby for this first programming job and Ruby on Rails, I did start
to fall in love with the approach of like doing things in a way that felt like it did
away with the formalities a little bit.
And it said, let's model domain concepts.
Let's come up with APIs that are DSLs, domain specific languages.
Let's really think about the domain.
Let's think about the domain terms.
Let's speak in domain terms, not in lingo that's talking about an abstract factory instance.
And you know, like Java does start to feel like you're bending over backwards to do things
that aren't related to your domain.
So I liked that about Ruby.
I felt like, okay, I'm really spending a lot of time thinking about my domain.
So that resonated.
Then working with Ruby on Rails.
Now I liked, I think I liked Ruby more than I liked Ruby on Rails.
I know there's a lot to love about Ruby on Rails, but I found it extremely confusing
to navigate because of all of the magic and all of the implicitness and the mocking, the
mocking, Jeroen.
Don't get him started on mocking.
Have you worked with like code bases that do a lot of mocking in their test suites?
I think so.
It's been a while, but yeah, I think so.
Well, I know so, Jeroen.
I know that I've done it because I remember it because I really did not like it.
Like, I don't know.
I still feel the blood on my hands.
I think, I don't know, maybe that is a part of my, maybe that's my radioactive spider
that bit me or something.
I don't know, but I really don't like mocking in tests because it just feels like there's
something so horribly wrong.
If this is what we're doing, then we need to throw everything away and rethink it.
Wait a second.
You've been bitten by mocking, right?
So now you gain the ability to mock mocking.
And now we just make fun of it all the time.
That's right.
Yes, I do.
Mock man.
I would like to, I'd like to make a mockery out of mocking and gosh, because it just feels
like you're, you don't, you don't know anymore what you're testing, you know, because any,
you can't trust anything that you're looking at.
So that was, that was my experience with Ruby on Rails.
I'm looking at some code and I'm like, okay, what, what things are happening to get here?
Like what global variables are there?
What, what code is mixed into this module?
So like, this is like a class that I'm defining, but does something monkey patch it later?
Or is there a module that gets mixed into it later that changes the behavior or override
Is it calling some methods that depend on implicit context and depend on some, some
state that it's changing?
Does it pass in an argument somewhere and that gets mutated somewhere?
And that's like a very real thing that happened when I was debugging things and trying to
figure out what went wrong.
And so like, and then you go to fix it.
And I, and I loved like writing tests to wrap my head around what was working.
And when I was writing unit tests, I'm like, oh yes, this, like, this makes sense.
I can like understand what this is doing.
And then you start doing controller level tests, integration tests, and everything is
mocked and you're like, wait a minute now, like now there's all this magic in the code
And now I've added this, like, I don't know what I'm actually testing.
I don't know what's real and what's fake in the test.
So I was very disillusioned by that, but I didn't, I didn't know it at the time.
I didn't know I was disillusioned at the time because that I'm like, well, I guess like
this is programming.
This is like, this is what you do.
And I didn't know there were alternatives to that.
This is my life now for the next 40 years or however long.
So I had had a little bit of a seed planted because when I was doing Ruby on Rails, I
discovered the enumerable mixin, which is something you can use on data structures that
are enumerable like arrays to, to filter them and map them and inject fold L sort of thing.
Wait, was inject fold L?
I can't even, I honestly can't even remember now.
Sounds like a weird name for fold, but I think it might've been.
And then there was compact.
Compact was very cool.
Compact is something I do all the time now in Elm, a filter map identity.
Oh yeah.
Removing all the nils in the case of Ruby from a, from a list.
But but I fell in love with working in that way and I started to really, you know, instead
of using the shovel operator to imperatively add things into an array as you iterate over
it, it's a way to push things into a list.
That's another thing about Ruby and Ruby on Rails.
There's more than one way to do it.
You know, my mind is a little bit stuck on the shovel operator.
I'm trying to imagine what it would look like.
It's a double carrot.
I think it's two less than signs.
Oh, so function composition in Elm, they call that shovel?
They call it shovel because you're shoveling things into an array, I guess.
So it's more about the use and what it looks like.
I guess.
I think so.
But these are things that you, you need to know.
And so much time was spent in code reviews, just talking about, you know, nitpicks of
like, oh, you know, I really don't like the shovel operator.
I prefer to do it this way.
I prefer to do it, you know, with a list dot map, or I prefer to do it with a for loop,
or I prefer to do it within each loop because those are all things you can do.
I prefer to use unless.
I prefer to use if.
It's like, geez, let's just like have one way to do things that works nicely, you know,
Let's configure this linter to make all those choices for us.
Oh, right.
Which linter should we use?
Yeah, I prefer this linter.
This was in the days before like auto formatters were in vogue also.
So you know, that was a whole nother thing.
But yeah, it felt like there was so much churn just figuring out how to express something.
And at the same time, like, like, I wanted to just think about how do I model these domain
And how do I understand what the heck is actually happening here?
Like, how do I get a test around it to understand exactly what inputs lead to what outputs and
what scenarios are interesting?
How do I model the domain, interestingly, and how do I avoid like magic stuff?
And so like enumerable started to feel like, OK, I like this way, but I felt a little bit
out of place because I didn't feel like everybody was on the same page as me with like, some
people could kind of get behind it, but it wasn't a widely held opinion that that was
a cleaner way to do things.
So I guess the thing after my Ruby on Rails days was I got into coaching, agile and technical
coaching and that influenced me a lot in terms of the power of small steps, the power of
being very deliberate.
And I was coaching teams, I was coaching a team using AngularJS.
And there were so many, so many challenges working with that code base, you know, making
it testable and, you know, bugs would pop up and Angular just, you know, this is Angular
1, AngularJS.
And it was, again, there were a lot of ways you could do things.
There were a lot of foot guns.
There was, you know, you could mutate the DOM.
You're definitely not supposed to.
There are like big warning signs that say, warning, don't use this, but it's here.
And you find some random stack overflow post and you don't know what's broken.
There's some subtle, like leaky abstraction that you need to fix and you don't know what's
going wrong to fix it.
And so a stack overflow post tells you to mutate the DOM and you do it.
And not to mention, it just felt like very difficult to, to even just like, you know,
I want to have this Angular dependency that I can use in this context.
How do I even get it in there?
And how do I know that it's working correctly?
You know, it like automatically injects values based on the variable name.
And you're like, is this even working?
And if it breaks, how do I know?
And at the same time, like I'm coaching this team on these technical practices and we're
helping them do legacy code refactoring, do continuous delivery, getting push button deploys
and doing trunk based development on it, all of these things.
And it had real results.
Like we were, we were shipping faster and more confidently, but there was so much work
to get there.
And I realized like the language choice plays a big role in your ability to do these practices.
And when I discovered Elm, it was a breath of fresh air because suddenly all these things
I was trying to coach, like let's avoid having our tests blow up on the first of the month
because it depends on the specific date they're run.
Let's make them deterministic.
Like these are practices I was coaching teams on that, like I saw results in the code bases
becoming more robust and teams spending less time churning on these fires and more time
focusing on the domain and shipping things faster.
But with Elm, I'm like, wow, like dependency injection is just the only way to do things
because you can't depend on impure things.
And testing is very straightforward and you have this fast feedback loop from the compiler
telling you exactly what went wrong.
Even back then, because I think you used Elm in 18?
That was in the 18 days.
When the compiler was still slow, right?
Well, when I say fast feedback, I mean, everything was kind of slow back then.
So I wasn't really like noticing a speed difference between other things.
Also, this wasn't like a, you know, several hundred thousand line code base.
But when I say fast feedback loop, I mean, just more like compared to scratching your
head at why isn't this Angular thing working and it not telling you and you literally spending
a whole day trying to figure it out.
And you're like, oh, of course it was here, some dumb little thing, but it doesn't tell
So it really felt like a breath of fresh air.
And it really felt like it addressed these things in my experience with Ruby that didn't
sit right with me where mocking it's like, well, you can't mock.
But more importantly, like you express the code in a way where you wouldn't need to mock
because it's not coupled to all of these side effects and external systems.
You inject that in.
So you just test the behavior.
You write something that isn't coupled to that.
So all of these like very subtle decoupling things that I was trying really hard to like
coach teams on and teach them how to practice.
It's like, well, in Elm, you don't really need to teach that.
It's just like, I mean, in Elm, you just need to tell people, write tests.
But if they write tests, then they're going to write them in that way and they're going
to write their code in that way.
So I think that's I think that's kind of my story.
That's why I really believe in Elm because all these things like that, I felt like I
didn't belong.
I wasn't in the right place because I just wanted one way to do things.
And also, I just like wanted these practices to be natural.
It just made sense to me.
Yeah, I totally see where you're coming from.
The mock spider, radioactive mocks.
Mock man.
Well, Jeroen, what is your super villain backstory?
Are you a super villain or are you a superhero?
Who knows?
The listeners can decide.
Please say I'm a good guy.
Yeah, so where I come from is more from working as a developer.
So my career started with CoffeeScript and JavaScript and then more and more JavaScript
until I did some Elm.
And I was pretty much always getting a little bit frustrated with all the problems that
we were hitting, crashes that were happening that felt preventable.
I started looking into ways that we can improve things by using the newest framework out there.
I remember being very excited about AngularJS when I was still interning.
I was excited by React when it was released, which is at a company where we're using AngularJS.
And later on, I became excited by Elm for the same reason as well.
I started playing with functional programming using Lodash, a specific version of Lodash,
which is called Lodash-FP, which is all those, not standard, but all those extra functions
like we have in basics extra and text extra that are done in FP style.
So nothing is mutated.
You always get a copy of things and the order of arguments is data last instead of data
So that was quite different from regular Lodash, but I really enjoyed using that.
That made things feel more easier to understand.
And the Lodash, the FP stuff is using like curried JS style.
So you were already into partial application and down that rabbit hole at that point.
Yeah, in a way, yeah.
So maybe I didn't use it all that much, I feel, in retrospect, but it did make my learning
of Elm much easier.
I didn't have as much trouble with learning Elm as plenty of others have done, probably
because of that.
Yeah, yeah, I think so.
It's just like, well, it's the same things as Lodash, except you have less surprises.
And yeah, and it worked well.
So that felt very nice.
And at the same time, I was playing with ESLint, writing a lot of ESLint rules.
I wrote like 75 over the course of a year, because there were just so many problems that
you could have in our code base and in JavaScript.
So I wrote plenty for packages that were published, a few under my name, a few under other people's
names, and a few that were custom to our code base at work.
And I mean, 75 rules are a lot of rules.
I don't think I've written that many for Elm Review in the four years that I've been working
on it, or however long that was.
So yeah, at some point, I discovered Elm.
And I'm like, well, just first to play with Elm, I needed to try it out.
And Elm is a front-end language to do web applications, but I had no real experience
with making front-end applications.
What I did have experience with, however, was writing Linter rules.
So I decided, well, you know what, let's try to make a Linter, even a basic one.
And I really liked the experience, mostly because of custom types, like just the fact
that you can pattern match on AST nodes, and you know exactly what they contain and all
the AST nodes that you can encounter.
That felt like a breath of fresh air, because when I was running ESLint rules, oftentimes
I didn't know which AST nodes I would hit, which one I would encounter.
And then there were some properties that I thought would always be there that turned
out to be optional.
And when I relied on them not being optional, that crashed the whole ESLint application.
And that didn't feel nice.
So when I was playing with writing a Linter in Elm, I was like, well, the experience is
much nicer.
And I say that even while writing the Linter from scratch.
So that was a lot more work.
And that was your first Elm project, right?
That was my first Elm project.
And at some point that became ElmReview.
And that was at the beginning of 2017.
So that's been a long time.
Yeah, wow.
Yeah, so then I didn't use Elm for a few years.
Started doing it professionally at a company, and I really enjoyed it.
There was one thing that was lacking.
There's like, oh, well, there's plenty of problems in my code base that we can just
fix by telling people, hey, look at the code you wrote.
This is not how we should do things.
And I'm like, well, if only we had a Linter that could write custom Linter rules.
Well, you know the rest of the story.
So yeah, my experience with Elm was like, there's a lot less things that you need to
check with static analysis, because the compiler is already doing that, and the design of the
language is already doing that.
I actually made a blog post on Elmcraft, or an article on Elmcraft, describing all the
rules for ESLint, the core rules that don't make sense in Elm, like that you don't need,
or which ones do you still need?
And like 86% or something like that were not needed, and therefore they're not in ElmReview
And that's just like a staggering number.
So yeah, these are the kinds of things that I really enjoyed with Elm.
And over the course of my Elm career, or mostly working as a tooling developer, I've just
come to appreciate how much potential Elm has.
And it's a bit of a weird potential that you have, because you can say, oh well, JavaScript
has plenty of potential, you can do plenty of amazing things, and that's true.
Rust has plenty of potential, etc.
All those languages have them.
But Elm's case is a bit particular, because for instance, for JavaScript, you're like,
oh, JavaScript is amazing, and once we have async await, or whatever new feature that
was decided by a committee, it's going to be much more awesome, things are going to
be much easier, and you're going to be able to create very cool products with it or very
cool tooling.
And the Elm way, the way that Elm has potential is not that way.
It's not like, oh, we're waiting on features that a committee has decided or that Evan
has decided.
It's more like, well, we see a lot of innovation because people push what they can do with
And I'm just always amazed by what people do.
And it's usually just relying on the design of the language, which is like pure functions
everywhere, immutable values everywhere.
And just from those tiny facts, you can do so much.
Like ElmReview, great tool, but it's great because it has a language that is very analyzable.
And if a value doesn't appear anywhere, then you can just remove it.
Easy as that.
Lambdara, for instance, has like, well, we're just writing Elm code.
And because Elm code is just plain data, we can just send them over the wire from the
front end to the back end and back end to the front end, maybe with some additional
But you can basically just write Elm and you have now an amazing experience writing front
end and back end languages with hosting and backups and all that.
And it's only because we're pushing on the things that Elm gives us, not because we're
expecting new features to arrive to the language.
And that's something that I haven't found anywhere else.
So that's one of the reasons why I really care about Elm, is I just see so much potential
and it's not even like because I see it, like I can think of it.
It's like I know that people will make more things because they just keep happening.
Yeah, right.
That resonates with me a lot too.
Like because, yeah, as you say, it's not just like what got you in the door, but then what
makes you see the long term vision that you want to be a part of?
And I think we both are really invested in that.
And it is, like you say, because I mean, you know, Elm Tailwind modules and Lambdaera and
you know, Elm UI and all these like innovative approaches.
I mean, Elm format, it just like it feels like there's also an ethos in the community
of being willing to think things up from first principles.
That's really cool.
But thinking things up from first principles while also being very pragmatic and user focused.
And I think that's pretty remarkable.
Yeah, Elm's design has a lot of things going for it, where we're able to mix a very simple
language with very strong guarantees to get a lot of things out of it.
So we have a simple language that is easy to teach.
Like people always tell you, oh, there's a learning curve because it's different.
But in practice, Elm is still a very simple language, especially for a functional one.
It's teachable, it's analyzable for Elm review, for people reviewing the code.
It's pretty fast.
It's super maintainable because of pure functional features and immutable.
And all of that, it goes well together.
And you add to that, like all the things that you can get out of that.
And it's just the result is just amazing, in my opinion.
That's why I stay here, because I see some potential.
I don't know what people will come up with.
I'm very excited to see things.
I see other languages, like for instance, Rust is an amazing choice for plenty of projects
at the moment.
And it's trying to improve the status quo compared to other languages or frameworks
that are in the same space.
So mostly about memory and performance, it's trying to be really good at that.
And other languages do the same thing, like F sharp is an improvement over C sharp because
of improvements.
It's a different approach.
And you've got other languages like Rescript or Reason, I still don't remember the name,
Grain, Glean, they all try to improve the status quo, improve things compared to JavaScript,
compared to other languages.
But they never go as deep as Elm goes.
Like it's always like, well, F sharp is, if you're a functional, it's a functional language,
we're not going to go deep into purity.
Glean is like, well, we're going to be pretty much just like Elm, but we have FFI with Erlang
And you lose some of the guarantees that Elm has, or the Elm approach has.
And I'm like, well, it's a shame because you lose so much by doing that.
The difference between a, I mean, a 99% guarantee isn't a guarantee, right?
And it just, it feels different.
You know, not to say that it's not a valid approach with benefits to say, I want to make
the set of trade-offs where I can do FFI with these other languages, or, you know, I want
to just write in JavaScript, or I want to use Rescript and be able to directly call
JavaScript and wrap things with their FFI wrappers.
That's great.
Like, that's a totally valid set of trade-offs.
It's just a very different set of things that fall out of that compared to Elm.
And I think you and I really find it a compelling vision when you say, let's make that drastic
And, you know, as you're saying, like, I think the thing about Elm, it's not, it's not about
what Elm adds.
It's about what Elm has removed.
And it's removed these things that you, that give you guarantees.
So now you can say, well, this is all I have.
I have custom types and pure functions and immutable values.
And that's, if that's all there is, then I can make so many assumptions and I can have
so many guarantees and I can build such interesting tools to use that.
I don't even know if I was like a tooling person before I got into Elm.
Like I feel like Elm really changed that about me where it, I mean, in my coaching days,
I really saw the power of good tools.
And I realized that if you're really good at editor tools, it's not, it's not a fun
It is like a very powerful tool that transforms you as a developer.
I think like, I think if you're able to navigate around refactoring tools and work, I find
that so powerful, like working with guaranteed refactorings, which like if you're working
with Java or Kotlin, it's like really powerful what you can do just working with like refactoring
operations that you can trust.
But the potential there in Elm is even greater because there are way fewer sharp edges that
you can encounter.
Well, as you say, Elm has removed a lot of features and in a way it has removed pretty
much all the foot guns.
It also has removed a lot of escape hatches because in some of the escape hatches, you
have a gun.
We are in, in the basement of America.
I don't know.
Plenty of guns everywhere.
And as you say, like there are trade-offs to doing things in one language or another
and making one tool in JavaScript is, might be much easier than writing in Elm or a similar
language with those same limitations.
But you don't get the same things in return.
So in Elm, like I'm almost amazed that I forgot to say that, but like there are no errors.
There are no crashes.
Like, yeah, that's kind of the main things.
So for instance, if you write things in Lambda or in Elm pages, your code will not crash.
It will not have any errors.
You could probably have a framework like Lambda or Elm pages for JavaScript or other languages
like that, but you're not going to be able to prevent it from crashing.
Or maybe it's possible, but you're going to have to do so much work on making that work.
So you're going to have to add additional limitations to your language.
So for instance, say like, well, you can use, it's just JavaScript, but don't use eval,
don't use subclassing, don't use, I don't know, whatever feature doesn't work in this
imaginary situation.
Or you're going to just do a lot more analysis work.
Like oh, please add all these ESLint plugins to make sure you're not falling into one of
these traps or using these foot guns or all these things that you need to worry about.
Like in Elm, it's just much simpler.
That's the default approach.
And then tooling authors, package authors in Elm have just this ethos of trying to make
things type safe, which just improves the situation for Elm even more.
Sometimes at the cost of a little bit more verbose API or things that are not as nice
to use because you need to handle all possible cases.
But in practice, like the result is really, really good.
And you're just going to have a hard time having the same results in another language.
At least when Elm is a good fit for your project, like not saying Elm is always a good fit.
Like we're, but.
Yeah, and obviously there is a trade off with convenience, you know, just being able to
grab an off the shelf NPM package or, you know, React hook or component library, whatever
it may be.
You know, there's a trade off.
And this is a choice that we all make when we're using Elm.
And I mean, in a way, like I feel like you and I really want to do everything we can
to make the ecosystem as compelling as we can to narrow the gap of those trade offs.
Because like inherently, yes, there is a certain like there's people want convenience and Elm
takes away convenience in a fundamental way that gives you something back that's very
It gives you back the ability to reason about your code in a totally different way and the
ability to have guarantees and trust your code in a very different way.
But it takes away convenience and that's just a fundamental truth about the core trade offs
that Elm makes.
And some people are just not going to like that.
Some people are not going to want to be constrained in that way.
They're going to say, hey, you know what?
Like I'm an adult.
I want to be able to have a global variable if that's how I want to solve my problem.
I want to be able to bypass the compiler checks and just use a type and not have to write
a decoder for it and things like that.
And that's a reasonable preference, but it's just a very different world.
And but, you know, I mean, I think that working with Tailwind in Elm is super compelling.
And like that's, you know, as we fill out the ecosystem with more of these things, we
get closer to that vision, which it's not going to be.
I don't think it's ever going to be as big as JavaScript.
It's just I think inherently like you take away people's convenience and fewer people
will be attracted to that world.
But in some cases, like people are going to adopt it and they'll be fine with it.
Like all the functional tools that we have in Elm, like map and filter and reduce and
Well, we can see those in popping up in all other languages, anonymous functions as well.
So people are getting used to some of the features.
And I would kind of say like Elm's some of Elm's features are like seatbelts.
People hated them when they had to start using them.
I'm guessing I was still too young back then.
Oh, yeah.
But now everyone has them.
And I don't think a lot of people will just say, well, this is for nothing.
Like this is useless.
People know it's going to be helpful.
Some people will still decide to take them off or not to put them on.
And well, it's going to be very scary for them.
Should anything happen, you lose some guarantees.
And yeah, sometimes the tradeoffs are very much in favor of one design or compared to
another seatbelts.
It's not a lot of a lot of constraints, but it adds a lot of guarantee about like helping
you survive a crash.
So it's definitely worth the effort and not worth encountering the risk.
And I'd say in Elm, like there's just so many things that handling all cases, handling that
something is null or nothing, it's worth it.
It's not always practical, but yeah, it's a very compelling story.
I mean, it is interesting.
Like I think TypeScript has shown that like, I think that 99% guarantees are in a lot of
people's minds.
And, and that's okay.
But a lot of people calling JSON dot parse and it returning in any type, it's like, yeah,
that's fine.
You know, or maybe they're like, well, I'll use Zod or IOTS and do a decoder style thing.
And be really careful about not introducing any types, but some people are like a lot
of people see TypeScript more as a developer tool and a productivity tool and an auto-completion
tool rather than something that prevents crashes in their system and something, I mean, you
know, prevent some, but it doesn't prevent all and people, people aren't expecting it
to and they're okay with that.
But yeah, when we can have an ecosystem built around this, it just opens up these interesting
possibilities, which we haven't really even scratched the surface of with editor tooling,
refactoring tools.
You know, I mean, Elm Review has like filled a lot of this gap, but Elm Review still has
so much more that it could do, I'm sure.
So like, we're really just scratching the surface of what we can do with this.
Not to mention that, you know, as you talked about, like the thoughtfulness of the API
design that we see is really humbling.
And I mean, I love being a part of this community for that reason.
Like it's just like people really put a lot of care into the domain and they really think
through like they put so much care into that user's experience.
Like what is it going to be like using this package and what things could go wrong and
what things can I make so the user doesn't have to ever think about going wrong because
I can prevent it entirely.
And what things can I model that can go wrong because I can't avoid it, but I can make it
explicit and nice to work with and make those choices.
So and as we talked about in our documentation episode, the Elm package docs are a big part
of that.
And I mean, navigating documentation back when I was doing Ruby on Rails development
and JavaScript development, you know, sometimes tough, like finding what you were looking
for and like, what, what can I, what can I call?
Because there's meta programming and things are, you know, except different types of values,
you know, except an object or null or undefined and have different behavior based on what
you pass in.
So it's very, very pleasant to work with Elm APIs and very easy to navigate.
And it's just so, yeah, like I think, and in general, like I think I really at my core
believe in this idea of working with pure functions as, as the basis of what we're writing
and building out all of these things around them.
Again, like the mocks, right?
Like if you're a mock man, it's just like, it solves that problem by inverting things.
If you can't do non-deterministic things, if you can't mutate state and perform side
effects and do non-deterministic outputs from, from within your code, you can only do it
from outside of your code.
You can only pass it in from outside of your code as a dependency.
You've inverted that as a language feature, which is amazing.
And I can't understate the value of that to me, having that as not a guideline and a principle
and a best practice, but as a part of the language is very powerful.
And so I just deeply believe in that.
I also believe in that not just for my beliefs about like best practices for coding you know,
taking small steps and making things testable and all these sorts of things, but also for
Like I believe that it's a very good way to target things as a framework author to, to
just neatly define like, here's the interface for this thing.
And I, as the framework, I'm going to be the interface between you and the outside world,
but I'm going to clearly define the contract.
Choose your contract of what you can ask me to do, and I'll go do the dirty stuff in the
outside world that performs side effects and does impure things.
So building Elm pages, that's been something I've really started to believe more deeply
as well is that Elm is actually a very powerful tool for, as a target for framework authors.
And I, well, actually the day that we're recording this is the day after I released Elm Pages
And I hope that there will be more big framework releases like this to come in the Elm ecosystem,
because I think it's a very promising part of the Elm language.
And I hope it's for the maintainer because it's been a lot of work.
It has.
Very true.
Yeah, I think we could do with maybe a suite of tools to empower framework authors.
I'm not sure if that would be at the compiler level or a set of meta tools, but whatever
it is, yeah, we could definitely empower.
And in general, I think, I mean, I think that's what I most wish for the Elm ecosystem is
that we could empower authors of tools to do more, like having more access to type information
and things like that.
Like if we have that, I feel like so many powerful tools would come out of that.
See, you're not even asking for new features in the language.
Right, exactly.
You just want the things that we have to be even easier to access to make even better
tools or better frameworks or better packages.
Yes, exactly.
Because there's so much rich information that the compiler has.
And when you pair that together with the guarantees that the language gives you, the tooling
possibilities are endless.
But if we had an easier way to make use of those and didn't have to reinvent the wheel
every time as tooling authors, I think it would enable a lot of innovation.
And that's like, I think that's really what Elm needs to blossom.
Like you said, it's not, it's not so much new, like there aren't that many language
features that Elm really needs, maybe a handful of small improvements, but nothing, nothing
There's like, that's not the main thing it needs.
I do feel like we're both on the, of the opinion, like what Elm is missing is more tools.
At least that was what we said.
And I'm sure that if we, if other people talked about the same topic in Elm, like more regular
users of Elm, just people who write Elm to do their day job, then they would have a very
different reply to this or different opinion of this.
At least I don't think they would focus on tooling as much.
In practice, I think most people, they want better tools and for people in the JavaScript
world, for instance, that often comes, that often comes from new language features or
new framework or new build tools or whatever.
So yeah, also tooling, but also sometimes new language features.
I mean, we, we would definitely benefit a lot from a larger ecosystem.
You know, I mean, it would be great to, if you want to use a particular, you know, view,
view library, it would be great if there were some no brainer choices for doing material
UI or Ant design or whatever it is in Elm.
That would definitely be a huge boon for, for the Elm community, I think.
Another reason why I care about Elm is just, I find it fun.
It's like just working on, no, not even working on Elm things.
It's like working with Elm.
I'm for instance, super happy that I've built Elm review in Elm, at least mostly in Elm.
The Elm parts are the more, the most fun ones and just the, yeah, the, the sheer simplicity
of refactoring and adding new features and making sure you don't have to, not having
to think about all the edge cases because the compiler will remind you about those.
It's just feels so nice.
It's just very enjoyable, very relaxing compared to when I work on Elm review, but on the CLI
part, which is in parts written in JavaScript.
Now with a slightly bit TypeScript or JavaScript with JS doc and it's not a fun.
Yeah, I feel the same way.
And I definitely make the sacrifice of writing JavaScript and TypeScript to build these meta
frameworks to make it nicer to work in the Elm ecosystem.
But then once I can move away from that and just say, okay, I built all this infrastructure.
Now let me sit down and write an Elm pages script, you know, or let me write a route
module in my Elm pages app.
Like yeah, I feel so happy just having that explicitness and the Elm compiler to help
And again, like not having to wonder, does this throw an exception?
Does, does this change some state somewhere, you know, or should this use the shovel operator
or a map or a for loop or an each loop, you know, or it just see like, it really does
feel like there's, there's almost one way to express a lot of Elm code.
Of course it's not literally one way, but it, it, it feels like you write Elm and it,
you don't have to think about all these details.
You think about what is the problem I'm solving and, and you can refactor your code.
It's fun to refactor your code.
It's not scary.
And like, well, here we go.
Probably going to break a bunch of stuff.
And if you, if you write tests with Elm, it's even easier to, to refactor your Elm code.
And it's very easy to write tests in Elm.
It's so nice to write tests in Elm.
And the kinds of tools that we see, like Martin Stewart wrote Lambdaera program tests, which
I'm absolutely amazed by just emulating.
So similar to Elm program tests, where you have something that, that emulates a browser,
letting you click on something in an Elm view and navigate around an Elm application and
make assertions about what the view shows.
Lambdaera program test builds upon that, but it lets you simulate multiple connected clients
interacting with an actual Lambdaera backend and actually executing that backend code.
And it's not mocking it.
It's running the same code that's going to run in your backend in production and the
same code that's going to run on your frontend in production.
And you can trust it.
And there is the browser emulation piece, but that's a pretty thin layer, you know,
clicking on things and triggering on click events.
So besides that, you know, that it's going to behave the exact same way, but it's as
fast as a unit test because it's not spinning up a headless browser.
And in the case of Lambdaera program tests, it's emulating multiple connected clients
to like a real time backend framework.
And you can actually view it stepping through it.
It's just unreal.
And the, and this was something that Martin Stewart was like hacking on something.
He's like, Oh yeah, it'd be nice if I could like write a test for multiple connected clients
to make sure I've got these race conditions ironed out.
And it'd be nice if I could visualize the state of it.
And he just kind of hacks it together and he's like, Oh yeah, it actually works out
perfectly and it's really easy and elegant.
And that's how it is.
Like I feel like that's something inherent in Elm that things don't end up, you pull
on the thread and it gets messier and messier and you, and it works really nicely until
you start pulling on that thread and then it falls apart.
In Elm I feel like you start pulling on that thread and it, it comes together even more
cleanly because it's, there's an elegance and a simplicity to Elm itself.
It requires some work to, to, to remove all the hairy parts, but yeah, absolutely.
It requires a lot of work, but you're like, the potential is there to build amazing tools
that like don't have these caveats and these messy edges.
If you're willing to put in that work as a tooling author.
I'm thinking of Cypress for instance, where Cypress is a testing framework where you can
emulate your browser and it actually runs a browser and it's super powerful, but everywhere
in its docs it says things like, don't do this or don't do things this way.
And whenever you go to another test, then we just start from scratch.
It's like kind of the same experience that you just said, like you, you pull on a thread
and the result is nice, but at some point if things get hairy and in the case of Cypress,
because it's JavaScript, it's playing with a browser, which is complicated in practice.
Well, they don't put out something nice.
They just say, okay, well not start from here.
You should not do this.
You should not do that.
And the result is not as nice and you don't get the same results.
Like it's slower, well for good reasons potentially, but it can crash.
It can crash in weird ways.
I might be a little bit biased, but you get what I mean.
I mean, you know, I think that's what we get for the price of Elm, the price of writing
pure functions, which is a limitation that we take on.
And that's what we get from that, right?
So really interesting things emerge from that.
But that's why tooling is so important in Elm, because we paid that price.
So give us our money's worth by giving us amazing tools and dedicating your life to
building really cool tools, tooling authors.
So that's why we do it.
I will dedicate my life to make these awesome tools that rely on the purity and functional
and blah, blah, blah.
So that's not my villain story.
That's my priesthood story or something.
Maybe it's a curse.
I don't know what it is, but here we are.
You talked earlier about people who do TypeScript and they're happy with the new guarantees
that they gain from TypeScript compared to JavaScript.
And I mean, it was a lot of work to convince those people to use TypeScript for good reason,
because it has a lot of complexity still and a lot of build steps and all that.
And some people got convinced and some people are now very, very happy with it.
And TypeScript is now pretty much the standard, even compared to JavaScript, at least in the
circles that I...
Sometimes you just don't know how bad you have it, right?
Like the people who did JavaScript and not TypeScript, they didn't know how good it was
to have types.
We often say that they've been bitten by Java and they're pretty lousy type system.
And that might be true.
But yeah, if you go to Reason or to Elm or to F Sharp, the types are really nice.
And I would say from TypeScript compared to Elm, you now have a type checker, which works
It doesn't use the same technology or the same idea behind it.
So the TypeScript one is not as reliable.
Like something that is still missing is side effect tracking.
And I don't think the TypeScript people know how bad they have it, that they have to handle
all those side effects.
Yeah, right.
Every time I go to the Netherlands, I'm just always amazed by something that is very simple
and that is traffic lights.
Have you ever been to the Netherlands?
No, I'd like to go.
Okay, well, the road infrastructure is very nice because you've got bikes everywhere.
You get a separated bike lane and a separate pedestrian lane on top of the normal roads.
And the traffic lights are just amazing.
Like for instance, if you're in a car and you go to a crossroad, so we've got traffic
lights everywhere stopping people.
And if you're the only one who's driving through that.
So for instance, if you're driving in the middle of the night, then the traffic light
will be red.
And once you arrive at this traffic light, it will go green and you can just go now because
the traffic light knows there's no one around.
And every time I go there, I'm like, ah, this is so amazing.
And then I go back to France and I get to a traffic light that is red and I look everywhere
and there's no one in sight.
No pedestrian, no bike lanes.
Oh, well, there are no bike lanes and no other cars.
I'm like, why am I waiting?
And just being able to have a green light right away would improve traffic for sure
because people don't stop for nothing.
You don't have a large lane of cars just waiting for this red light.
And the people, at least in France, I don't think they know how bad they have it because
they haven't seen, they haven't been to the Netherlands.
When they have, they go there for bad reasons like French tourists.
Right, right.
And yeah, I think for typescript, it's the same.
Like if you go to Elm, you won't have the same type system.
It will be a much nicer one.
Limiting, potentially, but much nicer.
Side effects, not an issue, but you don't know how bad you have it when you have that.
So trade-offs everywhere, but sometimes the results are very, very nice.
And I think it would be nice for people to try out those things.
And by the way, go to the Netherlands.
It's a nice place.
Yes, I definitely will.
But don't take the plane too much.
I mean, it's definitely, you kind of buy into a way of working and thinking.
And I find it really interesting.
My time as a coach, doing my coaching work really influenced me on this as well, of how
much somebody's mental model of something can influence the way they interpret what's
going on.
So for example, like a lot of my coaching work, I was trying to get teams not being
blocked by things, not being blocked by needing things from other teams, but being empowered
to work on things on their own and being able to ship things all within one team and being
able to deploy something with the push of a button.
But if you're perceiving things as being more efficient by another team working on something,
then you're going to interpret the pain points around that in a different light.
Whereas if you perceive the pain of fitting pieces together, where two different teams
built something and now you go to integrate those two pieces and they don't work, or these
two systems don't understand each other, or they have a very heavy handed contract with
each other because it's not people operating within the same context, or you're going to
ship something and you have five months of work that you're going to spend one month
You're going to perceive that very differently if you have a mental model that says, well,
let's be efficient with our testing.
We have to manually test this, so let's be efficient by batching everything up.
We don't want to ship something today and then have to go test the whole app.
That would be inefficient.
Well, if that's your mental model of things, then it is going to look inefficient.
But if you have a different mental model, then you look at it as the more we batch things
up, the more that can break at once.
And the more we've lost context from the thing that we've worked on to know what we're looking
And the less we've automated testing things and the less confident we can be about our
deploy process and the less we automate our deploy.
So looking at it through different lenses totally transforms the way that you see it.
I think it's the same with looking at the tradeoffs of Elm versus TypeScript.
If you're looking at it as the value of guarantees versus the inconvenience of having to pass
through side effects explicitly, not being able to trigger them from anywhere, the hindrance
that that causes you, you're going to perceive it very differently.
And I think some people just have a different mental model and a different preference fundamentally.
And I think that's fine.
But for those who, I mean, my bottom line is if you make a set of tradeoffs, then cash
in the good things from those tradeoffs.
You've paid the cost of making the sacrifices of the cons of that tradeoff.
So get all the pros from that tradeoff that you can.
And right.
But you need to know which tradeoffs you made.
If you only know JavaScript, what are the tradeoffs of JavaScript compared to other
Like where does it shine?
And I mean, I think, I mean, I've heard a lot of people say that try Elm out, you'll
learn something even if you end up not using it in your production stack.
So I definitely think it's a good learning experience for people to try it out regardless
of whether they end up using it.
It's interesting because when you say, tell people how to write good code, it's usually
like stay simple, write good names and just use simple functions.
That in practice, that's what it boils down to.
Like keep codes very simple.
Keep it stupid, simple, silly, simple, silly.
Is that stupid?
Usually people say keep it simple, stupid.
I was just being silly.
Well, I mean, it's maybe a less offensive one.
Not the one that I had heard at least.
I mean, in practice, like if you want to go towards better and simple code, you go to
words code that it looks like Elm and Elm just makes that the default.
Also like the only thing you can do.
So we might feel like a limitation, but in practice, like, yeah, it's just good code
because that's what good code tends to words.
I mean, I definitely am convinced personally, my, like all of the things that I've learned
about what makes a code base maintainable are very aligned with Elm and happen very
naturally with Elm.
Making code traceable, you know, decoupling things, inversion of control, all these types
of practices.
It's very natural with Elm.
Also like it's hard to imagine with how core parse don't validate and these types of principles
make impossible states impossible are to how I think about writing good code and fixing
bugs and keeping them fixed.
I don't think I could go back.
I don't know, I don't know how I would write code without tools in my tool belt that make
it really easy to do that.
And when I, when I'm writing TypeScript personally, I honestly don't do that much of things like
parse don't validate and make impossible states impossible.
It's just cumbersome and I don't really get the full guarantee.
So it feels like, why am I bending over backwards to make discriminated unions that like, I
can't really trust.
It feels like it's going against the grain of how the whole ecosystem is working that
I'm using.
On top of that, it's also like, there's this distraction or there's this temptation, this
little devil telling you like, Oh, Hey, this could be much simpler if you just mutate this
Like, and potentially for good reason, because also like can be more performance.
But there's always this temptation to write code in a, not a nice way.
That is, I just find distracting and sometimes I get tempted in practice to do that.
And that's how my code turns out.
And that will, or the might create problems, but you don't have that in Elm.
And that feels just nice.
Like it's not an option.
Stop thinking about it.
Just write the good code from the start.
And if it's not great, then you can refactor it because refactoring is safe.
It feels good.
Little angels everywhere.
And it just, it really does feel like Elm takes it a step further, you know, like something
like Haskell or pure script.
Like I've never felt that drawn to, to some of these other languages, because again, there's
just like Elm really makes this hard choice of like not having escape patches and having
pure functions and exhaustive case checks and all these things that are, it's just like
airtight at the core.
Like all of its core decisions are made around being airtight and then having pragmatic APIs
that are focused, like making, you know, which maybe somebody who's really big into Haskell
would say, well, yeah, but you're missing out on the power of a lot of things that type
systems can provide to you.
And you're missing out on some of the ease that you have from things like type classes
and stuff.
And there, there are definitely trade-offs there.
There are definitely valuable things that come from that.
But Elm, it goes all in on saying no escape patches.
It's an airtight system that you can completely trace and understand pure functions all the
way, and let's be pragmatic and talk about things in more domain terms than category
theory terms or things like that.
And to me, that just really resonates like that, that that's my love language, just like
speaking in domain language and simple, understandable, traceable code that you know exactly what
it does and its pure functions.
Like it just works for me at the core.
And Elm does that in a way that I think is very unique.
And I think I definitely am keen to see what Richard Feldman's project Rock does.
I think that like he is kind of bringing a similar ethos to a different context and more,
you know, more of a sort of the types of things you would do with Rust back end, more performance
focused projects.
But I think he's bringing a similar ethos there that I'm very keen to see what he does
I think that will pull up my heartstrings as well.
Yeah, I'm looking forward to playing with it more as well.
And I really hope they don't make any choices that go counter to what we like about Elm,
the large parts.
From everything I've seen so far, it has.
But yeah, I agree.
Yeah, we kind of mentioned like it's about pushing Elm to its limits.
But as a tooling author, it's also just simply intellectually fun to see how far you can
push it.
For instance, I had a lot of fun making pull requests to Elm Optimize Level 2.
Yeah, to make things even faster, but relying on the fact that it's Elm codes that I'm optimizing.
Right, right.
You can do isomorphic things with Elm code because if it can give you the same result
and it's pure, so it's so easy to swap it out for something else that does the same
thing, then you can do whatever dirty tricks you want.
Yeah, yeah, exactly.
Yeah, also like Tail Recursion module concept I worked on that I made blog posts about,
because it's still Elm, but now the compiler can change the resulting source code, the
resulting JavaScript in a way that is more optimized.
And that would unlock some ways of running Elm code that are currently like not stack
safe or something.
That would be amazing.
Is that a feature for the language or is it just like optimization?
That's a good question.
Stack safety is a feature.
Yeah, it's borderline.
It's still Elm, but...
I mean, put it this way, if Elm didn't have tail call optimization, then certain use cases
wouldn't be possible.
And being able to make a guarantee about that is definitely compelling.
So yeah, I think in conclusion, like Elm is just such a nice bundle of features that are
put together in a very nice and polished way.
The fact that it doesn't crash, the fact that its language is super simple and teachable,
compared to Haskell for instance, the fact that the resulting code is good code and maintainable
code and that you can have tools around it that are just so powerful that just make so
much good use of all the guarantees that the language gives you and the compiler gives
And I'm sure I'm forgetting more things, but it's just such a dense, small, little language
that is with so much good in it.
It's just super enjoyable.
And a community of inspiring people who believe in that stuff too, which is really cool, you
know, and who pull up their sleeves and try to build cool things with it.
Yeah, I really like the ethos of the community, like everyone trying to make good stuff.
Yeah, and just the quality of the average Elm package is pretty impressive.
Yeah, so that's why we care about Elm.
Well, this was a fun trip down memory lane.
And perhaps you're a superhero trying to build cool static analysis and I'm a super villain
trying to destroy all mocking in the universe.
Mock man!
I'm one step closer.
Well Jeroen, until next time.
Until next time.