1. 13
  1.  

  2. 4

    This is cool but more and more I wish functional languages would have a standard library trait/typeclass called something like FromLiteral, with the signature FromLiteral a => String -> Result a.

    Then, if you had a string literal in your code but the compiler infers it should be a Regex, it calls the FromLiteral implementation for Regex at compile time, and either rewrites the generated program with the successful output, or throws an error.

    1. 4

      Bit irritating how Elm forces you to go into an infinite loop (fromLiteral string = fromLiteral string) instead of letting you crash with a nice error in the impossible case with the old Debug.crash. (That’s Debug.todo since Elm 0.19, and is only permitted if you compile in debug mode.)

      I suppose one might define and use

      impossible : a -> a
      impossible x = impossible x
      

      in those spots as a means of documentation.

      Somewhat relatedly, I find Elm’s insistance on not allowing “unsafe” operations to lead to obfuscation of failure cases. E.g., it’s common to have a catch-all case in your update function that just silently discards unexpected message combinations:

      update : Msg -> Model -> Model
      update msg model = case (msg, model.state) of
          -- handle expected combinations
          ...
          -- ignore impossible combinations
          _ -> model
          -- instead of the more helpful
          -- Debug.crash <| "unexpected message/state combination: "
              ++ Debug.toString msg ++ ", " ++ Debug.toString model.state
      
      1. 1

        You don’t have to discard invalid states in the catch-all clause silently though. You could still send them to an error-reporting service, for example (although not in the specific case you show - you’d have to use something other than Browser.sandbox).

      2. 2

        I wonder how this contrasts with later-binding techniques like E-style auditors. Both systems walk an AST and examine whether an expression fulfills a contract; elm-review certifies modules, while E-style auditors certify objects.

        It seems that the biggest difference is that elm-review is optional; it is possible to forget to run the tool. In contrast, E-style auditors are not skippable, but must be executed at runtime. The other big difference is that elm-review is policy chosen unilaterally by the code reviewer and applied evenly over the entire source tree, while E-style auditors are chosen by contract with consenting objects and only applied at each annotated object construction site.