New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] break, next and return and blocks #420
Comments
"return" escaping closures is the same in other languages, such as scala. That's why it's generally discouraged. |
Maybe, that's not my point though. My point is that I shouldn't have to think about whether the block will be captured or not when I want to exit it early. |
@jhass I think what you propose makes total sense. For example this code: def foo
bar do
return 1
end
end Without knowing what |
@jhass What about inline procs? f = ->{
break # disallowed
# Which of the following exists f?
next
return
} |
Mmh, tricky. Ruby differentiates whether it's Proc.lambda? apparently. # In Ruby
proc { break :a; :b }.call # LocalJumpError
proc { return :a; :b }.call # LocalJumpError
proc { next :a; :b }.call # :a
def foo; proc { break :a; :b }.call; :c; end; foo # LocalJumpError
def foo; proc { return :a; :b }.call; :c; end; foo # :a
def foo; proc { next :a; :b }.call; :c; end; foo # :c
def foo(a) a.call; :c; end; foo proc { break :a; :b } # LocalJumpError
def foo(a) a.call; :c; end; foo proc { return :a; :b } # LocalJumpError
def foo(a) a.call; :c; end; foo proc { next :a; :b } # :c
-> { break :a; :b }.call # :a
-> { return :a; :b }.call # :a
-> { next :a; :b }.call # :a
def foo; -> { break :a; :b }.call; :c; end; foo # :c
def foo; -> { return :a; :b }.call; :c; end; foo # :c
def foo; -> { next :a; :b }.call; :c; end; foo # :c
def foo(a) a.call; :c; end; foo -> { break :a; :b } # :c
def foo(a) a.call; :c; end; foo -> { return :a; :b } # :c
def foo(a) a.call; :c; end; foo -> { next :a; :b } # :c So the lambda is very close to an anonymous function but retains the block semantics of However that means Crystal would need to differentiate the So I'm not 100% sure, what do you think? PS: I think we also should work out proper names for the closures, so far I use "block" for |
What is the status on this one. I'm glad it will be changed to be consistent to the users intention (if I didn't misunderstand). |
Currently the rules for those keywords are dramatically different depending on whether the block is captured or not.
With a not captured block
break
exits from the calling method, the argument provides the methods return valuenext
exits from the block, the argument provides the blocks return valuereturn
exits from the method the block is defined inWith a captured block
break
is disallowednext
is disallowedreturn
exits from the block, the argument provides the blocks return valueProposal
I think it would be more consistent to swap the meanings for
next
andreturn
in the captured block case. This way, if the library decides to not capture the block or vice versa, less code on the caller side is affected. More importantly the caller doesn't need to think about whether the block is captured or not in order to understand what thereturn
inside a block is doing.The text was updated successfully, but these errors were encountered: