Issue #15973 has been updated by Eregon (Benoit Daloze).


I'm not sure changing this is good, because it can be very surprising for the code to change semantics dynamically.
Also, should `proc(&lambda)` make a non-lambda Proc then? It would be inconsistent if not.

As I said in https://bugs.ruby-lang.org/issues/15620#note-2, the current rule is AFAIK only change the semantics if a block is directly given, because the programmer means to use those semantics then.
If not, don't change the semantics as it would break the user (the Proc's code)'s intention.
The only exception to this is `define_method` with a pre-existing `Proc`, which is very rare, and understandably needed because methods should check arguments strictly. (maybe we don't need that exception)

I believe #15620 should be fixed on its own, it's a bug of the optimization.

Here is an example (a bit contrived, I'm tired):
```ruby
def foo(arg)
  early_check = Proc.new {
    # everything here assumes it will always be proc/non-lambda semantics
    return :early_return if arg > 3
  }

  # Some way for some external code to access `early_check`
  early_check = yield early_check

  early_check.call

  :method_return_value
end

p foo(4) { |pr| lambda(&pr) }
```

With current semantics, it returns `:early_return`.
With the proposed change, it returns `:method_return_value`.
That's very surprising, isn't it? The code clearly means it wants a non-local return to exit the method,
and yet somehow it was transformed into a local lambda return!

I think such a surprising transformation of user code should happen as little as possible, so I'm against this proposal.

Maybe we should simply forbid calling `proc`/`lambda` without a literal block (i.e., with an explicit Proc like `lambda(&pr)`), since it doesn't do anything useful ?
That would make more sense to me, and be in line with @ko1's recent changes to disallow things like `Proc.new`, etc without a block.

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

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