Parentheses for non-qualified calls are optional, except for zero-arity calls, which would then be ambiguous with variables. If parentheses are used, they must immediately follow the function name without spaces . For example, add (1, 2) is a syntax error, since (1, 2) is treated as an invalid block which is attempted to be given as a single argument to add .
…
Parentheses for qualified calls are optional. If parentheses are used, they must immediately follow the function name without spaces .
Let’s go code spelunking! Let’s start with Code.string_to_quoted because this has the general properties we want: it takes a string, and it will error if you do #4
case :elixir.string_to_tokens(to_charlist(string), line, column, file, opts) do
{:ok, tokens} ->
:elixir.tokens_to_quoted(tokens, file, opts)
{:error, _error_msg} = error ->
error
end
Here we find :elixir.string_to_tokens as well as :elixir.tokens_to_quoted so let’s dig in there and see if we can find the error generating bit. Let’s pop open an iex session to see if the first function returns an error:
Aha! Note the first item is now :parent_identifier vs :identifier. This likely gets used later.
Let’s move on to the :elixir.tokens_to_quoted function then:
tokens_to_quoted(Tokens, File, Opts) ->
handle_parsing_opts(File, Opts),
try elixir_parser:parse(Tokens) of
OK mostly just going to :elixir_parser so let’s go there:
Aha! This is a big old yrl file so let’s just do the easy thing and search for the word “space” and see if our error shows up:
Sure does! Let’s see when that gets called:
Unfortunately here is where my ability to help starts to reach its limits. I don’t particularly know or understand how yrl files work, so beyond seeing that the column values between #3 and #4 are different, I don’t super duper know how it’s arriving at that case. Probably something to do with that :paren_identifier thing. Hopefully this is a good jumping off point though!
EDIT: Made a small edit to include output from the #3 case.
It’s implying that if (foo, bar) is being parsed as a function without parenthesis on its arguments, therefore it expects no parenthesis after the space, yet it found one, therefore the error.
It doesn’t parse to anything because it fails to parse in the first place.
The first response was fine
Usually when I want to see what something parses to I just call Code.string_to_quoted or quote/2, depending on if I want more metadata or not. If it fails to parse then it’s not valid syntax.
Yeah I think this is a good way to put it. It tokenizes, but does not parse.
A small addendum: The elixir code base is really often quite approachable and I highly recommend poking about for these sorts of questions.
As a gentle nudge, when asking for help, do take care to not come down too hard on folks that didn’t quite hit your desired mark with their answer. You are asking for a favor after all.
Thank you, the difference in the :elixir.string_to_tokens output above is precisely what I was looking for. I completely agree that the correct statement is “It tokenzes, but does not parse.”
I absolutely agree that I am asking for help. The issue though is that he claimed the error message answers my question (it does not), and implies I did not even bother to read the error message (I did).