ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:93482] [Ruby master Feature#15973] Make Kernel#lambda always return lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
@ 2019-07-02 13:20 ` XrXr
  2019-07-02 13:31 ` [ruby-core:93484] " matz
                   ` (35 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: XrXr @ 2019-07-02 13:20 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been reported by alanwu (Alan Wu).

----------------------------------------
Feature #15973: Make Kernel#lambda always return lambda
https://bugs.ruby-lang.org/issues/15973

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93484] [Ruby master Feature#15973] Make Kernel#lambda always return lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
  2019-07-02 13:20 ` [ruby-core:93482] [Ruby master Feature#15973] Make Kernel#lambda always return lambda XrXr
@ 2019-07-02 13:31 ` matz
  2019-07-02 20:49 ` [ruby-core:93502] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda eregontp
                   ` (34 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: matz @ 2019-07-02 13:31 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by matz (Yukihiro Matsumoto).


I agree. Even though we have to investigate how big the consequence of the change first.

Matz.


----------------------------------------
Feature #15973: Make Kernel#lambda always return lambda
https://bugs.ruby-lang.org/issues/15973#change-79034

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93502] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
  2019-07-02 13:20 ` [ruby-core:93482] [Ruby master Feature#15973] Make Kernel#lambda always return lambda XrXr
  2019-07-02 13:31 ` [ruby-core:93484] " matz
@ 2019-07-02 20:49 ` eregontp
  2019-07-03  2:03 ` [ruby-core:93506] " shyouhei
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2019-07-02 20:49 UTC (permalink / raw)
  To: ruby-core

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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93506] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2019-07-02 20:49 ` [ruby-core:93502] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda eregontp
@ 2019-07-03  2:03 ` shyouhei
  2019-07-08  0:20 ` [ruby-core:93597] " XrXr
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: shyouhei @ 2019-07-03  2:03 UTC (permalink / raw)
  To: ruby-core

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


No.  I'm against it.  We have discussed this before multiple times.  See the issued I linked just now.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93597] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2019-07-03  2:03 ` [ruby-core:93506] " shyouhei
@ 2019-07-08  0:20 ` XrXr
  2019-07-08  0:35 ` [ruby-core:93598] " XrXr
                   ` (31 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: XrXr @ 2019-07-08  0:20 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by alanwu (Alan Wu).


The 2.4 spec is a bit problematic since it makes it impossible to forward a
block to `Kernel#lambda` with a block pass. In the rest of the language
forwarding a block has no effect on semantics compared to passing one
literally. The idea of literal blocks being different from non-literal ones
exists _only_ in the case of `Kernel#lambda`.

A concept at odds with the rest of the language specific to one single method
is sure to surprise. Special one-off concepts make the language harder to learn
and add complications to implementaitons.

As others have pointed out, it's already possible to transform a proc into a
lambda-proc via `define_method`. My proposal isn't adding anything new with
regards to messing with the perscribed usage of code within blocks.

Transforming a proc into a lambda-proc is certainly a sharp tool. For me it
falls in the same category as `instance_variable_set` and `const_set`. However,
I think the situation in which it ends up being surprinsg is very rare.
`return` within a `Proc.new do ...` comes up rarely as is.

Is "someone might misuse this in specific sutations" a good reason to keep an
ad-hoc concept in the language? For me, no.


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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93598] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2019-07-08  0:20 ` [ruby-core:93597] " XrXr
@ 2019-07-08  0:35 ` XrXr
  2019-07-08 13:49 ` [ruby-core:93615] " shyouhei
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: XrXr @ 2019-07-08  0:35 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by alanwu (Alan Wu).


I would also like to note that if we revert back to the behavior in 2.4, code that relied on `lambda` without block will not have an easy upgrade path.


```ruby
def make_a_lambda
  lambda
end
```

is not equivalent to

```ruby
def make_a_lambda(&block)
  lambda(&block)
end
```

under 2.4 spec.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93615] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (5 preceding siblings ...)
  2019-07-08  0:35 ` [ruby-core:93598] " XrXr
@ 2019-07-08 13:49 ` shyouhei
  2019-07-09 14:32 ` [ruby-core:93635] " XrXr
                   ` (29 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: shyouhei @ 2019-07-08 13:49 UTC (permalink / raw)
  To: ruby-core

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


"It's already broken, why not break it more" is not what I can follow.

Can I ask you why you need this feature?  If this not more than a matter of consistency, I would like to second @eregon's proposal: lambdas without literal blocks to be prohibited at all.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93635] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (6 preceding siblings ...)
  2019-07-08 13:49 ` [ruby-core:93615] " shyouhei
@ 2019-07-09 14:32 ` XrXr
  2019-07-09 14:38 ` [ruby-core:93636] " eregontp
                   ` (28 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: XrXr @ 2019-07-09 14:32 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by alanwu (Alan Wu).


> Can I ask you why you need this feature? 

I want to be able to forward a block to `Kernel#lambda`.

`Kernel#lambda` is in a weird spot. Even though it's a method, making it behave like one has the unfortunate side-effect of allowing proc transformation.
On the other hand, restricting it to just literal blocks is fairly magical and makes it just another way to do stabby lambda.
It seems like there is no perfect solution here.
I don't feel too strongly about my proposal. Banning block-pass to `Kernel#lambda` sounds good to me too if others are not comfortable with making proc-to-lambda transformation more accessible.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93636] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (7 preceding siblings ...)
  2019-07-09 14:32 ` [ruby-core:93635] " XrXr
@ 2019-07-09 14:38 ` eregontp
  2019-07-11  5:20 ` [ruby-core:93661] " akr
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2019-07-09 14:38 UTC (permalink / raw)
  To: ruby-core

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


alanwu (Alan Wu) wrote:
> `Kernel#lambda` is in a weird spot. Even though it's a method, making it behave like one has the unfortunate side-effect of allowing proc transformation.

Yes, the semantics of `Kernel#lambda` have always been a bit weird because no method should be allowed to convert a Proc to a lambda and inversely.
And visually, `lambda { ... }` receives a block, which is a non-lambda Proc.

My point of view is `lambda` is a relic of the past, and we should use `-> { ... }` instead, which has clear semantics and obviously you can't pass a pre-existing block to it.
Yes, I think we should raise `lambda(&existing_block)` as that can't behave intuitively (it seems either useless or confusing).

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93661] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (8 preceding siblings ...)
  2019-07-09 14:38 ` [ruby-core:93636] " eregontp
@ 2019-07-11  5:20 ` akr
  2019-07-11  8:18 ` [ruby-core:93674] " matz
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: akr @ 2019-07-11  5:20 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by akr (Akira Tanaka).


I'm against it.

Changing lambda <-> proc can violate the intent of programmers who write a block.

It seems good to raise an exception at lambda(&b) where b is (non-lambda) proc.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93674] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (9 preceding siblings ...)
  2019-07-11  5:20 ` [ruby-core:93661] " akr
@ 2019-07-11  8:18 ` matz
  2019-07-11 10:00 ` [ruby-core:93679] " knu
                   ` (25 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: matz @ 2019-07-11  8:18 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by matz (Yukihiro Matsumoto).


In my opinion, `lambda` should return `lambda` object as a principle. We need to keep the discussion.
Maybe we can generate a delegating lambda object in this case.

Matz.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93679] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (10 preceding siblings ...)
  2019-07-11  8:18 ` [ruby-core:93674] " matz
@ 2019-07-11 10:00 ` knu
  2019-07-11 11:57 ` [ruby-core:93682] " ruby-core
                   ` (24 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: knu @ 2019-07-11 10:00 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by knu (Akinori MUSHA).


I don't think the lambda flag should be altered after the creation of a proc, because it's all up to the writer of a block how `return`/`break` etc. in a block should work.

What about just deprecate `lambda` in the long run in favor of the lambda literal `->() {}`?

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93682] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (11 preceding siblings ...)
  2019-07-11 10:00 ` [ruby-core:93679] " knu
@ 2019-07-11 11:57 ` ruby-core
  2019-07-11 16:27 ` [ruby-core:93692] " shyouhei
                   ` (23 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: ruby-core @ 2019-07-11 11:57 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by marcandre (Marc-Andre Lafortune).


knu (Akinori MUSHA) wrote:
> I don't think the lambda flag should be altered after the creation of a proc, because it's all up to the writer of a block how `return`/`break` etc. in it should work.
> 
> What about just deprecate `lambda` in the long run in favor of the lambda literal `->() {}`?

akr wrote similar opinion.

This same opinion would call for deprecation of `define_method(&block)`, which I believe would be a mistake.

I am assuming it is clear that `lambda(&block)` would never mutate `block` and return a new object that would be a lambda.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93692] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (12 preceding siblings ...)
  2019-07-11 11:57 ` [ruby-core:93682] " ruby-core
@ 2019-07-11 16:27 ` shyouhei
  2019-07-12  4:11 ` [ruby-core:93708] " XrXr
                   ` (22 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: shyouhei @ 2019-07-11 16:27 UTC (permalink / raw)
  To: ruby-core

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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93708] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (13 preceding siblings ...)
  2019-07-11 16:27 ` [ruby-core:93692] " shyouhei
@ 2019-07-12  4:11 ` XrXr
  2019-07-12  5:31 ` [ruby-core:93711] " shyouhei
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: XrXr @ 2019-07-12  4:11 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by alanwu (Alan Wu).


The idea to generate a delegating lambda seems to side-step a lot of the issues posted here.
For reference here are some quotes from the log in #15930:

```ruby
b = proc {|x| x }
lambda(&b) #=> lambda {|x| b[x] }
 
b = proc {|x, y, k:1| x }
lambda(&b) #=> lambda {|x, y, k:1| b[x, y, k:k] }
```
This preserves the `return` semantics in the original proc. I would imagine it would also add an entry to the call stack.
(side note, I think the default parameter evaluation has to be left to the original proc too since a `return` could be in there)

What do you folks think about this?

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93711] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (14 preceding siblings ...)
  2019-07-12  4:11 ` [ruby-core:93708] " XrXr
@ 2019-07-12  5:31 ` shyouhei
  2019-07-12  5:43 ` [ruby-core:93712] " akr
                   ` (20 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: shyouhei @ 2019-07-12  5:31 UTC (permalink / raw)
  To: ruby-core

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


Yes, I can compromise with delegation scheme, as long as it leaves its own frame in the call stack.  An optional method for a proc to prevent such delegation is desirable but can be added later.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93712] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (15 preceding siblings ...)
  2019-07-12  5:31 ` [ruby-core:93711] " shyouhei
@ 2019-07-12  5:43 ` akr
  2019-07-12  9:30 ` [ruby-core:93717] " eregontp
                   ` (19 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: akr @ 2019-07-12  5:43 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by akr (Akira Tanaka).


Eregon (Benoit Daloze) wrote:

> With current semantics, it returns `:early_return`.
> With the proposed change, it returns `:method_return_value`.
> That's very surprising, isn't it?

I agree.

The lambda-ness of Proc object affects control flow: the behavior of "return" and "break".

If lambda(&b) changes the lambda-ness of b, two control flow can exist.
I think no programmer want to consider two control flow when implementing one block.




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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93717] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (16 preceding siblings ...)
  2019-07-12  5:43 ` [ruby-core:93712] " akr
@ 2019-07-12  9:30 ` eregontp
  2019-07-17 21:20 ` [ruby-core:93822] " XrXr
                   ` (18 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2019-07-12  9:30 UTC (permalink / raw)
  To: ruby-core

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


alanwu (Alan Wu) wrote:
> The idea to generate a delegating lambda seems to side-step a lot of the issues posted here.

So then, would it be the same semantics as this?

```ruby
b = proc {|x, y, k:1| x }
l = lambda { |*args, **kwargs, &block| b.call(*args, **kwargs, &block) }
```

I think the lambda cannot have the same (in the code) arguments as the proc, otherwise https://bugs.ruby-lang.org/issues/15973#note-16 would fail too.

@alanwu Can you present use case(s) for turning procs into lambdas?
So far I only see consistency but the delegating lambda is not that consistent with #lambda with a literal block.
Without a good use-case, I think raising on #lambda without a literal block would be the safest and least surprising.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93822] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (17 preceding siblings ...)
  2019-07-12  9:30 ` [ruby-core:93717] " eregontp
@ 2019-07-17 21:20 ` XrXr
  2019-07-26 17:53 ` [ruby-core:93935] " daniel
                   ` (17 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: XrXr @ 2019-07-17 21:20 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by alanwu (Alan Wu).


> Can you present use case(s) for turning procs into lambdas?

One use case is reading the parameters of blocks as if they were written for a method definition: https://bugs.ruby-lang.org/issues/9777#note-11
Another one is getting lambda style parameter checking for the incoming block. msgpack-ruby does this through the CAPI: https://github.com/msgpack/msgpack-ruby/blob/b48f9580bfd33be6a86652f10a41bd691a7d0c91/ext/msgpack/unpacker_class.c#L367

I asked for opinions about the delegation scheme because it seems like a good way to go if we _must_ return a lambda. At the time I didn't make up my mind as to whether it would be a good idea to return one.
I now believe that banning everything but the literal block form lambda is overall better. `lambda` being a method exposes it to many different ways of calling it, some of which don't have obvious semantics.
We can pick a semantic for lambda(&thing), but there will always be some percentage of users that find the behavior surprising. We can minimizes surprises, but we can't eliminate it, as long
as `lambda` is a method.

To illustrate, here are two more ways to call into `Kernel#lambda` that are hard to define good semantics for: `super` (zsuper) and `method(:lambda).call {}`. Right now zsuper creates a lambda while
`method(:lambda).call {}` doesn't. I'm not sure what these should do and different people probably have different ideas.

I think `lambda` was supposed to be a psudo-keyword but implementing it as a method is unfortunately exposing it to a whole array of usage that were not considered.
If we can promote it to a psudo-keyword, that would be best. Failing that, banning `lambda(&thing)` at least removes one source of surprise with clear messaging.

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:93935] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (18 preceding siblings ...)
  2019-07-17 21:20 ` [ruby-core:93822] " XrXr
@ 2019-07-26 17:53 ` daniel
  2019-07-30  8:08 ` [ruby-core:94038] " ko1
                   ` (16 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: daniel @ 2019-07-26 17:53 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by Dan0042 (Daniel DeLorme).


I think the delegating lambda idea doesn't really work. I mean, it doesn't *do* anything. You just get a lambda that behaves like a proc. It just changes the return value of `Proc#lambda?` which I don't think has any benefit by itself. In fact it might be counterproductive to hide the fact that this Proc object really behaves like a proc and not a lambda.

It seems the main use case for proc->lambda conversion is to validate the Proc defines the correct parameters? But I believe it's quite ok to let the writer of the Proc worry about that. And if you *really* want a lambda you should just enforce it.
```ruby
def foo(lambda)
  lambda.lambda? or raise ArgumentError
  lambda.call(1,2,3)
end
foo -> (x) do
  42
end
#=> ArgumentError (wrong number of arguments (given 3, expected 1))
```
So I haven't yet seen a single good use case for this conversion, and I can't think of one despite trying. You'd need a situation where you want a Proc to have either proc or lambda behavior based on a condition. That's....

On the other hand there's a good case to make for just letting the programmer do what s/he wants. If you want to convert a proc into a lambda presumably you have a reason for doing so, and understand the consequences. The only real danger is if a proc was converted to a lambda *inadvertently* . But I can't come up with a realistic situation where this could occur. All the "surprising" examples I've seen are contrived and in fact not surprising at all. If a method expects a proc and you give it a lambda, that's no different than giving it an Integer or any other object that fails expectations. I honestly can't think of a situation where you'd want `lambda(&myproc)` to just pass through the proc unchanged; if you don't want to convert you'd just use `myproc` directly, right?

In the end it seems the only benefit of proc<->lambda conversion is for the sake of consistency of the `proc` and `lambda` methods? I guess that makes some sense, because this situation is definitely weird and surprising:
``` ruby
lambda{ }                                         #=> #<Proc:0x000055e295d1d648@(irb):1 (lambda)> 
class X;def lambda;super;end;end; X.new.lambda{ } #=> #<Proc:0x000055e295d0b0d8@(irb):2 (lambda)>
lambda(&proc{ })                                  #=> #<Proc:0x000055e295d08d88@(irb):3>
method(:lambda).call{ }                           #=> #<Proc:0x000055e295d01da8@(irb):4>
def foo(&b);lambda(&b);end; foo{ }                #=> #<Proc:0x000055e295cf4810@(irb):6 (lambda)>
```

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

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:94038] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (19 preceding siblings ...)
  2019-07-26 17:53 ` [ruby-core:93935] " daniel
@ 2019-07-30  8:08 ` ko1
  2019-07-30 13:31 ` [ruby-core:94054] " matz
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: ko1 @ 2019-07-30  8:08 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by ko1 (Koichi Sasada).

Assignee set to matz (Yukihiro Matsumoto)
Status changed from Open to Assigned

does anyone can write a discussion summary? :p

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

* Author: alanwu (Alan Wu)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* 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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:94054] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (20 preceding siblings ...)
  2019-07-30  8:08 ` [ruby-core:94038] " ko1
@ 2019-07-30 13:31 ` matz
  2019-07-30 16:32 ` [ruby-core:94058] " daniel
                   ` (14 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: matz @ 2019-07-30 13:31 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by matz (Yukihiro Matsumoto).


I agree with @akr here, as long as `lambda` with a block argument warns.
We need to keep compatibility. But I think we should warn this inconsistent behavior.

Matz.

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

* Author: alanwu (Alan Wu)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* 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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:94058] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (21 preceding siblings ...)
  2019-07-30 13:31 ` [ruby-core:94054] " matz
@ 2019-07-30 16:32 ` daniel
  2019-08-05 16:04 ` [ruby-core:94150] " daniel
                   ` (13 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: daniel @ 2019-07-30 16:32 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by Dan0042 (Daniel DeLorme).


akr (Akira Tanaka) wrote:
> The lambda-ness of Proc object affects control flow: the behavior of "return" and "break".
> 
> If lambda(&b) changes the lambda-ness of b, two control flow can exist.
> I think no programmer want to consider two control flow when implementing one block.

I think everyone can agree with that. The issue I guess is **should it be allowed to define a lambda using block syntax**, with the two main viewpoints being

A. `lambda()` and `define_method()` already allow this, so it's a well established pattern. So why not allow `my_anonymous_function_dsl{  }` ? In this case the one writing the block knows it's supposed to have lambda semantics. In 2.5 it became allowed in certain circumstances but that was apparently unintended (#15620)? A search through major gems showed no incompatibilities. Numerous tickets through the years indicate current behavior is surprising to many.

B. `lambda()` and `define_method()` should never have allowed this; proc/lambda semantics should be defined **lexically**. Changing it dynamically is surprising. We can't break compatibility but we should not dig ourselves any deeper. Use `my_anonymous_function_dsl&->{  }` instead. It's a change in behavior so there may be incompatibility issues.

Does this seem like an accurate summary?

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

* Author: alanwu (Alan Wu)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* 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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:94150] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (22 preceding siblings ...)
  2019-07-30 16:32 ` [ruby-core:94058] " daniel
@ 2019-08-05 16:04 ` daniel
  2019-09-28  3:46 ` [ruby-core:95140] [Ruby master Feature#15973] Let " XrXr
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: daniel @ 2019-08-05 16:04 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by Dan0042 (Daniel DeLorme).


This may be irrelevant but I would like to point out that proc->lambda conversion was supported in ruby 1.8

```ruby
b = Proc.new{ return 42 }
b.call          #=> LocalJumpError: unexpected return
lambda(&b).call #=> 42
```

I'm not sure if the change was intentional or not, but this feature request is really about restoring lost behavior, not introducing new one. :-)


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

* Author: alanwu (Alan Wu)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* 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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:95140] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (23 preceding siblings ...)
  2019-08-05 16:04 ` [ruby-core:94150] " daniel
@ 2019-09-28  3:46 ` XrXr
  2019-12-21 21:09 ` [ruby-core:96397] " eregontp
                   ` (11 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: XrXr @ 2019-09-28  3:46 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by alanwu (Alan Wu).


I have updated my fix for [Bug #15620] to also issue a warning in cases it
returns the argument it receives without modification.

Since both 2.5.x and 2.6.x has [Bug #15620], there may be code in the wild that
depend on the unintended lambda conversion behavior. It might make sense to
put the 2.4.x behavior back for 2.7.0-preview2 to find out whether it's an
issue.

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


----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-81779

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96397] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (24 preceding siblings ...)
  2019-09-28  3:46 ` [ruby-core:95140] [Ruby master Feature#15973] Let " XrXr
@ 2019-12-21 21:09 ` eregontp
  2019-12-24 17:35 ` [ruby-core:96459] " ko1
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2019-12-21 21:09 UTC (permalink / raw)
  To: ruby-core

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

Target version set to 2.8

@matz Is it OK to warn for this in the next Ruby version?

I think it's going to highlight wrong usages (good) and I would expect there are very few usages of `lambda(&existing_proc)`.

The warnings were implemented in https://github.com/ruby/ruby/pull/2289 by @alanwu but @ko1 said we should postpone them as it's too late for 2.7:
https://github.com/ruby/ruby/pull/2289#issuecomment-567820054

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83318

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96459] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (25 preceding siblings ...)
  2019-12-21 21:09 ` [ruby-core:96397] " eregontp
@ 2019-12-24 17:35 ` ko1
  2019-12-24 17:37 ` [ruby-core:96460] " ko1
                   ` (9 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: ko1 @ 2019-12-24 17:35 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by ko1 (Koichi Sasada).


This is one idea: how about to prohibit `lambda(&...)` creation? (block literal is always prohibited)?

3.0: deprecation warning and show 3.1 will raise exception.
3.1: raise exception for `lambda(&...)`

same as `proc`.


----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83383

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96460] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (26 preceding siblings ...)
  2019-12-24 17:35 ` [ruby-core:96459] " ko1
@ 2019-12-24 17:37 ` ko1
  2019-12-25 11:04 ` [ruby-core:96463] " eregontp
                   ` (8 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: ko1 @ 2019-12-24 17:37 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by ko1 (Koichi Sasada).


more aggressive proposal is obsolete `lambda` call, and use `->` (maybe it is too aggressive).


----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83384

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96463] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (27 preceding siblings ...)
  2019-12-24 17:37 ` [ruby-core:96460] " ko1
@ 2019-12-25 11:04 ` eregontp
  2019-12-25 11:13 ` [ruby-core:96464] " eregontp
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2019-12-25 11:04 UTC (permalink / raw)
  To: ruby-core

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


ko1 (Koichi Sasada) wrote:
> This is one idea: how about to prohibit `lambda(&...)` method call? (block literal is always prohibited)

I think you mean non-literal block (`&`) becomes prohibited.

> 3.0: deprecation warning and show 3.1 will raise exception for `lambda(&...)`
> 3.1: raise exception for `lambda(&...)`
> 
> same as `proc`.

And whether it's `lambda(&...)` or `lambda { }` is detected by the lambda method itself (like for the warning)?

That sounds good to me.

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83391

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96464] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (28 preceding siblings ...)
  2019-12-25 11:04 ` [ruby-core:96463] " eregontp
@ 2019-12-25 11:13 ` eregontp
  2019-12-25 11:15 ` [ruby-core:96465] " eregontp
                   ` (6 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2019-12-25 11:13 UTC (permalink / raw)
  To: ruby-core

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


ko1 (Koichi Sasada) wrote:
> more aggressive proposal is obsolete `lambda` call, and use `->` (maybe it is too aggressive).

Sounds even better to me, but I guess that might be disruptive for everyone to adopt `-> {}` style.
It would be interesting to see what matz thinks about this.

`->` exists since at least 2.0, so it shouldn't be a compatibility issue to use it.

From the point of view of a Ruby VM, not having to handle `#lambda` magically changing the semantics of the passed block would be great,
because it's really awkward and hard to check if the block is literal or not (considering `lambda` can be `alias`-ed).

It would also simplify the semantics for the user: `method_call { ... }` is always a non-lambda Proc, and `-> {}` is the only way for a lambda.

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83392

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96465] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (29 preceding siblings ...)
  2019-12-25 11:13 ` [ruby-core:96464] " eregontp
@ 2019-12-25 11:15 ` eregontp
  2019-12-25 11:20 ` [ruby-core:96467] " zverok.offline
                   ` (5 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2019-12-25 11:15 UTC (permalink / raw)
  To: ruby-core

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


On a related note I think we should also prohibit `define_method(&non_lambda)` because that confusingly treats the same block body differently (e.g., the same `return` in the code means something different).

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83393

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96467] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (30 preceding siblings ...)
  2019-12-25 11:15 ` [ruby-core:96465] " eregontp
@ 2019-12-25 11:20 ` zverok.offline
  2019-12-25 11:51 ` [ruby-core:96469] " eregontp
                   ` (4 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: zverok.offline @ 2019-12-25 11:20 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by zverok (Victor Shepelev).


> On a related note I think we should also prohibit `define_method(&non_lambda)` because that confusingly treats the same block body differently (e.g., the same return in the code means something different).

Seem it will have an awful impact on any DSLs?..

Like

```ruby
skip_if { |user| user.admin? }

# ...implemented as
def skip_if(&condition)
  define_method(:skip?, &condition)
end
```

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83394

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96469] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (31 preceding siblings ...)
  2019-12-25 11:20 ` [ruby-core:96467] " zverok.offline
@ 2019-12-25 11:51 ` eregontp
  2019-12-25 19:34 ` [ruby-core:96475] " zverok.offline
                   ` (3 subsequent siblings)
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2019-12-25 11:51 UTC (permalink / raw)
  To: ruby-core

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


zverok (Victor Shepelev) wrote:
> Seem it will have an awful impact on any DSLs?..

Which is IMHO a perfect example of how dangerous that is.
What if it's `skip_if { |user| return 42 }`?
Do you expect that to return from the surrounding method or to return from the block?
For any non-lambda Proc it should mean return from the surrounding method, `define_method` breaks that (by converting a proc to a lambda implictly).

```ruby
# Assuming your definition of skip_if

skip_if { |user| return 42 } # should return from the surrounding method but does not
skip?(1) # but it does not, it just returns from the block!

proc { |user| return 43 }.call # returns from the surrounding method
raise "unreachable" # never reached, as expected
```

There is an easy workaround:
```ruby
def skip_if(&condition)
  define_method(:skip?, -> *args { condition.call(*args) })
end
```

With that `skip?(1)` returns from the surrounding method, as it should like every other literal block.

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83396

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96475] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (32 preceding siblings ...)
  2019-12-25 11:51 ` [ruby-core:96469] " eregontp
@ 2019-12-25 19:34 ` zverok.offline
  2019-12-26  7:49   ` [ruby-core:96490] " atdot
  2019-12-26 20:46 ` [ruby-core:96500] " daniel
                   ` (2 subsequent siblings)
  36 siblings, 1 reply; 38+ messages in thread
From: zverok.offline @ 2019-12-25 19:34 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by zverok (Victor Shepelev).


Ugh, let me be a bit philosophical here (how many times I promised myself to not engage in discussions about Ruby's "spirit"? I've lost count.)

I understand the point you are speaking from (language implementer's background, who constantly fights with "dangerously illogical" parts), but for me, one of the key points of Ruby's attractiveness is how far it goes to reduce boilerplate in a logical and humane way. There is a non-neglectible gap between "human" consistency and "computer" (formal) consistency. 

I am writing in Ruby for >15 years now (and teaching it for >5 years, and blah-blah-blah). I've implemented and used metric shit-ton of DSLs. So, for me and my intuition is experience, it is just this way:
```ruby
skip_if { |user| return 42 }
```
...is something that will behave "unexpectedly"? Yes. 
Have I met a lot of cases when it was really written and shot somebody in the head? No.
What if somebody really happens to meet with this case and is surprised? I believe they'll spend some time to wrap they head about it. That's a price we pay to have "complex language for writing simple code".

Now, when I see this:
```ruby
def skip_if(&condition)
  define_method(:skip?, &condition)
end
```
...which "should" be "simply workarounded" to this:
```ruby
def skip_if(&condition)
  define_method(:skip?, -> *args { condition.call(*args) })
end
```
...I see it as "your language implementation is really busy doing its important things. So it will not help you to write clean and obvious code. I (language implementation) see what you want to do (define methods implementation from a block in the variable), and I know how to fix it (block should be converted to lambda), but you (puny human) should do it with your own soft hands".

It _can and will_ harm the will to write simple helping DSLs (which, one may argue, "is a good thing" anyways?..)

Why, then, bother with "all this proc vs lambda nonsense" (as some may, and do, argue)? All in all, "you don't need this complexity at all", right? Because

```ruby
sources.zip(targets).map { |src, tgt| tgt.write(src) }
```
...can be "easily workarounded" as this:
```ruby
sources.zip(targets).map(->(arguments) { arguments[1].write(arguments[0]) } }
```
...and everything suddenly becames more consistent and homogenous...

We can go this way really far, honestly :)

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83402

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96490] Re: [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
  2019-12-25 19:34 ` [ruby-core:96475] " zverok.offline
@ 2019-12-26  7:49   ` atdot
  0 siblings, 0 replies; 38+ messages in thread
From: atdot @ 2019-12-26  7:49 UTC (permalink / raw)
  To: Ruby developers

Ok, make a new ticket about define_method. How about lambda?

Koichi

> 2019/12/26 4:34、zverok.offline@gmail.comのメール:
> 
> Issue #15973 has been updated by zverok (Victor Shepelev).
> 
> 
> Ugh, let me be a bit philosophical here (how many times I promised myself to not engage in discussions about Ruby's "spirit"? I've lost count.)
> 
> I understand the point you are speaking from (language implementer's background, who constantly fights with "dangerously illogical" parts), but for me, one of the key points of Ruby's attractiveness is how far it goes to reduce boilerplate in a logical and humane way. There is a non-neglectible gap between "human" consistency and "computer" (formal) consistency. 
> 
> I am writing in Ruby for >15 years now (and teaching it for >5 years, and blah-blah-blah). I've implemented and used metric shit-ton of DSLs. So, for me and my intuition is experience, it is just this way:
> ```ruby
> skip_if { |user| return 42 }
> ```
> ...is something that will behave "unexpectedly"? Yes. 
> Have I met a lot of cases when it was really written and shot somebody in the head? No.
> What if somebody really happens to meet with this case and is surprised? I believe they'll spend some time to wrap they head about it. That's a price we pay to have "complex language for writing simple code".
> 
> Now, when I see this:
> ```ruby
> def skip_if(&condition)
>  define_method(:skip?, &condition)
> end
> ```
> ...which "should" be "simply workarounded" to this:
> ```ruby
> def skip_if(&condition)
>  define_method(:skip?, -> *args { condition.call(*args) })
> end
> ```
> ...I see it as "your language implementation is really busy doing its important things. So it will not help you to write clean and obvious code. I (language implementation) see what you want to do (define methods implementation from a block in the variable), and I know how to fix it (block should be converted to lambda), but you (puny human) should do it with your own soft hands".
> 
> It _can and will_ harm the will to write simple helping DSLs (which, one may argue, "is a good thing" anyways?..)
> 
> Why, then, bother with "all this proc vs lambda nonsense" (as some may, and do, argue)? All in all, "you don't need this complexity at all", right? Because
> 
> ```ruby
> sources.zip(targets).map { |src, tgt| tgt.write(src) }
> ```
> ...can be "easily workarounded" as this:
> ```ruby
> sources.zip(targets).map(->(arguments) { arguments[1].write(arguments[0]) } }
> ```
> ...and everything suddenly becames more consistent and homogenous...
> 
> We can go this way really far, honestly :)
> 
> ----------------------------------------
> Feature #15973: Let Kernel#lambda always return a lambda
> https://bugs.ruby-lang.org/issues/15973#change-83402
> 
> * Author: alanwu (Alan Wu)
> * Status: Assigned
> * Priority: Normal
> * Assignee: matz (Yukihiro Matsumoto)
> * Target version: 2.8
> ----------------------------------------
> When Kernel#lambda receives a Proc that is not a lambda,
> it returns it without modification. l propose to change `Kernel#lambda`
> so it always returns a lambda.
> 
> Calling a method called lambda and having it do nothing in effect is
> 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>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96500] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (33 preceding siblings ...)
  2019-12-25 19:34 ` [ruby-core:96475] " zverok.offline
@ 2019-12-26 20:46 ` daniel
  2020-01-10 22:21 ` [ruby-core:96767] " eregontp
  2020-01-16  8:12 ` [ruby-core:96900] " ko1
  36 siblings, 0 replies; 38+ messages in thread
