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("¬ 1")
{:ok, {:&, [line: 1], [{:not, [line: 1], [1]}]}}
iex> Code.string_to_quoted("¬ 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("¬ 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("¬ 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.