Issue #15973 has been updated by shyouhei (Shyouhei Urabe).


Suppose we change the spec so that `lambda(&nonlambda)` generates a lambda.
Suppose we have the following nonlambda proc:

```ruby
1: foldr = proc do |x, *xs|
2:   foo(x, foldr.(xs)) if x ||! xs.empty?
3: end
```

A straight-forward foldr implementation, with `foo` defined elsewhere.
Now let's "convert" it into a lambda:

```ruby
4: foldr = lambda(&foldr)
```

This magically breaks the program.  The meaning of `|x, *xs|` changed.
The problem I see is that the broken program would generate a backtrace like this:

```
Traceback (most recent call last):
        5444: from tmp.rb:2:in `block in <main>'
        5443: from tmp.rb:2:in `block in <main>'
        5442: from tmp.rb:2:in `block in <main>'
        5441: from tmp.rb:2:in `block in <main>'
        5440: from tmp.rb:2:in `block in <main>'
        5439: from tmp.rb:2:in `block in <main>'
        5438: from tmp.rb:2:in `block in <main>'
         ... 5433 levels...
           4: from tmp.rb:2:in `block in <main>'
           3: from tmp.rb:2:in `block in <main>'
           2: from tmp.rb:2:in `block in <main>'
           1: from tmp.rb:2:in `block in <main>'
tmp.rb:2:in `block in <main>': stack level too deep (SystemStackError)
```

There is _no_ single bit of information that the prolem is caused by that lambda conversion.
An end user has no other way than to blame tmp.rb:2 not tmp.rb:4, because the backtrace says so.

This is really bad.  Think of for instance the block was from another library.  The library authors suddenly get angry bug reports due to some random other guy turned their proc into lambda.  This is nonsense.

Non-lambda to lambda conversion disturbs the boundary point of responsibility.  Should not be allowed I believe.

----------------------------------------
Feature #15973: Make it so Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-79307

* Author: alanwu (Alan Wu)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
When Kernel#lambda receives a Proc that is not a lambda,
it returns it without modification. l propose changing `Kernel#lambda`
so it always returns a lambda.

Calling a method called lambda and having it effective do nothing was
not very intuitive.

https://github.com/ruby/ruby/pull/2262

Judging from marcandre's investigation here: https://bugs.ruby-lang.org/issues/15620#note-1
changing the behavior should not cause much breakage, if any. 


This also happens to fix [Bug #15620]



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