Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler error by space between function name and ( #5761

Closed
t-ce opened this issue Feb 12, 2017 · 15 comments

Comments

Projects
None yet
3 participants
@t-ce
Copy link

commented Feb 12, 2017

Environment

Fedora 25
Erlang/OTP 19 [erts-8.2.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.3.1)

Current behavior

In iex, note the space between function name (f) and (:

iex(8)> defmodule A do def f (x), do: x end
** (CompileError) iex:8: can use only variables and \\ as arguments in function heads

Or as a a program (test.ex) with the same line of code:

$ elixir test.ex 
** (CompileError) test.ex:1: can use only variables and \\ as arguments in function heads

Also on more lines there is an error:

defmodule A do
  def f (x), do: x
end

Expected behavior

Either no error or a correct error message

@josevalim

This comment has been minimized.

Copy link
Member

commented Feb 12, 2017

We will attempt to clarify the error message. Your example is being parsed as def f((x), do: x).

@kelvinst

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2017

@josevalim any idea of how the error message could be clarified for this situation? Having hard times to find a good message for it. 🤣

All I can think of is something like:

only variables and \\ are allowed as arguments in definition header.
Tip: the syntax sugar for space instead of parens can be a tricky mud pit here.
As you can see in:

    def foo (x), do: x

that is actually parsed like:

    def foo((x), do: x)

@kelvinst

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2017

Maybe change the can be a tricky mud pit by can generate some confusion, IDK. 🤣

@josevalim

This comment has been minimized.

Copy link
Member

commented Feb 13, 2017

only variables and \\ are allowed as arguments in definition header.

If you did not intend to define a header, make sure your function definition has
the proper syntax by wrapping the arguments in parentheses and ensuring there
is no space between the function name and arguments, got:

    #{Macro.to_string({:def, [], [{name, _, args}]})}
@t-ce

This comment has been minimized.

Copy link
Author

commented Feb 13, 2017

Just an observation: The space is accepted in the multi-line version

defmodule A do
  def f (x) do
    x
  end
end
@josevalim

This comment has been minimized.

Copy link
Member

commented Feb 13, 2017

@t-ce not if you have multiple arguments, which then is a parser error. It is generally good advice to not add spaces between the function name and arguments. :)

@kelvinst

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2017

@t-ce yes, but this does not:

defmodule A do
  def f (x, y) do
    {x, y}
  end
end
@kelvinst

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2017

Opening a PR really soon. Wait for it!

@t-ce

This comment has been minimized.

Copy link
Author

commented Feb 13, 2017

Thank you.
I tested your code @kelvinst.

defmodule A do
  def f (x, y) do
    {x, y}
  end
end

And I got

** (SyntaxError) iex:2: unexpected parentheses. If you are making a function call, do not insert spaces between the function name and the opening parentheses. Syntax error before: '('

That is, there is already a message with the space. Beside function call one could add or a function definition

@kelvinst

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2017

@t-ce the problem is that in def f (x), do: x the compiler understands it like a function header without the body, which cannot have any match expression too. That's why this message you got exist as it is in the first place.

@kelvinst

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2017

@josevalim got one problem with Macro.to_string\1. I changed the message and in the tests I got def(f(x) do x end) instead of def(f((x), do: x)). I have tested here, and got the following result:

iex(1)> IO.puts Macro.to_string(quote do: def f (x), do: x)
def(f(x) do
  x
end)

Is this a problem with Macro.to_string? Or did I lose something?

@kelvinst

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2017

Forget about it! I was just confused by the way it prints. Actually def(f(x) do x end) is an invalid function header too, the correct would be def(f(x)) do x end

@josevalim

This comment has been minimized.

Copy link
Member

commented Feb 13, 2017

@kelvinst

This comment has been minimized.

Copy link
Contributor

commented Feb 13, 2017

Well, it's a good point. I got confused pretty easily, maybe only the long description would be less confusing and clear enough. WDYT?

kelvinst added a commit to kelvinst/elixir that referenced this issue Feb 13, 2017

Improving the function header def args compilation error
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761

kelvinst added a commit to kelvinst/elixir that referenced this issue Feb 13, 2017

Improving the function header def args compilation error
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761
@josevalim

This comment has been minimized.

Copy link
Member

commented Feb 13, 2017

kelvinst added a commit to kelvinst/elixir that referenced this issue Feb 13, 2017

Improving the function header def args compilation error
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761

kelvinst added a commit to kelvinst/elixir that referenced this issue Feb 13, 2017

Improving the function header def args compilation error
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761

kelvinst added a commit to kelvinst/elixir that referenced this issue Feb 13, 2017

Improving the function header def args compilation error
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761

kelvinst added a commit to kelvinst/elixir that referenced this issue Feb 13, 2017

Improving the function header def args compilation error
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761

kelvinst added a commit to kelvinst/elixir that referenced this issue Feb 13, 2017

Improving the function header def args compilation error
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761

kelvinst added a commit to kelvinst/elixir that referenced this issue Feb 14, 2017

Improving the function header def args compilation error
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761

josevalim added a commit that referenced this issue Feb 15, 2017

Improving the function header def args compilation error (#5765)
The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes #5761

ckampfe added a commit to ckampfe/elixir that referenced this issue Jul 22, 2017

Improving the function header def args compilation error (elixir-lang…
…#5765)

The code:

    def f (x), do: x

was printing the function header definition error because it is parsed
to this:

    def f((x), do: x)

So we made an additional description to the compilation error.

This commit fixes elixir-lang#5761
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.