From: daniel @ 2019-12-26 20:46 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by Dan0042 (Daniel DeLorme).


> one of the key points of Ruby's attractiveness is how far it goes to reduce boilerplate in a logical and humane way. There is a non-neglectible gap between "human" consistency and "computer" (formal) consistency.

+1, very much. I'm glad there's still someone who cares about usefulness over ["consistency"](https://www.google.com/search?q=ralph+waldo+emerson+quote+foolish+consistency)

Converting a proc to a lambda is very useful for DSLs. And generally speaking it's empowering to programmers. Maybe a bit dangerous, but I can take care of myself. I really don't need or want to be "protected" from powerful yet "unexpected" behaviors. This ticket was about making `lambda` always return a lambda; at which point did it become about preventing this from happening?

I understand there's many who are emotionally invested into making ruby stricter and easier to implement/optimize, but at least there should be good alternatives for what the proc->lambda conversion allows.

For DSLs:

```ruby
#a block is specified, and this DSL is documented to have lambda semantics, so we need to convert the proc to lambda
register_lambda(:xyz) do |x,y,z|
  return x+y+z
end

#or a pretty syntax to pass a lambda as a block
register_lambda(:xyz)->(x,y,z) do
  return x+y+z
end

#because this is ugly, honestly
register_lambda(:xyz, &->(x,y,z) do
  return x+y+z
end)
```

Or what about:

```ruby
block = proc{ |x,y,z=1| }
block.parameters #=> [[:opt, :x], [:opt, :y], [:opt, :z]]
                 # yes I know that all params are optional in a proc,
                 # but I wanted to know which have a default value and which don't
lambda(&block).parameters #=> [[:req, :x], [:req, :y], [:opt, :z]]
                          # this tells me what I wanted to know in a simple and easy way
```

Beyond the argument that this is dangerous (yes it is), there's also the fact that, used wisely, this is sometimes **useful**.

> it's really awkward and hard to check if the block is literal or not (considering lambda can be alias-ed).

Then wouldn't it be really simple if all blocks were converted to lambdas regardless of being literal or not? KISS.

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83432

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96767] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (34 preceding siblings ...)
  2019-12-26 20:46 ` [ruby-core:96500] " daniel
@ 2020-01-10 22:21 ` eregontp
  2020-01-16  8:12 ` [ruby-core:96900] " ko1
  36 siblings, 0 replies; 38+ messages in thread
From: eregontp @ 2020-01-10 22:21 UTC (permalink / raw)
  To: ruby-core

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


Yes, sorry I should not have mentioned `define_method` here, even though it's related it's not the main topic.
I'll make a new issue for it.

----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83761

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [ruby-core:96900] [Ruby master Feature#15973] Let Kernel#lambda always return a lambda
       [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
                   ` (35 preceding siblings ...)
  2020-01-10 22:21 ` [ruby-core:96767] " eregontp
@ 2020-01-16  8:12 ` ko1
  36 siblings, 0 replies; 38+ messages in thread
