DEV Community

How I (Finally) Built an App in Elm

Ali Spittel on November 22, 2017

Two years ago, I was asked by a company I was working for to learn Elm — a functional front-end programming language. I found the syntax strange an...
Collapse
 
lucretius profile image
Robert Lippens

So much this - I think I've tried to dig into Elm three or four times now, over the course of several years. I love the ideas behind it, and the guarantees it provides. I thought after getting heavily into functional-style JavaScript programming the transition would be easier but it was always difficult.

I want to like it, but I'd take TypeScript's semi type-safety over Elm any time.

Collapse
 
levi_donaldson profile image
Levi Donaldson

This is how I feel. I understand the performance boosts in the final products but the process of building and typing out all of the [ ][ ] in code just cripples me. I really love the idea of functional programming, it just seems to run circles around OOP, but the syntax is absolutely awful and as a person who specializes in CSS this is the greatest downfall. My experience with CSS in elm has not been good. I wish there was a lot more info and tutorials about it. If it had the same type of hype and following as Vue (which just feels good) I think more would be done with it.

I do have to say though that a truly remarkable project is Dscova.com I really wish these guys would put more information out in actual code so we could learn how to build things as good as this.

Collapse
 
euler2718 profile image
John Corley

Js functional style really doesn't feel the same for a variety of reasons...I think no matter how good you get at it. Elm/purescript a lot closer to Haskell. So if you are trying to learn that style, go for it. That being said, elm has so many breaking changes even today, that using in production beware.

Collapse
 
jess profile image
Jess Lee

I love this walkthrough -- definitely something I'll be referring back to if I ever take a stab at Elm.

Collapse
 
ozgurodun profile image
Özgür Dinç

Thanks for the article i really liked it :D
I started using Elm 0.18. In the process i got used to functional coding. I really like the compiler errors but still hate the documentation of elm packages. I think the documentation is not updated(some packages updated but not their documentation) and not complete(eg. http v1.0.0 package).
Being a new language creates lack of examples and most examples are for older versions of Elm. And because Elm is still in like alpha development(0.18) features change dramatically. This causes the examples found on net are not 100% compatible with the version used.
All in all Elm is a good and fun language but using it for a live project is a hard decision to take. I believe ELm will grow and be a very nice language for frontend.

Collapse
 
aspittel profile image
Ali Spittel

Yeah, the packages are really rough to deal with from what I noticed! I was trying to use a random number generator package and I couldn't get it to work!

Collapse
 
mrmurphy profile image
Murphy Randle

I think the ideal would be a combination of JS style docs, where most of the documentation for a lot of libraries is in the README with a few examples, and the Haskell style, where types are often all you're given.

I found that as I got better at reading type signatures, I much much much preferred Elm's package repository and documentation to what can normally be found on NPM, but that was totally because I learned to read the type signatures (which took practice).

As much as I love having type signatures in the documentation, the presence of helpful types in Elm's package documentation can make it more difficult for package authors to remember to write out good examples. And examples are definitely needed in many cases to make sense of how the libraries are intended to be used. That's a way in which the community can improve.

Collapse
 
carstenk_dev profile image
Carsten

I know it can be hard but if you are interested just have a look in elm-slack - I'm sure you'll find people helping you get over the first blockers.

Just to give you some outlook: the little snippet you gave can be written as

currentQuestion : Maybe Question -> Question
currentQuestion = 
    Maybe.withDefault
        { question = ""
        , answers = []
        , correctAnswer = ""
        }

and you can find many of these little things that makes your life easier here package.elm-lang.org/packages/elm-...

You'll probably not believe me but it's really a lot easier than react/redux and quite safer too

Collapse
 
aspittel profile image
Ali Spittel

Awesome, thanks! I think it depends on the developer -- for me I've been a React/Redux dev for a couple years professionally so it is much easier!

Collapse
 
jvarness profile image
Jake Varness

I've always thought that Elm was an excellent programming language! Strong type safety, helpful compiler messages, good community, great tools! What more could you ask for in a programming language?

In 32 lines or less of code I was able to write a crappy little app with horrible styling that communicated with Github's REST API to check how many followers a user has. It's not impressive by any stretch of the imagination, but the power you have with relatively little code is awesome!

Collapse
 
aspittel profile image
Ali Spittel

Ah cool! I definitely think it depends on the project and which data structures you need for it!

Collapse
 
ben profile image
Ben Halpern

Really honest take. Great great post.

Collapse
 
eljayadobe profile image
Eljay-Adobe

Great article!

What version of Elm?

I see the current version is 0.18, which has undergone a significant amount of change since I originally looked at Elm.

For example, I was surprised to find out Elm got rid of FRP when 0.17 came out.

For those who are considering Elm for anything, one big caveat is that Elm is undergoing rapid evolution from release-to-release. It's both a good thing, and bother to absorb those changes.

Collapse
 
aspittel profile image
Ali Spittel

I used the current version for this! I definitely agree -- I kept finding libraries that were now incompatible.

Collapse
 
jjunqueira profile image
Joshua Junqueira

Great post I can totally relate!

I think It can be difficult to learn functional programming because a lot of time people are also learning advanced statically-typed functional programming. So they are really learning two things at once: Functional programming, and an advanced type system. Elm isn’t super advanced when compared to something like Haskell however it is still a massive change from JavaScript or python.

I think of learning functional programming like the experience of learning to program for the first time rather than the experience learning a new programming language. It takes a lot of time and dedication but I think it pays off in the end.

Collapse
 
aspittel profile image
Ali Spittel

Yeah! I have quite a bit of Java and C++ experience, so that wasn't really the worst part for me, but I can see that for a lot of people. The most I use FP in my day to day is React and Redux -- I don't use FP for work so this was just a quick side project!

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

It took me a couple of tries at F# (my first FP language, similar to Elm) before I could write in it, and a bit longer before I was writing using functional idioms. So don't feel bad. Elm (and FP)'s learning curve is harder compared to something like JavaScript, but it is worth learning. This is kinda the way I look at it in graphs.

Writing your first pure JS app is about like this. Super easy to start, but increasingly hard to recover from mistakes.
x squared graph

Writing your first Elm app is kinda like this (assuming no prior FP knowledge). Pretty hard to get started... maybe even have to "unlearn" some habits. But recovering from beginner mistakes (or changing requirements) is not particularly hard. Just normal work.
log x graph

Also note that there are built-in helpers for Maybe. Totally optional to use, but a little shorter.

blankQuestion =
    { question = ""
    , answers = []
    , correctAnswer = ""
    }

currentQuestion : Maybe Question -> Question
currentQuestion possibleQuestion =
    Maybe.withDefault blankQuestion possibleQuestion

-- or if you prefer

currentQuestion possibleQuestion =
    possibleQuestion |> Maybe.withDefault blankQuestion
Enter fullscreen mode Exit fullscreen mode

We use Elm in production, and I am very happy with that choice. In fact, we trained two devs without prior professional experience (but with CS education) to use Elm. They were writing in it after a couple of weeks and doing features after a month. I think immersion and going through the learning process with others helps. After 1 month, this was obviously not the greatest Elm/FP code, but Elm is quite amenable to refactoring once you learn a better way.

Collapse
 
aspittel profile image
Ali Spittel

Ah okay! I gave myself probably around 10 hours in total -- I'm not learning it for a job so it makes it harder to justify a huge time commitment! I do have Redux experience, though this was my first fully functional language. I was just proud that I had something working at the end! Maybe someday I will have more time to commit to learning FP more fully!

Collapse
 
eljayadobe profile image
Eljay-Adobe

If you do get to the point that you want to make another attempt at an FP language, and you have some interest in .NET, then I highly recommend F# and The Book of F# by Dave Fancher.

F# is essentially OCaml for .NET, created by Don Syme of Microsoft Research Cambridge.

Unlike Elm, it isn't a pure FP language. (To be a first-class .NET language, it has to support .NET's OO paradigm.) But like Elm, it puts FP front-and-center.

