Project

General

Profile

Actions

Bug #20785

closed

Should `a in b, and c` `a in b, or c` `a in b, rescue c` be syntax ok?

Added by tompng (tomoya ishida) 3 months ago. Updated 6 days ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 3.4.0dev (2024-10-04T03:22:53Z master 939ec9f080) +YJIT +MN +PRISM [arm64-darwin22]
[ruby-core:119462]

Description

This code is accepted in parse.y but rejected in prism

tap do
  a in b, and c
  a in b, or c
  a in b, rescue c
end

# parsed as
tap do
  (a in b,;) and c
  (a in b,;) or c
  a in b,;
rescue c
end

I think these should be rejected like prism (parse.y accepts)

a in b, and c

a in b,
and c

tap do
  a in b, rescue c
end

I think these should be accepted like parse.y (prism rejects)

tap do
  a in b,
end

tap do
  a in b,
rescue
end

Updated by nobu (Nobuyoshi Nakada) 3 months ago

  • Assignee set to matz (Yukihiro Matsumoto)

Updated by nobu (Nobuyoshi Nakada) 3 months ago

  • Assignee changed from matz (Yukihiro Matsumoto) to ktsj (Kazuki Tsujimoto)

Updated by Dan0042 (Daniel DeLorme) 3 months ago

tompng (tomoya ishida) wrote:

I think these should be accepted like parse.y (prism rejects)

tap do
  a in b,
end

tap do
  a in b,
rescue
end

Can you explain your reasoning here? I'm guessing that a in b, is parsed as a in [b,] but a trailing comma like that is just too wild for me; it totally breaks my intuitions about Ruby syntax, and I think it should be rejected.

Updated by ktsj (Kazuki Tsujimoto) 3 months ago

  • Assignee changed from ktsj (Kazuki Tsujimoto) to matz (Yukihiro Matsumoto)

I agree with tompng's proposal.

I'm guessing that a in b, is parsed as a in [b,] but a trailing comma like that is just too wild for me

in (=>) can be considered right assignment.
And, I think it makes sense that a trailing comma is allowed in right assignment, just as a trailing comma is allowed in normal assignment.

a => b, # one-line pattern matching as right assignment
b, = a  # normal assignment

What do you think, @matz (Yukihiro Matsumoto)?

Updated by mame (Yusuke Endoh) about 1 month ago

Discussed at the dev meeting. Matz says that, in principle, the trailing comma of a pattern should be allowed.

a in b, and c    # Prism should accept this as `(a in b,) and c`
a in b, or c     # Prism should accept this as `(a in b,) or c`

In terms of rescue after a comma, it should be handled as a modifier.

a in b, rescue c # (a in b,) rescue c

In terms of a newline after a comma, it should be handled as an end of a sentence.

a in b, # This line should be a complete sentence
and c   # This is an invalid line

However, if there are implementation difficulties with the parser, he would consider compromises.

@yui-knk (Kaneko Yuichiro) @kddnewton (Kevin Newton) Do you think if matz's expectation is feasible?

Updated by kddnewton (Kevin Newton) about 1 month ago

I think this resolution makes sense, we can make that work. Should we get started on it?

Actions #7

Updated by hsbt (Hiroshi SHIBATA) about 1 month ago

  • Status changed from Open to Assigned

Updated by Dan0042 (Daniel DeLorme) about 1 month ago

mame (Yusuke Endoh) wrote in #note-5:

In terms of a newline after a comma, it should be handled as an end of a sentence.

a in b, # This line should be a complete sentence
and c   # This is an invalid line

I doubt my opinion makes any difference here, but the above makes no sense to me. I would expect this to be a valid pattern match:

a in b,
     c,
     d 

Updated by Eregon (Benoit Daloze) about 1 month ago

I think @Dan0042 (Daniel DeLorme) has a point.
For instance if I'm using some longer variables names and the array/tuple has many elements it would be natural to wrap it into two lines, but IIUC this change would break it:

if tuple in element_type, element_size, dimensions, pointer, offset, buffer_length, stride
  ...
end
# might be wrapped as:
if tuple in element_type, element_size, dimensions, pointer, offset,
    buffer_length, stride
  ...
end

In the OP description, I think all cases can be very easily made clear and unambiguous by appending *.
For example:

tap do
  a in b, * and c
  a in b, * or c
  a in b, * rescue c
end

tap do
  a in b, *
end

tap do
  a in b, *
rescue
end

From that I think considering trailing comma for in pattern matching as SyntaxError is good, as it encourages clarity and removes syntactical ambiguity (at least from a human perception).

Updated by mame (Yusuke Endoh) about 1 month ago

Dan0042 (Daniel DeLorme) wrote in #note-8:

I doubt my opinion makes any difference here, but the above makes no sense to me. I would expect this to be a valid pattern match:

a in b,
     c,
     d 

In RubyConf venue, I showed @matz (Yukihiro Matsumoto) your example, and it has convinced him. He changed his mind and said that a comma at the line end should continue to the next line. Your opinion made difference :-)

Actions #11

Updated by ydah (Yudai Takada) 6 days ago

  • Status changed from Assigned to Closed

Applied in changeset git|f6e0a037aa21bd90830cecc397c16918890d76a2.


[ruby/prism] [Bug #20785] Allow , and and , or after patterns

Partially: https://bugs.ruby-lang.org/issues/20785

https://github.com/ruby/prism/commit/71c9102d02

Actions

Also available in: Atom PDF

Like2
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like1Like0