How to bring Elm's safety to Haskell?

I’m sorry if this is not the right place to ask.

Hi, you might need to provide a little more information if you would like some help :slight_smile: What do you mean by ‘safety’? How is it missing in Haskell?

I don’t know much of Haskell, but probably only use total functions, that do not throw exceptions

Thank you for your reply. I want to have “no runtime exception” like Elm in Haskell. Reading some introductions showed that you can have runtime error in Haskell.

Thank you for your reply. So how to find these functions?

I wouldn’t want to point you in the wrong directions since I’m not practicing Haskell (only had a brief introduction). But I am pretty sure every function that may thow in an obvious manner (like head, tail for lists etc.) have a safe counterpart. Sorry cannot help much, I’d say google is your friend :wink:

Safety in haskell is tricky. Even if your own code is safe, code you use could throw errors.
This is primarily because of:

  • historic choices (e.g. Data.List.head will throw on an empty list)
  • more trust in the programmer (if you want to use error/undefined, you can; you want partial functions, sure)
  • haskell touches the real world more directly - elm always has the browser for some buffering. File interactions for instance may fail and throw errors.

What I do in my own code is:

  • use/define total functions for list, assume functions that give only “part” of a list will throw when given the empty list (head, last, init, tail).

  • turn on warnings for incomplete pattern matches (using -fwarn-incomplete-patterns, you can set this globally in your project’s cabal file)

It’s also possible to use a custom prelude (custom set of default imports). this article shows how that works and what it changes. I haven’t yet tried this but it seems very good. It adds a bunch of extra warnings and makes the safe list functions the default.

So, haskell relies more on programmer discipline to enforce safety, but there are some steps that you can take to make the experience slightly nicer.

4 Likes

No problem. Thank you :smile:

Thank you for your advices.

By the way, all Elm core functions should be safe right. Any packages like these in Haskell?

that is what the custom preludes do.

Having it just be a package means that

  • the default ones are still there
  • you always have to qualify the functions, because the defaults are still there

So instead you can have GHC load a different set of default functions, a custom prelude.
The protolude I linked seems a solid choice.

2 Likes

I see. Thank you very much!

no need to worry about this as much in elm. there are no partial or unsafe functions in elm’s core packages :slightly_smiling_face:

Thank you for your reply.

Ah yes. What i mean is are there any packages in Haskell that like Elm’s core packages? I want to feel safety in Haskell just like when i’m in Elm

If you’re interested in just things like safe functions on Lists have a look https://hackage.haskell.org/package/safe Otherwise there are many competing approaches to make Haskell safer but I’m not expert so I’ll leave those to someone else.

Ah thank you :smile:

Also if you want to go deeper into type-safety this is a nice article about less obvious unsafe things https://www.fpcomplete.com/blog/2018/01/weakly-typed-haskell and almost tutorial how to design typesafe APIs.

Elm actually is quite capable of throwing runtime exceptions. For example:

Equality comparison, for example, can throw if it eventually finds itself needing to compare functions. The Haskell-style solution to this would be to have an equatable typeclass or pseudo-typeclass a la comparable.

The compiler is too lenient with respect to cyclic data structures —in part to enable things like recursive decoders —and that lenience can lead to runtime exceptions.

And then there are assorted bugs that can lead to runtime exceptions —e.g., there are issues in the virtual DOM with sending malformed messages. I would sort of accept that software is rarely perfect but given how long these linger in the main release one has to consider whether preventing runtime exceptions is a high priority.

This is not to dismiss the benefits Elm brings to bear in reducing runtime errors compared to say JavaScript, but to attach a little bit of realism to the “no runtime errors” advertising claims.

Mark

4 Likes

Once again thank you.

You’re right. Fortunately the claims still true for me.

The problem with runtime exceptions in elm (due to bugs, almost nothing is necessary by design (maybe beside == on functions (or things containing functions) and Regex.regex) is that when you encountered them for the first time you have no idea what is wrong and how to fix it. In case of some, you might even have no idea that the issue is there because it happens only with some type of input or in some browser. Frankly, I had much more production issues because of the elm unsafety than because of the Haskel’s but also frontend our team is working on is much much more complicated than backend so it’s definitely not representative. Anyway, I believe the thing Marks is trying to say is that It’s always better to express your love for one piece of tech without picking on another especially when your arguments are kind of false:

Thank you for your reply. I want to have “no runtime exception” like Elm in Haskell. Reading some introductions showed that you can have runtime error in Haskell.

^ I would love to have no runtime exceptions in Elm as well. But they are there. Do I blame anyone - no. It’s not that easy to make perfect software (we should all lear Coq maybe :rofl:).

Reading some introductions

People are different and has different values. This is an important part to me. My conclusion would be haskell shows there are unsafe finctions in introduction. On the other hand as Mark said well imho:

to attach a little bit of realism to the “no runtime errors” advertising claims.

I would sort of accept that software is rarely perfect but given how long these linger in the main release one has to consider whether preventing runtime exceptions is a high priority.

I’m not trying to pick on a technology you or anyone else but frankly one of the things I value highly is honesty and somehow I kind of dislike whole “you’re not allowed to talk about issues” mindset. If you like elm you will probably like it even after first weird runtime exception. But you were promised not to have them. And they will stay with you for a long time.

I really hope it doesn’t sound offensive to anyone. I’m only trying to express my view which might be slightly different from views of other - hopefully, someone finds it at least acceptable opinion). Sorry for OT.