From: ko1 @ 2020-01-16  8:12 UTC (permalink / raw)
  To: ruby-core

Issue #15973 has been updated by ko1 (Koichi Sasada).


Quote from today's devmeeting.

Discussion:

* Proposing to deprecate `lambda(&block)` (`lambda` call with `Proc` object as block)
* Benefits of obsoleting `lambda`?
    * Simplify for new Ruby developers. (no duplicated syntax.)
    * Suspend for short term (for years)
* Don't want more incompatibilities just after Ruby 2.7
* Migration pass to deprecate `lambda(&block)`.
    1. Print warning at 3.0. (No compatibility layer.)
        * “The lambda call is meaningless. Delete it.”
        * “Delete meaningless lambda”
    3. Raises error at 3.1 (or 3.2, ...)

Conclusion:

* `lambda(&b)` will be prohibited.
    * Print warning at 3.0. (No compatibility layer.)
    * Raises error at 3.1 (or 3.2, ...)


----------------------------------------
Feature #15973: Let Kernel#lambda always return a lambda
https://bugs.ruby-lang.org/issues/15973#change-83917

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

Calling a method called lambda and having it do nothing in effect is
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/

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2020-01-16  8:12 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-15973.20190702132050@ruby-lang.org>
2019-07-02 13:20 ` [ruby-core:93482] [Ruby master Feature#15973] Make Kernel#lambda always return lambda XrXr
2019-07-02 13:31 ` [ruby-core:93484] " matz
2019-07-02 20:49 ` [ruby-core:93502] [Ruby master Feature#15973] Make it so Kernel#lambda always return a lambda eregontp
2019-07-03  2:03 ` [ruby-core:93506] " shyouhei
2019-07-08  0:20 ` [ruby-core:93597] " XrXr
2019-07-08  0:35 ` [ruby-core:93598] " XrXr
2019-07-08 13:49 ` [ruby-core:93615] " shyouhei
2019-07-09 14:32 ` [ruby-core:93635] " XrXr
2019-07-09 14:38 ` [ruby-core:93636] " eregontp
2019-07-11  5:20 ` [ruby-core:93661] " akr
2019-07-11  8:18 ` [ruby-core:93674] " matz
2019-07-11 10:00 ` [ruby-core:93679] " knu
2019-07-11 11:57 ` [ruby-core:93682] " ruby-core
2019-07-11 16:27 ` [ruby-core:93692] " shyouhei
2019-07-12  4:11 ` [ruby-core:93708] " XrXr
2019-07-12  5:31 ` [ruby-core:93711] " shyouhei
2019-07-12  5:43 ` [ruby-core:93712] " akr
2019-07-12  9:30 ` [ruby-core:93717] " eregontp
2019-07-17 21:20 ` [ruby-core:93822] " XrXr
2019-07-26 17:53 ` [ruby-core:93935] " daniel
2019-07-30  8:08 ` [ruby-core:94038] " ko1
2019-07-30 13:31 ` [ruby-core:94054] " matz
2019-07-30 16:32 ` [ruby-core:94058] " daniel
2019-08-05 16:04 ` [ruby-core:94150] " daniel
2019-09-28  3:46 ` [ruby-core:95140] [Ruby master Feature#15973] Let " XrXr
2019-12-21 21:09 ` [ruby-core:96397] " eregontp
2019-12-24 17:35 ` [ruby-core:96459] " ko1
2019-12-24 17:37 ` [ruby-core:96460] " ko1
2019-12-25 11:04 ` [ruby-core:96463] " eregontp
2019-12-25 11:13 ` [ruby-core:96464] " eregontp
2019-12-25 11:15 ` [ruby-core:96465] " eregontp
2019-12-25 11:20 ` [ruby-core:96467] " zverok.offline
2019-12-25 11:51 ` [ruby-core:96469] " eregontp
2019-12-25 19:34 ` [ruby-core:96475] " zverok.offline
2019-12-26  7:49   ` [ruby-core:96490] " atdot
2019-12-26 20:46 ` [ruby-core:96500] " daniel
2020-01-10 22:21 ` [ruby-core:96767] " eregontp
2020-01-16  8:12 ` [ruby-core:96900] " ko1

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).