DEV Community

Discussion on: What simple things annoy you about your favourite programming languages?

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

Using both Elm and F#. Here are a few things that irk me.

  • Hazardous generics
    Elm : Result SomeErrorType SomeType
    F# : Result<SomeType, SomeErrorType> - The sharp angles cut me

  • Elm union types do not allow an optional leading |, which makes the first one a pain to copy/paste, diff, etc. (Maybe implemented soon.)

    -- Elm
    type SomeUnion
        = FooCase -- merge conflict waiting to happen
        | BarCase
Enter fullscreen mode Exit fullscreen mode
    // F#
    type SomeUnion =
        | FooCase
        | BarCase
Enter fullscreen mode Exit fullscreen mode
  • F# let syntax is nicer to use. Elm let statements require an in clause whereas it is optional/implicit in F#. Additionally, elm-format always expands let statements to multi-line. The visually-enormous resulting code leads you to want to avoid let in Elm.
    -- Elm
    let
        asdf =
            oneLiner x

        fdsa =
            anotherOneLiner y

    in
        f asdf fdsa
Enter fullscreen mode Exit fullscreen mode
    // F# - easier to read IMO
    let asdf = oneLiner x
    let fdsa = anotherOneLiner y
    f asdf fdsa
Enter fullscreen mode Exit fullscreen mode
  • Elm generates curried constructors for all record and union types. Curried constructors are great because they support partial application. F# does not, and the normal record construction syntax is quite verbose. I often create my own curried constructor for partial application.
    -- Elm
    type alias SomeType =
        { someInt : Int
        , someString : String
        , someFloat : Float
        }

    -- automatic curried constructor
    let x = SomeType 1 "foo" 3.14 in ...

    let list = List.map ( SomeType 1 "foo" ) [ 3.14, 2.718 ] in ...
Enter fullscreen mode Exit fullscreen mode
    // F#
    type SomeType =
        { SomeInt : int
          SomeString : string
          SomeFloat : double
        }

    // make my own curried constructor
    let mkSomeType a b c =
        { SomeInt = a; SomeString = b; SomeFloat = c }

    let x = mkSomeType 1 "foo" 3.14

    let list = List.map ( mkSomeType 1 "foo" ) [ 3.14; 2.718 ]
Enter fullscreen mode Exit fullscreen mode

Here is what the last two lines would look like in C#.

    var x = new SomeType(1, "foo", 3.14);

    var arr =
        new double[] { 3.14, 2.718 }
            .Select(x => new SomeType(1, "foo", x))
            .ToArray();
Enter fullscreen mode Exit fullscreen mode