Compiler: Cannot use pattern matching in function definition

Created on 30 Jun 2015  路  4Comments  路  Source: elm/compiler

lines _ _ 0 = []
lines [] _ _ = []
lines (x::xs) (y::ys) i = line x y i :: lines xs ys (i-1)

Error:
Name Collision: There can only be one definition of 'lines'.

Is this intentional? Can we add functionality to the compiler to desugar this, or should it stay the same?

Most helpful comment

Yep, unlike Haskell we do not allow you to define functions across many lines. A case expression is preferred.

There used to be a nice Haskell wiki that explained the cons of defining things this way, but they changed the recommendation for some reason. The short version is that it does not scale well in production code. I had some of these in elm-compiler and it always turned bad. Adding a single variable requires a modification to every line. You also end up naming the same variables tons of times in more complex cases.

I also prefer not to add redundant syntax at this point. It is expressible another way. If you follow the style guide (which talks more about the philosophy behind my syntax choices) it'd be like this:

zipLines n lines1 lines2 =
  if n <= 0 then
    []
  else
    case (lines1, lines2) of
      (x::xs, y::ys) ->
        line x y i :: zipLines (n-1) xs ys

      (_, _) ->
        []

The overall idea is that in certain settings it is worth it to buy regularity of code at the cost of vertical lines.

All 4 comments

Yep, unlike Haskell we do not allow you to define functions across many lines. A case expression is preferred.

There used to be a nice Haskell wiki that explained the cons of defining things this way, but they changed the recommendation for some reason. The short version is that it does not scale well in production code. I had some of these in elm-compiler and it always turned bad. Adding a single variable requires a modification to every line. You also end up naming the same variables tons of times in more complex cases.

I also prefer not to add redundant syntax at this point. It is expressible another way. If you follow the style guide (which talks more about the philosophy behind my syntax choices) it'd be like this:

zipLines n lines1 lines2 =
  if n <= 0 then
    []
  else
    case (lines1, lines2) of
      (x::xs, y::ys) ->
        line x y i :: zipLines (n-1) xs ys

      (_, _) ->
        []

The overall idea is that in certain settings it is worth it to buy regularity of code at the cost of vertical lines.

Alright, thanks for explaining.

I use pattern matching in function definitions in Erlang a lot. I don't find any problems with production code. I'm an ejabberd developer and, by any means, it's production code. Also, every Erlang code is using this style. I miss the feature in OCaml, now I miss it in Elm.

Please reconsider your point of view.

Would also really like to see this added back in.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ShalokShalom picture ShalokShalom  路  3Comments

evancz picture evancz  路  4Comments

ccapndave picture ccapndave  路  3Comments

maxsnew picture maxsnew  路  4Comments

zoren picture zoren  路  5Comments