elm / compiler

Compiler for Elm, a functional language for reliable webapps.
https://elm-lang.org/
BSD 3-Clause "New" or "Revised" License
7.48k stars 658 forks source link

Dot notation for "Methods" #2282

Open Anderssorby opened 1 year ago

Anderssorby commented 1 year ago

I think adding a function "method" dot notation would simplify expressions and ease adaptation for JS-developers. Lean4 is purely functional, but also has support for .dot notation for associated functions. https://leanprover.github.io/lean4/doc/namespaces.html I think this should be added to Elm too.

Example

type alias A =
    { b: String }
-- this is possible
getB = .b
-- A new possibility to add functions to the type "namespace"
A.doStuff : A -> B -> C
A.doStuff self b = c

-- This could also be possible
fun : A -> B -> C
fun a = a.doStuff

f : Maybe a -> b
f m = m.map (\a -> a.stuff) |> .withDefault defaultB
github-actions[bot] commented 1 year ago

Thanks for reporting this! To set expectations:

Finally, please be patient with the core team. They are trying their best with limited resources.

lucamug commented 1 year ago

Some discussion here: https://discourse.elm-lang.org/t/dot-notation-for-methods/8727

turboMaCk commented 1 year ago

I did not read the discussion on discourse so apologizes if I'm repeating something from there.

With this proposal I wonder what you would expect for this code to produce:

adding_one t =
  t.map (\a -> a + 1)

My take

I can imagine primarily 2 expected results... ### Ad-hoc Polymorphism This code should compile and work so that I can call: ```elm adding_one (Just 1) --> Just 2 adding_one [1, 2, 3] --> [2, 3, 4] ``` Anyway as you can see this introduces new type of polymorphism which is currently not possible in elm. The type would be something like: ```elm adding_one : f Int -> f Int ``` where `f` is of kind `kind f = Type -> Type` ### This Code should be rejected Compiler should error with something `can't specialize f in ...` prohibiting you from using this feature in this way. In such case you would need to somehow specify which type does `t` have like: ```elm adding_one : Maybe Int -> Maybe Int ``` Anyway as you can see this syntax would break type inference in a way it would no longer be possible to infer type without this annotation. Also in my opinion this makes whole feature kind of useless. It would make `.` just an alternative syntax `|>` which is also ambiguous. This code which is already possible at the moment doesn't have this problem and provides exactly the same capabilities: ```elm adding_one f = f |> Maybe.map ((+) 1) ```