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
Autocasting from Bool?
to Bool
#12704
Comments
The main question is: why? What's the benefit of using I think the answer might be around "it's more efficient to use Bool over Bool | Nil, and it might be faster to compile." But in my experiments changing methods to return So I wouldn't introduce a semantic change without a proof that it has a meaningful impact. |
Those changes were about correctness more than performance. A We can cast anything to a def foo(x : Bool)
end
foo(true.as?(Bool?))
foo(nil) # okay?
foo(Pointer(Void).null) # okay?
foo(1) # okay?? In particular it would be really odd if Ruby RBS has a |
I mentioned the motivation in the OP:
If the purpose of a value is to express truthiness, having two values for representing falsey ( |
@HertzDevil In general, I don't think autocasting anything to |
Autocasting is currently never done for return values. This is entirely something new. I think it is a bad idea to have two sets of autocasting rules for return values and other restrictions. And my concern still stands: def foo : Bool
nil.as(Bool?)
end
def foo : Bool
nil # okay?
end
def foo : Bool
# okay?
end Besides, at this point |
I guess what I'm saying is that if you want to make sure to return I would actually find it confusing if I think introducing such a rule might cause more confusion than benefit. |
It's maybe not exactly autocasting, but the idea was inspired by the return type restriction |
FWIW I would consider a good idea to have a method to do the equivalent to |
I think @straight-shoota 's arguments are fully sound and I fully support the idea. And this might be backwards compatible? Of course, other than the case when someone was actually comparing to nil 😕 |
It could be implemented as a syntax sugar transform, like the following: def foo : Bool
body
end def foo : Bool
!!begin
body
end
end The fact that |
If we want explicit returns to be an error then it can't just be syntax sugar. For the def foo : Nil
return 1
end That's how it works for |
I meant only a wrong explicit return - this certainly errors: def foo : Bool
!!begin
return 6
nil
end
end Anyway maybe it's not a good way to implement it. And yes, I was fearing that part about |
I don't think the This: def foo : Bool
1
end would get transformed to this: def foo : Bool
!!begin
1
end
end which actually typechecks, but it's probably not what you want. |
That actually sounds concerning to me, depending on the approach, because people might start trying to give it special meanings |
This idea is inspired by #12702: A lot of predicate methods are returning
Bool | Nil
when justBool
would suffice. RemovingNil
makes the API more concise. Looking at the diff of that PR, it consists of prefixing!!
to many return expressions for predicate methods. This double negation mapsnil
tofalse
, thus removing theNil
type from the union.What if instead of altering the implementations, we introduce an autocast from
Bool?
toBool
? At least for method return values?Nil
has a singleton valuenil
and it is falsey. CastingNil
toBool
is clearly defined.Random example from that PR results in this method:
With
Bool?
autocasting, we could write it like this:I think that would be more elegant.
Both examples are semantically equivalent. But the type restriction has other benefits (documentation and tying down the API). So considering we want to add return types in many places anyways, autocasting would avoid having to write
!!
as well.The text was updated successfully, but these errors were encountered: