Hacker News new | past | comments | ask | show | jobs | submit login

I am a back-end developer, and I don't know front-end. I also know very little of functional programming.

Elm is the only language that I like writing, and where I don't feel in a state of frustration when I write. It might have a lot of limitations, bu tit makes me happy. Given that our job is basically to be in a constant state of half broken code, this makes me a huge fan of the language.




    our job is basically to be in a constant state of half broken code
In my experience, Elm code is only ever in a state of "horribly broken, won't compile" or "works". Whether that's a bug or a feature depends on what I'm trying to do...


That's interesting. How does Elm statically know if the logic of your app is correct? Since I don't know Elm I'll use some pseudocode:

  if condition
    pourCoffee()
  else
    pourTea()
Is Elm able to determine that this condition is flipped the wrong way?


Neither Elm, nor any language in the Typed FP family, can do that. What it can do is to prevent us from making clerical mistakes. That's the surprising thing I learned programming in Typed FP: we very rarely make logical mistakes. Our programs are all broken, make no mistake, but they are broken not because we accidentally swapped a conditional (logical mistake), but rather because we passed in data of the wrong shape (clerical mistake).

A common clerical mistake which Elm, Reason etc. prevents, is when we grab something from a list and pass it to another function. What if in a rare case it is possible that the element doesn't exist? A function deeper in the stack might crash, or if defensively built, substitute it with an empty value. Both could be wrong.

By providing more information about our data and our functions to the compiler, the compiler can ensure our code always follow those constraints. These constraints are often in our head when using dynamically typed languages, or even statically typed OO languages. Typed FP helps us make them explicit in code so the compiler can track it instead of we tiring ourselves mentally and making a mess of it.


Expanding slightly, Elm (as well as others in this family), can create structures that assert certain rules. In the case of a list being empty, you can also use ADTs to create nonempty version ala `type NonemptyList a = NonemptyList a (List a)` where it's impossible to construct without that first element even if the second list is empty. A lot of languages lack this sort of feature. Then you can go about your code knowing you neither have to handle empty nor write a bunch of tests because empty construction is impossible and this is enforced by the compiler.


Sometimes I wonder whether Alan Perlis would mock at us for being Bible salesmen for Typed FP languages.. yet it is such a quality-of-life upgrade and a thinking tool that it feels justified to shout from the rooftops :)


> These constraints are often in our head when using dynamically typed languages, or even statically typed OO languages.

I’m curious about this comment on statically typed OO languages. I work mainly with C# and don’t have much FP experience. Are you referring to exhaustive matching?

Edit: To clarify, I understand that C# compiler won’t prevent you from trying to access an element in an empty collection. What prevents you, in a typed FP language, from accessing head of an empty list?


Yes I was thinking of a couple of things, but most importantly the existence of null in the language. So functions either receive exactly the type they were looking for (which is better than dynamically typed), or a null (which never happens in a Typed FP language).

In OCaml, (List.hd []) throws an exception, which is not a desirably behaviour, so we mostly use a safer version of List.hd which would return an option type. This could be either "None" or "Some(value)". To operate on option types, we have to pattern match and handle both cases where the value could be either None or Some)

Exhaustive pattern matching is useful here, so is the very notion of variants. Without variants (or sum type / union type) we tend to leave domain concepts implicit in the codebase. While we can simulate variants with classes, it is too unwieldy to be used except for core domain concepts.


Got it, thanks!


Just want to give props. This is the clearest explanation of the value of typed FP I've ever seen.


:)


> Neither Elm, nor any language in the Typed FP family, can do that.

I didn't think so. So claims like:

> In my experience, Elm code is only ever in a state of "horribly broken, won't compile" or "works".

Which I find to be pretty common among fans of strongly typed functional languages, is incorrect.


Elm makes no claims to correct your logic. Logical errors are not caught by the compiler. You might still decode a JSON field to the wrong field on a Record (if the fields are the same type), you might invert a BOOL and use True were you meant False, you might incorrectly calculate some value, etc.

But, state errors are caught – your application can not get into an impossible state and therefore should never have any runtime errors.

Getting back to logical errors – Elm can provide some additional safeguards. For example you could have a record

``` type alias Point = { x: Int, y: Int } ```

and then decode it with

``` decode.map2 Point (field "y" int) (field "x" int) ```

Whoops you got the wrong order.

So you could make X and Y explicit types:

``` type alias Point = { x: PointX, y: PointY } type PointX = PointX Int type PointY = PointY Int decode.map2 Point (field "x" decodeX) (field "y" decodeY) ```

Now your decoder won't compile unless the types line up correctly. But this adds a bit of extra overhead in unwrapping the values, but not much.


Yes, because in elm everything is pure. At least in the code you write. Elm will force you to declare all possible cases that can happen, all branches in every function you write. That leaves literally nothing to break.

Not saying you can't break an elm program. But you won't run into runtime exceptions in elm, by design:)


This has been my experience, 100%.




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

Search: