From: headius@...
Date: 2020-08-12T21:29:09+00:00
Subject: [ruby-core:99574] [Ruby master Bug#17105] A single `return` can return to two different places in a proc inside a lambda inside a method

Issue #17105 has been updated by headius (Charles Nutter).


Just to be clear I am +1 on single return target, as described here: https://github.com/jruby/jruby/issues/6350#issuecomment-669603740

In addition to the confusing (and possibly inefficient) behavior that results from having two possible return targets, there's also a bug potential here if someone "accidentally" allows a proc containing a return to escape from its lambda container. Rather than returning from the lambda as it should have done, it will now return from the next "returnable" scope, and likely interrupt execution in an unexpected way.

I would challenge anyone to explain why the current behavior *should* exist, since I can't think of a single valid use case. If there's no use case for a confusing "feature", we should remove it.

----------------------------------------
Bug #17105: A single `return` can return to two different places in a proc inside a lambda inside a method
https://bugs.ruby-lang.org/issues/17105#change-87042

* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
A single `return` in the source code might return to 2 different lexical places.
That seems wrong to me, as AFAIK all other control flow language constructs always jump to a single place.

```ruby
def m(call_proc)
  r = -> {
    # This single return in the source might exit the lambda or the method!
    proc = Proc.new { return :return }

    if call_proc
      proc.call
      :after_in_lambda
    else
      proc
    end
  }.call # returns here if call_proc

  if call_proc
    [:after_in_method, r]
  else
    r.call
    :never_reached
  end
end


p m(true)  # => [:after_in_method, :return]
p m(false) # :return
```

We're trying to figure out the semantics of `return` inside a proc in
https://github.com/oracle/truffleruby/issues/1488#issuecomment-669185675
and this behavior doesn't seem to make much sense.

@headius also seems to agree:
> I would consider that behavior to be incorrect; once the proc has escaped from the lambda, its return target is no longer valid. It should not return to a different place.
> https://github.com/jruby/jruby/issues/6350#issuecomment-669603740

So:
* is this behavior intentional? or is it a bug?
* what are actually the semantics of `return` inside a proc?

The semantics seem incredibly complicated to a point developers have no idea where `return` actually goes.
Also it must get even more complicated if one defines a `lambda` method as the block in `lambda { return }` is then non-deterministically a proc or lambda.



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