https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112020-12-19T18:34:27ZRuby Issue Tracking SystemRuby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=893292020-12-19T18:34:27Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul><li><strong>Tracker</strong> changed from <i>Bug</i> to <i>Feature</i></li><li><strong>Subject</strong> changed from <i>Syntax error with . in pattern</i> to <i>Allow expressions in pattern matching</i></li><li><strong>Backport</strong> deleted (<del><i>2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN</i></del>)</li></ul><p>IIUC, it is by design that you can't have expressions in pattern match; pattern match are a quite separate syntax.</p>
<p>I agree that it is quite limiting, so I've taken the liberty to changing your issue to a feature request.</p>
<p>It would be great to allow expressions somehow. Maybe when wrapped in () or ``?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">version</span> <span class="k">in</span> <span class="p">{</span><span class="ss">released_at: </span><span class="p">(</span><span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2010</span><span class="p">)</span><span class="o">..</span><span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">2020</span><span class="p">))}</span>
<span class="c1"># or</span>
<span class="n">version</span> <span class="k">in</span> <span class="p">{</span><span class="ss">released_at: </span><span class="sb">`Time.new(2010)..Time.new(2020)`</span><span class="p">}</span>
</code></pre> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=893352020-12-20T09:26:02Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/182">@marcandre (Marc-Andre Lafortune)</a> The idea is interesting. I propose <code>^(expression)</code> notation.</p>
<p>Matz.</p> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=893402020-12-20T15:28:56Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>That's perfect 👍<br>
Any chance Nobu can come up with a patch quickly?</p> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=893562020-12-21T07:23:23Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p><a href="https://github.com/ruby/ruby/pull/3956" class="external">https://github.com/ruby/ruby/pull/3956</a></p> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=895052020-12-24T09:56:15Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>Thank you. <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/4">@nobu (Nobuyoshi Nakada)</a> We need approval from <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/3007">@ktsj (Kazuki Tsujimoto)</a> as well. It will be available in 3.1.</p>
<p>Matz.</p> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=895802020-12-27T17:45:27Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul><li><strong>Assignee</strong> set to <i>ktsj (Kazuki Tsujimoto)</i></li></ul> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=896122020-12-28T16:18:21Zktsj (Kazuki Tsujimoto)kazuki@callcc.net
<ul></ul><p>I am basically positive.<br>
(I've had the same idea. :) <a href="https://speakerdeck.com/k_tsj/pattern-matching-new-feature-in-ruby-2-dot-7?slide=64" class="external">https://speakerdeck.com/k_tsj/pattern-matching-new-feature-in-ruby-2-dot-7?slide=64</a>)</p>
<p>But I've been a little concerned most of languages which have pattern matching don't support such syntax.<br>
If there were a obvious reason, I'd like to know that.</p> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=896162020-12-28T17:20:20Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>ktsj (Kazuki Tsujimoto) wrote in <a href="#note-7">#note-7</a>:</p>
<blockquote>
<p>If there were a obvious reason, I'd like to know that.</p>
</blockquote>
<p>I can think of three reasons.</p>
<ul>
<li>(1) This feature makes an exhaustive check impossible (like a guard), which is not related to Ruby's pattern matching.</li>
<li>(2) It is difficult for a compiler to generate efficient code. For example, it cannot create a jump table statically. But we already have a pinning operator, so this may not be related to Ruby.</li>
<li>(3) The semantics will become very complicated when the expressions have side-effects.</li>
</ul>
<p>For (3), I think that the evaluation order should be unspecified; expression patterns may or may not be evaluated at any time (including compilation time). Otherwise, it would be very difficult or even almost impossible to optimize pattern matching. But I'm unsure if "the evaluation order is unspecifed" is acceptable for Ruby.</p> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=896192020-12-28T20:09:53Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>mame (Yusuke Endoh) wrote in <a href="#note-8">#note-8</a>:</p>
<blockquote>
<p>ktsj (Kazuki Tsujimoto) wrote in <a href="#note-7">#note-7</a>:</p>
<blockquote>
<p>If there were a obvious reason, I'd like to know that.</p>
</blockquote>
<p>I can think of three reasons.</p>
<ul>
<li>(1) This feature makes an exhaustive check impossible (like a guard), which is not related to Ruby's pattern matching.</li>
<li>(2) It is difficult for a compiler to generate efficient code. For example, it cannot create a jump table statically. But we already have a pinning operator, so this may not be related to Ruby.</li>
<li>(3) The semantics will become very complicated when the expressions have side-effects.</li>
</ul>
</blockquote>
<p>We also already have all theses issues/possibilities (including modifying local variables on the fly):</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">var</span> <span class="o">=</span> <span class="mi">42</span>
<span class="nb">proc</span> <span class="o">=</span> <span class="o">-></span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="p">{</span> <span class="n">var</span> <span class="o">=</span> <span class="mi">666</span><span class="p">;</span> <span class="kp">true</span> <span class="p">}</span>
<span class="k">case</span> <span class="p">[</span><span class="ss">:foo</span><span class="p">,</span> <span class="mi">42</span><span class="p">]</span>
<span class="k">in</span> <span class="p">[</span><span class="o">^</span><span class="nb">proc</span><span class="p">,</span> <span class="o">^</span><span class="n">var</span><span class="p">]</span>
<span class="nb">puts</span> <span class="s2">"match"</span>
<span class="k">else</span>
<span class="nb">puts</span> <span class="s2">"no match"</span>
<span class="k">end</span>
<span class="c1"># => no match (currently)</span>
</code></pre>
<p>I don't see an issue with this: don't shoot yourself in the foot...</p>
<blockquote>
<p>For (3), I think that the evaluation order should be unspecified; expression patterns may or may not be evaluated at any time (including compilation time). Otherwise, it would be very difficult or even almost impossible to optimize pattern matching. But I'm unsure if "the evaluation order is unspecifed" is acceptable for Ruby.</p>
</blockquote>
<p>By "compilation time" you mean "parse time"? That does not seem acceptable; it has to be at runtime.</p>
<p>As for order, we can leave it unspecified, or decide that order should be by priority (say basic patterns first, then pin variable & expressions, and guards last) and left to right within a priority group? It seems that it is what all implementations should prefer doing.</p> Ruby master - Feature #17411: Allow expressions in pattern matchinghttps://bugs.ruby-lang.org/issues/17411?journal_id=910352021-03-21T06:14:59Zktsj (Kazuki Tsujimoto)kazuki@callcc.net
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="Pattern matching pin operator against expression [Feature #17411] This commit is based on the pa..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/21863470d965b8cc299b1f82417c70d5d26f8ab2">git|21863470d965b8cc299b1f82417c70d5d26f8ab2</a>.</p>
<hr>
<p>Pattern matching pin operator against expression [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Allow expressions in pattern matching (Closed)" href="https://bugs.ruby-lang.org/issues/17411">#17411</a>]</p>
<p>This commit is based on the patch by <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/4">@nobu (Nobuyoshi Nakada)</a>.</p>