Feature #19545
openlp/hp logic parsing inconsistency
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) over 1 year 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