Collapse
 
heikodudzus profile image
Heiko Dudzus • Edited

I agree, just returning a value in a Maybe and then getting the value out of the Maybe functor by pattern matching via 'case' is clunky. That's not what Maybe is invented for.

The Maybe type can, in fact, reduce clunkiness of the code. But only if you are using it as (Applicative) Functor or Monad to propagate the failure transparently through some other part of your code.

As an example, in one of my projects, I have a function 'intersection' that computes a point of intersection for two given line segments. Two line segments can have an intersection, but need not to have. So using Maybe seems good.

intersection :: LineSeg -> LineSeg -> Maybe Point

In the further code, there is a function 'triangle' that takes three Points and returns the corresponding Triangle:

triangle :: Point -> Point -> Point -> Triangle

As you can guess, the program will at some point compute the Triangle built by three line segments. And this is where Maybe begins to shine:

triangleABC = triangle <$> intersection a b <*> intersection a c <*> intersection b c

You see what happend here: The triangle function was written for Points that really exist. But I have applied it to intersection points that maybe exist but maybe not! I could do so, because I used Maybe as Applicative Functor.

Of course, if any of the three intersections doesn't exist, triangleABC is Nothing. If they all three exist, triangle ABC is in a Just. Maybe reduces the need for clunky case analysis, but only if you really use it as Applicative Functor or Monad, that helps you to propagate Maybe data through your code. Otherwise it makes the code clunky, yes.

You can build bigger structures of 'Maybe Triangle's. The point is: You can write your code without having to think about (and deal with) the annyoing failures, you can concentrate on the cases where all is good, like I have done with my function 'triangle'.

I wanted to share some real code examples regarding Maybe, but it is better explained in full length here: learnyouahaskell.com/functors-appl... and here: learnyouahaskell.com/a-fistful-of-...

Edit: <$> seems to be <~ in Elm and <*> is ~
See the example in elm-lang.org/blog/announce/0.7

Collapse
 
thedanishdynamo profile image
Thomas Nielsen

I'm always puzzled why languages emerge and evolve, so far the only explanation is the Babel story in the Bible, it's meant to stop people from communicating because they try to build towers. Elm is a definitively maybe, sounds like it's going to rot.

Collapse
 
annarankin profile image
Anna Rankin

This is great! I've been meaning to try out Elm for a while since I took a tiny workshop on it at a conference - I'm interested to see if I run into the same feels/issues/other things that you did!

Thanks Ali! 💯💯💯

Collapse
 
jasongabler profile image
Jason Gabler

I am very curious to know why that company asked you to do work specifically in Elm. Would you please share that, and what framework you ended up developing with instead of Elm for that project?

As a student I found FP interesting as a computer science concept, but I had never imagined why anyone would use any (pure) FP language for a commercial purpose.

Collapse
 
euler2718 profile image
John Corley

Sounds like a lot of your issues may be around FP concepts in general?

For instance, do you dislike Haskell? Would Idris drive you crazy?

Collapse
 
rwoodnz profile image
Richard Wood

Ali. Keep trying it again! I've kept coming back to it because of my conviction that Functional Programming skills will improve my programming whatever language I develop in.

Collapse
 
aspittel profile image
Ali Spittel

I've been doing a bunch of FP in JavaScript recently, and I love it there! Just don't think I love a fully functional language (or the syntax of it!)

Collapse
 
euler2718 profile image
John Corley

The syntax or the concepts?
I feel like a lot of it just extends from lambda calc. There are definitely differences syntactically amongst for langs....just look at erlang and compare it to elm.

Collapse
 
aadeshere1 profile image
Aadesh Shrestha

Good read Ali.

Collapse
 
josephthecoder profile image
Joseph Stevens

Keep trying to learn new things! Good on ya 😀

Collapse
 
k4ml profile image
Kamal Mustafa

I try to learn Elm too in the past. Look like after a year, I didn't manage to proceed into part 2 - k4ml.me/learning-elm-part-1/.