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


marcandre (Marc-Andre Lafortune) wrote:
> mame (Yusuke Endoh) wrote:
> > I talked with ktsj, the author of pattern matching.  He had actually considered caching the result of deconstruct, but we found it difficult because of some reasons.
> > 
> > * If destructive operation is applied to the object being matched (this is possible in a guard expression), the behavior of pattern matching would get messed up.
> 
> Is there a valid use case for this though? Seems more like an anti-pattern that is better not being supported at all.

ktsj and I prefer simpleness and robustness to performance when we consider the design of Ruby language.  In Ruby, optimization is not primary; it is good as long as it does not change the naive semantics.  For example, if we disallow the redefinition of bulit-in methods including `Integer#+`, we can make the interpreter faster and can make the implementation much simpler.  But we still allow and respect the redefinition.

In this case, more intelligent optimization (including nice cache invalidation) that does not affect the semantics is needed (if the performance is really needed).


> > * If you need to cache the result of your own `deconstruct` definition, it is not so difficult to manually memoize the result.
> 
> I disagree. You can't simply use `@cache ||= ...`, you need to invalidate `@cache` if any dependency of the `...` changes. That may be quite tricky. Let's remember:
> 
>     There are only two hard things in Computer Science: cache invalidation and naming things.
> 
>     -- Phil Karlton

Agreed.  The same goes to Ruby interpreter itself :-)

----------------------------------------
Feature #15881: Optimize deconstruct in pattern matching
https://bugs.ruby-lang.org/issues/15881#change-78495

* Author: marcandre (Marc-Andre Lafortune)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 2.7
----------------------------------------
```ruby
class A
  def deconstruct
    puts 'deconstruct called'
    [1]
  end
end

case A.new
in [2]
  2
in [1]
  1
else
end

# => 1, prints "deconstruct called"
```

Shouldn't `deconstruct called` print only once, whenever the first deconstruction needed occurs?



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