I don't know if this effects your planned change to the grammar, but as a 
side-effect of `not` being treated as a normal function instead of a 
keyword, `not` when captured allows any arity (you may have already 
realized this, I did not).

For uncaptured, `not` with a different arity than 1 is a syntax error

iex> Code.string_to_quoted("not 1")    
{:ok, {:not, [line: 1], [1]}}
iex> Code.string_to_quoted("not 1, 2")
{:error, {1, "syntax error before: ", "','"}}

While captured it doesn't care

iex> Code.string_to_quoted("&not 1")  
{:ok, {:&, [line: 1], [{:not, [line: 1], [1]}]}}
iex> Code.string_to_quoted("&not 1, 2")
{:ok, {:&, [line: 1], [{:not, [line: 1], [1, 2]}]}}

This may count as a separated bug just a related depending on how it's 
fixed.

On Sunday, May 14, 2017 at 2:41:53 AM UTC-5, José Valim wrote:
>
> Thank you Luke for the detailed bug report.
>
> I think we should fix this by making "!" behave like "not" and remove this 
> special case from the grammar. The only unary operator that will bind 
> tightly to numbers then will be &, which is already behaves differently 
> from the others as it has very low precedence.
>
> Note that @ will still bind tightly to numbers but that's rather because 
> it has very high precedence and not a special case.
>
> I will push a commit to master later today.
>
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
> On Sun, May 14, 2017 at 4:18 AM, Luke Imhoff <[email protected] 
> <javascript:>> wrote:
>
>> I noticed this when splitting `not` from the other unary operators in 
>> IntelliJ Elixir's lexer grammar (because I can only do spacing rules on 
>> lexer tokens, so I need NOT_OPERATOR separate from UNARY_OPERATOR for 
>> https://github.com/KronicDeth/intellij-elixir/issues/98 so I can have no 
>> space between the symbolic operators, but require the space after `not` as 
>> it will blend into the argument otherwise).  I'm not sure this is really a 
>> problem or not.  It's just a weird edge-case that I produced since I test 
>> unary numeric and unary non-numeric operators.
>>
>> `not` is part of `unary_op_eol` (
>> https://github.com/elixir-lang/elixir/blob/39dd31c7d96f302986579bb6938d23c9db101661/lib/elixir/src/elixir_parser.yrl#L73),
>>  
>> which also contains `+`, `-`, `!`, `^`, `~~~`.
>>
>> Let's start with unary numeric at the top-level
>>
>> iex> Code.string_to_quoted("not 1")     
>> {:ok, {:not, [line: 1], [1]}}
>> iex> Code.string_to_quoted("! 1")  
>> {:ok, {:!, [line: 1], [1]}}
>>
>> Next, let's do something weird and make the `1` act something you can do 
>> dot calls on.  This is gibberish semantically in current Elixir, but 
>> something the syntax allows.
>>
>> iex> Code.string_to_quoted("not 1.(2)")
>> {:ok, {{:., [line: 1], [{:not, [line: 1], [1]}]}, [line: 1], [2]}}
>> iex> Code.string_to_quoted("! 1.(2)")  
>> {:ok, {{:., [line: 1], [{:!, [line: 1], [1]}]}, [line: 1], [2]}}
>>
>> So, the precedence of the AST is the same: (1) `not`/`!` on `1`; (2) dot 
>> call with `2` on the result of (1).
>>
>> Finally, let's try to capture the weird syntax
>>
>> iex> Code.string_to_quoted("&not 1.(2)")
>> {:ok, {:&, [line: 1], [{:not, [line: 1], [{{:., [line: 1], [1]}, [line: 
>> 1], [2]}]}]}}
>> iex> Code.string_to_quoted("&! 1.(2)")  
>> {:ok, {:&, [line: 1], [{{:., [line: 1], [{:!, [line: 1], [1]}]}, [line: 
>> 1], [2]}]}}
>>
>> So the precedence of the symbolic `!` and word `not` is no longer the 
>> same.
>> For `not`: (1) `1.(2)` is called; (2) `not` the  result of (1)`; (3) 
>> capture
>> For `!`: `!1` is called; (2) `.(2)` is called on the result of (1); (3) 
>> capture
>>
>> What has happened is that `not` has lost it's "keywordness" and is moving 
>> the position of a normal function name (like `foo` below)
>>
>> iex> Code.string_to_quoted("&foo 1.(2)")
>> {:ok, {:&, [line: 1], [{:foo, [line: 1], [{{:., [line: 1], [1]}, [line: 
>> 1], [2]}]}]}}
>>
>> So, this example is gibberish.  Does it apply to non-numeric unary 
>> operations?
>>
>> iex> Code.string_to_quoted("&! a.(2)")  
>> {:ok, {:&, [line: 1], [{:!, [line: 1], [{{:., [line: 1], [{:a, [line: 1], 
>> nil}]}, [line: 1], [2]}]}]}}
>> iex> Code.string_to_quoted("&not a.(2)")
>> {:ok, {:&, [line: 1], [{:not, [line: 1], [{{:., [line: 1], [{:a, [line: 
>> 1], nil}]}, [line: 1], [2]}]}]}}
>> iex(56)> Code.string_to_quoted("&foo a.(2)")
>> {:ok, {:&, [line: 1], [{:foo, [line: 1], [{{:., [line: 1], [{:a, [line: 
>> 1], nil}]}, [line: 1], [2]}]}]}}
>>
>> So, it's all consistent there: (1) `a.(2)` is evaluated; (2) the 
>> operator/function call; and (3) it's all captured.
>>
>> So, is the inconsistency in unary numeric `not` a bug in the native 
>> grammar or something to be expected?  If the unary operators should bind 
>> more tightly to numerics than non-numerics (as is my understanding of the 
>> current grammar) then `{:ok, {:&, [line: 1], [{{:., [line: 1], [{:!, [line: 
>> 1], [1]}]}, [line: 1], [2]}]}}` is correct and `not` should be `{:ok, {:&, 
>> [line: 1], [{{:., [line: 1], [{:not, [line: 1], [1]}]}, [line: 1], [2]}]}}`.
>>
>> The unary numeric operations in current language semantics seem to be 
>> there for positional captures, like `&1`, so this is mostly me bringing it 
>> up because I have to change IntelliJ Elixir's grammar to take this 
>> behaviour for unary numeric `not` into account separately from symbolic 
>> unary numerics.
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "elixir-lang-core" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/f5f75451-93dc-4163-bd9a-7055dab69d62%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/f5f75451-93dc-4163-bd9a-7055dab69d62%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/e2bc219e-1fed-4b9b-8196-815def0ba4b2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to