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
proposal: spec: boolean shortcut should allow mismatched types #4336
Comments
At the moment && is a binary operator and the operands of binary operators must have the same type, and bool != mybool. If b were an untyped constant, it would work (see e.g., http://play.golang.org/p/Td7n1UGr67 ). Arguably, in this operation the operands don't really inter-operate; rather this is control-flow. Thus perhaps they don't have to be of the same type. It would be a spec change, albeit backward-compatible. Status changed to Thinking. |
Let's leave this open to think about after Go 1.1. It bothers me that t != false && b != false is okay but t && b is not. http://play.golang.org/p/5CU_kKxXGS |
This problem is now partly mitigated by https://golang.org/cl/7524044/ (submitted). Expressions where one of the && or || operands is a comparison and the 2nd operand is not of type bool are legal now: x < y && z (because the result of x < y is an untyped bool). |
I think we should fix this in the following vain: x && y is equivalent to x == true && y == true (same for ||, of course) and the result of && is an untyped bool. Observations: 1. Comparisons already always return an untyped bool (which makes them much easier to explain). 2. && and || are not really binary operators: they only conditionally evaluate the 2nd argument, and so the result should arguably not depend on both argument types. 3. The spec currently says that the result type of && and || is the same as the operand types (which must match). But for, say: x << y && y << z, the operand types are untyped bools and so one would assume that the result should be untyped bool (per spec). But in fact, in this case the result gets "default-typed" to bool. This is again one of those implicit rules that are hard to deduce from the current spec. Making the result always an untyped bool would make this much clearer and simplify the spec. This is also test/fixedbugs/issue3924.go. 4. The implementation change should be trivial and is backward-compatible. I argue with can do this for 1.2. |
https://golang.org/cl/12382043 Status changed to Started. |
As pointed out by adonovan, a backward-compatible change must not ignore the current operand types. For instance, the originally proposed change will break the following code (for instance): type B bool var b B var x, y int var t interface{} = b && x < y // current spec: dynamic type of t is B; simplified proposal: dynamic type of t is bool _ = t.(B) // this would fail with the simplified proposal It's possible to amend the proposal but those new rules are more complicated than the existing rules. Leaving for Go 2. Labels changed: removed go1.2. Status changed to LongTerm. |
Issue #7251 has been merged into this issue. |
As noted above, this proposal is not backward compatible. And defined boolean types are uncommon. It doesn't seem worth making a non-backward-compatible change for this purpose. Therefore, this is a likely decline. Leaving open for four weeks for final comments. |
No further comments. |
The text was updated successfully, but these errors were encountered: