[ruby-dev:52043] [Ruby master Bug#17925] Pattern matching syntax using semicolon one-line

Issue #17925 has been updated by yui-knk (Kaneko Yuichiro). It's possible https://github.com/yui-knk/ruby/tree/bugs_17925. I think this is not limitaion but the matter of choice. Currently `expr` is expected after `case` therefore `expression in 42` is interpreted as `expr`. For example ```ruby case expression in 42 in true in false end ``` Before the change, this is interpreted as ```ruby case (expression in 42) in true in false end ``` After the change, this is interpreted as ```ruby case expression in 42 in true in false end ``` # Impact ## For `case ... in` As shown above, this will change the behavior of current codes. Before: ```ruby expression = 42 case expression in 42 in true p :t in false p :f end #=> :t ``` ```ruby expression = 421 case expression in 42 in true p :t in false p :f end #=> :f ``` After: ```ruby expression = 42 case expression in 42 in true p :t in false p :f end #=> nothing printed, because body for 42 is empty ``` ```ruby expression = 421 case expression in 42 in true p :t in false p :f end #=> 421 (NoMatchingPatternError) # because nothing matches ``` ## For `case ... when` Before this change, this is valid ```ruby case expression in 42 when true p :t when false p :f end ``` However after this change, it's invalid ```ruby case expression in 42 when true p :t when false p :f end # test2.rb:2: syntax error, unexpected `when' (SyntaxError) # when true # ^~~~ ``` Impact on `case ... when` is inevitable because new grammar recognizes this is `case ... in` when third symbol (`in`) appears. ## New exception `expr` appears other place of the grammar. For example, `if expr ...`, `while expr ...` and so on. This change introduces an exception that you can write one line pattern matching after `if`, `unless`, `while`, `until` and so on but you can't after `case`. # Conclusion * This a matter of choice not limitaion * New grammar introduces incompatibility. It changes the behavior of `case ... in` and breaks `case ... when` * It introduces an exceptional rule to the grammar * As a reporter says, there is workaround to add `;` after `expression` `expression in 42` always returns `true` or `false` therefore it might be useless for `case`. Howerver we need to consider such impacts and benefits before decision making. # Note Impact on `case ... when` can be found as Shift/Reduce conflict. In this state, shift derives `case ... when`, on the other hand reduce derives `case ... in`. https://github.com/yui-knk/ruby/tree/bugs_17925_2 ``` State 394 shift/reduce conflict on token "`in'": 60 expr0: arg • 71 expr: arg • "`in'" @7 @8 p_top_expr_body First example: $@1 k_case arg • "`in'" @7 @8 p_top_expr_body opt_terms @19 case_body k_end "=>" @5 @6 p_top_expr_body opt_terms Shift derivation program ↳ 2: $@1 top_compstmt ↳ 3: top_stmts opt_terms ↳ 5: top_stmt ↳ 7: stmt ↳ 37: expr ↳ 68: arg "=>" @5 @6 p_top_expr_body ↳ 269: primary ↳ 358: k_case expr_value opt_terms @19 case_body k_end ↳ 78: expr ↳ 71: arg • "`in'" @7 @8 p_top_expr_body Second example: $@1 k_case arg • opt_terms "`in'" @38 @39 p_top_expr then $@40 compstmt p_cases k_end '[' opt_call_args rbracket "operator-assignment" lex_ctxt command_rhs opt_terms "end-of-input" Reduce derivation $accept ↳ 0: program "end-of-input" ↳ 2: $@1 top_compstmt ↳ 3: top_stmts opt_terms ↳ 5: top_stmt ↳ 7: stmt ↳ 32: command_asgn ↳ 41: primary_value '[' opt_call_args rbracket "operator-assignment" lex_ctxt command_rhs ↳ 377: primary ↳ 361: k_case expr_value0 opt_terms p_case_body k_end ↳ 77: expr0 ↳ 500: "`in'" @38 @39 p_top_expr then $@40 compstmt p_cases ↳ 60: arg • ``` ---------------------------------------- Bug #17925: Pattern matching syntax using semicolon one-line https://bugs.ruby-lang.org/issues/17925#change-104453 * Author: koic (Koichi ITO) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.0dev (2021-05-28T16:34:27Z master e56ba6231f) [x86_64-darwin19] * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN ---------------------------------------- ## Summary There are the following differences between `case ... when` and` case ... in`. Is this an expected behavior? ```console % ruby -v ruby 3.1.0dev (2021-05-28T16:34:27Z master e56ba6231f) [x86_64-darwin19] % ruby -ce 'case expression when 42; end' Syntax OK % ruby -ce 'case expression in 42; end' -e:1: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby! -e:1: syntax error, unexpected `end', expecting `when' case expression in 42; end ``` So, I have two concerns. - Since the pattern matching syntax is different from `case ... when`, can't user write semicolon one-line `case ... in` in the same semicolon one-line as `case ... when`? - Does `case expression in 42; end` display an experimental warning of one-line pattern matching. Right? This is reproduced in Ruby 3.1.0-dev and Ruby 3.0.1. ## Additional Information NOTE 1: I understand that only syntax that doesn't use `case` and `end` is experimental one-line pattern matching syntax. ``` % ruby -ce 'expression in 42' -e:1: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby! Syntax OK ``` NOTE 2: The syntax is OK if a semicolon is used between `expression` and `in`. But `case ... when` is a valid syntax to omit. ``` % ruby -e ruby -ce 'case expression; in 42; end' Syntax OK ``` -- https://bugs.ruby-lang.org/
participants (1)
-
yui-knk (Kaneko Yuichiro)