Issue #15865 has been updated by pvande (Pieter van de Bruggen).


mame (Yusuke Endoh) wrote:
> I'd like to avoid to discuss a common topic between one-line and `case/in` in this particular ticket.

Agreed; the gist discusses the entirety of the feature-space, but the conversation in this ticket should be constrained to just the one-line pattern matching proposal.

> 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.

Agreed.  I would expect the semantics to match, either way.

> 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.) 

The Twitter post from ko1 that I was responding to was specifically soliciting feedback about the syntax:

From https://twitter.com/_ko1/status/1135788844916195329:
> We want to ask English speaker about this proposal. Do you feel natural on this syntax?

To be clear  I do not.  I'm happy to elaborate on exactly *why* not, but  as you point out my objections are not principally to the inline syntax.

> 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.

I agree, and I have posted the same gist in the other ticket (as you suggested) in the hopes of sparking similar discussion there.

> * 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>`.

I can't speak directly to the parsing difficulty.  From the outside, it *looks* like a combination of destructuring assignment (which deals with multiple LHS arguments), Array and Hash literals, and method arguments (e.g. required Hash keys, keyword splats).  The primary difficulty, then, would seem to come from not knowing (e.g.) if the malformed Hash you just parsed was a *pattern* or a *syntax error* until you know whether or not it's followed by `<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`.)

Once again, I agree.  It is correct for this syntax to mirror the block form, and I have not tried to imply otherwise.

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

* 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>