[ruby-core:114270] [Ruby master Bug#19782] Ruby operators precedence inconsistency

Issue #19782 has been reported by hurricup (Alexandr Evstigneev). ---------------------------------------- Bug #19782: Ruby operators precedence inconsistency https://bugs.ruby-lang.org/issues/19782 * Author: hurricup (Alexandr Evstigneev) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Unfortunately I could not find a good documentation regarding ruby operators precedence and associativity, but according to https://ruby-doc.org/3.2.2/syntax/precedence_rdoc.html `&&` has higher precedence than assignment. Meaning that `a && b = c` would be treated as `(a && b) = c` which makes a little sense, but still. But ruby 3.2.2 shows that it works as `a && (b = c)` (if I read it right): ``` def moo(a,b,c) if a && b = c end end puts RubyVM::InstructionSequence.of(method :moo).disasm ``` Gives me ``` == disasm: #<ISeq:moo@/home/hurricup/Projects/untitled/test.rb:1 (1,0)-(5,3)> (catch: false) local table (size: 3, argc: 3 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 3] a@0<Arg> [ 2] b@1<Arg> [ 1] c@2<Arg> 0000 getlocal_WC_0 a@0 ( 2)[LiCa] 0002 branchunless 13 0004 getlocal_WC_0 c@2 0006 dup 0007 setlocal_WC_0 b@1 0009 branchunless 13 0011 putnil 0012 leave ( 5)[Re] 0013 putnil ( 2) 0014 leave ( 5)[Re] ``` For example, perl has well documentation and same rules regarding these two ops: https://perldoc.perl.org/perlop#Operator-Precedence-and-Associativity And if you try: ``` use v5.38; my($var1, $var2, $var3) = (1,2,3); $var1 && $var2 = $var3; say $var1, $var2, $var3; ``` You will get expected: ``` Can't modify logical and (&&) in scalar assignment at /home/hurricup/Projects/untitled/test.pl line 5, near "$var3;" Execution of /home/hurricup/Projects/untitled/test.pl aborted due to compilation errors. ``` Could you please clarify this? Also would be really nice to have documentation on how precedence work, including calls without parens, like `some.thing expr` which precedence is consumed by `expr` here? -- https://bugs.ruby-lang.org/

Issue #19782 has been updated by sawa (Tsuyoshi Sawada). In general, precedence comes into play when an expression is ambiguous. An expression is ambiguous when there is more than one (grammatical) parse. `(a && b) = c` is not a grammatical parse of `a && b = c`; only `a && (b = c)` is. Hence, this expression is not ambiguous, and precedence is irrelevant here. ---------------------------------------- Bug #19782: Ruby operators precedence inconsistency https://bugs.ruby-lang.org/issues/19782#change-103961 * Author: hurricup (Alexandr Evstigneev) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Unfortunately I could not find a good documentation regarding ruby operators precedence and associativity, but according to https://ruby-doc.org/3.2.2/syntax/precedence_rdoc.html `&&` has higher precedence than assignment. Meaning that `a && b = c` would be treated as `(a && b) = c` which makes a little sense, but still. But ruby 3.2.2 shows that it works as `a && (b = c)` (if I read it right): ``` def moo(a,b,c) if a && b = c end end puts RubyVM::InstructionSequence.of(method :moo).disasm ``` Gives me ``` == disasm: #<ISeq:moo@/home/hurricup/Projects/untitled/test.rb:1 (1,0)-(5,3)> (catch: false) local table (size: 3, argc: 3 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 3] a@0<Arg> [ 2] b@1<Arg> [ 1] c@2<Arg> 0000 getlocal_WC_0 a@0 ( 2)[LiCa] 0002 branchunless 13 0004 getlocal_WC_0 c@2 0006 dup 0007 setlocal_WC_0 b@1 0009 branchunless 13 0011 putnil 0012 leave ( 5)[Re] 0013 putnil ( 2) 0014 leave ( 5)[Re] ``` For example, perl has well documentation and same rules regarding these two ops: https://perldoc.perl.org/perlop#Operator-Precedence-and-Associativity And if you try: ``` use v5.38; my($var1, $var2, $var3) = (1,2,3); $var1 && $var2 = $var3; say $var1, $var2, $var3; ``` You will get expected: ``` Can't modify logical and (&&) in scalar assignment at /home/hurricup/Projects/untitled/test.pl line 5, near "$var3;" Execution of /home/hurricup/Projects/untitled/test.pl aborted due to compilation errors. ``` Could you please clarify this? Also would be really nice to have documentation on how precedence work, including calls without parens, like `some.thing expr` which precedence is consumed by `expr` here? -- https://bugs.ruby-lang.org/

Issue #19782 has been updated by hurricup (Alexandr Evstigneev). sawa (Tsuyoshi Sawada) wrote in #note-1:
In general, precedence comes into play when an expression is ambiguous. An expression is ambiguous when there is more than one (grammatical) parse. `(a && b) = c` is not a grammatical parse of `a && b = c`; only `a && (b = c)` is. Hence, this expression is not ambiguous, and precedence is irrelevant here.
I'm sorry, I don't understand. What do you mean by 'expression is ambiguous'? According to the definition (from wikipedia):
In mathematics and computer programming, the order of operations (or operator precedence) is a collection of rules that reflect conventions about which procedures to perform first in order to evaluate a given mathematical expression.
According to rdoc I referred, assignment has lower precedence than HP logical ops, meaning that logical ops are done before assignments, which is not true. Would be nice to have a consistent precedence table with all 'but's. ---------------------------------------- Bug #19782: Ruby operators precedence inconsistency https://bugs.ruby-lang.org/issues/19782#change-103963 * Author: hurricup (Alexandr Evstigneev) * Status: Rejected * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Unfortunately I could not find a good documentation regarding ruby operators precedence and associativity, but according to https://ruby-doc.org/3.2.2/syntax/precedence_rdoc.html `&&` has higher precedence than assignment. Meaning that `a && b = c` would be treated as `(a && b) = c` which makes a little sense, but still. But ruby 3.2.2 shows that it works as `a && (b = c)` (if I read it right): ``` def moo(a,b,c) if a && b = c end end puts RubyVM::InstructionSequence.of(method :moo).disasm ``` Gives me ``` == disasm: #<ISeq:moo@/home/hurricup/Projects/untitled/test.rb:1 (1,0)-(5,3)> (catch: false) local table (size: 3, argc: 3 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 3] a@0<Arg> [ 2] b@1<Arg> [ 1] c@2<Arg> 0000 getlocal_WC_0 a@0 ( 2)[LiCa] 0002 branchunless 13 0004 getlocal_WC_0 c@2 0006 dup 0007 setlocal_WC_0 b@1 0009 branchunless 13 0011 putnil 0012 leave ( 5)[Re] 0013 putnil ( 2) 0014 leave ( 5)[Re] ``` For example, perl has well documentation and same rules regarding these two ops: https://perldoc.perl.org/perlop#Operator-Precedence-and-Associativity And if you try: ``` use v5.38; my($var1, $var2, $var3) = (1,2,3); $var1 && $var2 = $var3; say $var1, $var2, $var3; ``` You will get expected: ``` Can't modify logical and (&&) in scalar assignment at /home/hurricup/Projects/untitled/test.pl line 5, near "$var3;" Execution of /home/hurricup/Projects/untitled/test.pl aborted due to compilation errors. ``` Could you please clarify this? Also would be really nice to have documentation on how precedence work, including calls without parens, like `some.thing expr` which precedence is consumed by `expr` here? -- https://bugs.ruby-lang.org/
participants (2)
-
hurricup (Alexandr Evstigneev)
-
sawa (Tsuyoshi Sawada)