-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Semantics of block parameter's type restriction output type #10931
Comments
I prefer the consistency of nil-casting semantics for |
With non-captured blocks the return type is really not important, because there's no need to create a Proc for them. So, if a return type is omitted from a non-captured block, I chose to consider it as "I don't care about the return type". I don't think there's a use case where you'd want a non-captured block to have the For now we can fix the underscore issue (already fixed here: #10933 ). But I see no good reason to further change the semantic for non-captured blocks. |
Also nil-casting semantics is sometimes wrong for captured blocks. See #10911 |
Actually, I guess we could try (for 1.2) to have nil-casting semantics for non-captured blocks, if there's no explicit return type, but I'm afraid that's going to be a big breaking change. |
The benefit of different output type semantics is expressing intent. For example, |
I fear this is going to be a big breaking change as well. |
Do you think there will be significant amount of code relying of the current behavior? As a user I would rely on the mentioned intention. |
I really don't know. But we should just try it 🤷 |
It should be fairly unproblematic to change the semantics of With We can consider deprecating omitted output type, removing it in 2.0 and/or maybe re-adding it again with same semantics of |
This is a continuation of the discussions from #10467 (comment) and https://forum.crystal-lang.org/t/difference-between-underscore-and-empty-as-block-return-value/2998 and the problems faced with #10905.
Currently, there are two special values for the output type of a block parameter:
-> Nil
or->
(empty output type is equivalent toNil
)-> _
(underscore)Both effectively act as wildcards accepting any output type.
For a captured block parameter,
Nil
casts the output type toNil
, whereas_
passes through the actual return type. These semantics are well defined, make sense and there don't appear to be any issues. So I won't focus on captured block parameter types in this issue.For a yielding block, the actual type is always passed through.
There should technically be no difference between the two, but there are subtle, unintended ones (see https://forum.crystal-lang.org/t/difference-between-underscore-and-empty-as-block-return-value/2998 and #10928) The compiler's behaviour causes that underscore output type can involuntarily break code. As of now, underscore output type is essentially broken. One should always use
Nil
for yielding block parameters as a workaround (#10928 and #10929 apply that to stdlib).There's really no need to have both,
Nil
and_
output types with the same semantics.For simplicity, there should only be one or the other if they mean the same.
Alternatively, we could port the nil-casting semantics of
Nil
output type to yielding blocks. Not sure if that's much useful by itself, but it would help improve the expressiveness of yielding type restrictions.The text was updated successfully, but these errors were encountered: