Issue #15865 has been updated by mame (Yusuke Endoh).


Thank you for your comment.

This ticket discusses one-line pattern matching: `<expr> in <pattern>` in my proposal.  This proposal is based on the `case/in` pattern-matching statement.   I'd like to avoid to discuss a common topic between one-line and `case/in` in this particular ticket.

You have three points.

1. Matching is not strict.
2. The proposed <match-op> is `in`.
3. The pattern is on the RHS.

The design choice of (1) is done in `case/in` statement.  The one-line version and `case/in` should share the semantics of each pattern.  It is unarguably too confusing if they have different semantics.  So, I like not to discuss this issue in this ticket.

So, you have two concerns for my proposal about one-line pattern matching syntax: (2) the keyword `in` and (3) the word order.  I understand that it is unnatural in English.  (Honestly, it is mathematically/logically correct as you said, so it works for me, a non-native, though.)  However, I believe that this is the best choice for some reasons:

* The appearance of `case/in` statement is `case <expr>; in <pattern>; ... end`.  In a sense, the keyword `in` and the order that `<pattern>` follows the keyword `in` are already established, as long as we accept `case/in` statement.

* The order `<pattern> <match-op> <expr>` is very difficult (or maybe impossible?) to implement parsing rules.  Perhaps we need to use `<pattern-marker> <pattern> <match-op> <expr>`, but it is very tough to agree with symbol or keyword of `<pattern-marker>` and `<match-op>`.

You can discuss the grand design of pattern matching and the syntax of `case/in` statement in #14912.  If the grand design is overturned, my proposal will need to change drastically.  (But in short, I respect the design decision.  I'm not fully satisfied with the syntax, but we spent very long time to discuss what keyword is suitable and feasible, and finally chose the design including the keyword `in`.)

----------------------------------------
Feature #15865: `<expr> in <pattern>` expression
https://bugs.ruby-lang.org/issues/15865#change-78904

* Author: mame (Yusuke Endoh)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 
----------------------------------------
How about adding a syntax for one-line pattern matching: `<expr> in <pattern>` ?

```
[1, 2, 3] in x, y, z #=> true (with assigning 1 to x, 2 to y, and 3 to z)
[1, 2, 3] in 1, 2, 4 #=> false
```

More realistic example:

```
json = {
  name: "ko1",
  age: 39,
  address: { postal: 123, city: "Taito-ku" }
}

if json in { name:, age: (20..), address: { city: "Taito-ku" } }
  p name #=> "ko1"
else
  raise "wrong format"
end
```

It is simpler and more composable than "case...in" when only one "in" clause is needed.  I think that in Ruby a pattern matching would be often used for "format-checking", to check a structure of data, and this use case would usually require only one clause.  This is the main rationale for the syntax I propose.

Additional two small rationales:

* It may be used as a kind of "right assignment": `1 + 1 in x` behaves like `x = 1 + 1`.  It returns true instead of 2, though.
* There are some arguments about the syntax "case...in".  But if we have `<expr> in <pattern>`, "case...in" can be considered as a syntactic sugar that is useful for multiple-clause cases, and looks more natural to me.

There are two points I should note:

* `<expr> in <pattern>` is an expression like `<expr> and <expr>`, so we cannot write it as an argument: `foo(1 in 1)` causes SyntaxError.  You need to write `foo((1 in 1))` as like `foo((1 and 1))`.  I think it is impossible to implement.
* Incomplete pattern matching also rewrites variables: `[1, 2, 3] in x, 42, z` will write 1 to the variable "x".  This behavior is the same as the current "case...in".

Nobu wrote a patch: https://github.com/nobu/ruby/pull/new/feature/expr-in-pattern



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>