Project

General

Profile

Actions

Feature #19545

open

lp/hp logic parsing inconsistency

Added by hurricup (Alexandr Evstigneev) almost 2 years ago. Updated over 1 year ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:112990]

Description

As far as i get it, low precedence logic should behave the same as high precedence. But:

This is ok:

puts(false || !false)

And this is not:

puts(false or not false)

Feels like in latter case there is some mess with comma precedence.

Updated by hurricup (Alexandr Evstigneev) almost 2 years ago

puts not false

Feels pretty valid as well.

Updated by jeremyevans0 (Jeremy Evans) over 1 year ago

  • Tracker changed from Bug to Feature
  • Backport deleted (2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN)

Not all Ruby code is allowed directly as a method argument. You can surround the code with parentheses to allow it, so puts((false or not false)) works. This is a similar issue as puts(raise rescue false), but not exactly the same.

It may be possible to work around by modifying the parser to make paren_args handle this case (you could only handle this for method calls with explicit parentheses, since puts false or not false is already parsed as puts(false) or (not false). However, I haven't attempted that, and it might result in parser conflicts. In terms of puts not false, that might also be possible to, though trickier (maybe call_args). However, as you mentioned, usage with commas may be problematic, and it would be a bad idea to support this only for single argument calls, so unless you could get it working with multiple arguments, it doesn't seem worth changing.

In general, you should use &&, ||, and ! for these cases. and, or, and not are designed with control flow in mind (e.g. method1 arg or method2 as opposed to method arg1 || arg2).

I don't think the current behavior is a bug, switching to feature request.

Updated by hurricup (Alexandr Evstigneev) over 1 year ago

You are explaining from ruby developer perspective and it all makes sense.
But from pure language user this feels really strange and inconsistent. Especially puts((...)) :D

false or not false is pretty valid expression. And any expression is a valid argument for any call. The only thing that should be in effect there is precedence of ops, commas and parentheses.

This is totally non-critical thing, just for the information. Thanks for your time.

Updated by jeremyevans0 (Jeremy Evans) over 1 year ago

hurricup (Alexandr Evstigneev) wrote in #note-3:

And any expression is a valid argument for any call.

Just to be clear, while this may be a common belief, this is not the case. If you define valid expression to be a piece of Ruby code that could be executed by itself without a syntax error, then not all valid expressions are valid arguments in Ruby. The most obvious reason why not all valid expressions can be arguments is that some valid expressions contain ,, which is used to separate arguments (e.g. multiple assignment). However, that isn't the only reason.

From an CRuby internals perspective, all expressions (expr) are statements (stmt), and all statements surrounded by parentheses are primaries (primary), and all primaries are valid arguments (arg). Consult the arg definition in parse.y if you want to see what Ruby actually considers valid arguments.

It may be possible to modify the parser to expand the definition of argument to start allowing certain expressions that are not currently supported as arguments. I think doing so would be a feature request and not a bug fix, since we would not consider backporting such changes. FWIW, modifying the current parser is challenging, at least for me. Hopefully with YARP, it will be easier.

Updated by hurricup (Alexandr Evstigneev) over 1 year ago

jeremyevans0 (Jeremy Evans) wrote in #note-4:

hurricup (Alexandr Evstigneev) wrote in #note-3:

And any expression is a valid argument for any call.

Just to be clear, while this may be a common belief, this is not the case. If you define valid expression to be a piece of Ruby code that could be executed by itself without a syntax error, then not all valid expressions are valid arguments in Ruby. The most obvious reason why not all valid expressions can be arguments is that some valid expressions contain ,, which is used to separate arguments (e.g. multiple assignment). However, that isn't the only reason.

Thank you for the explanation. This is totally understandable for me.
I just saying that this may be non-intuitive for the language user.
Comma situation could be handled with proper precedence btw. Like perl does, for example. If you curios, see the table in the end of section: https://perldoc.perl.org/perlop#Operator-Precedence-and-Associativity

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like1Like0