Skip to content
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

Open
rsc opened this issue Nov 2, 2012 · 14 comments

Comments

@rsc
Copy link
Contributor

commented Nov 2, 2012

It is unclear to me what we are gaining by rejecting this program:

http://play.golang.org/p/yHXYQxkHbi

package main

import "fmt"

type T bool

func main() {
    var t T
    var b bool
    fmt.Println(t && b)
}

prog.go:10: invalid operation: t && b (mismatched types T and bool)

This might tie in with the other bool cleanup we've been doing, or it might be something
to leave for Go 2.
@griesemer

This comment has been minimized.

Copy link
Contributor

commented Nov 2, 2012

Comment 1:

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.

@gopherbot

This comment has been minimized.

Copy link

commented Nov 3, 2012

Comment 2 by robpike:

It's a bit of a stretch to say && isn't a binary operator but rather control flow. If
it's not an operator, why is it in the operator precedence tree?
I'd prefer to leave it as is because to change it requires special rules and because
it's not an important matter.
@rsc

This comment has been minimized.

Copy link
Contributor Author

commented Nov 6, 2012

Comment 3:

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

This comment has been minimized.

Copy link
Contributor

commented Mar 11, 2013

Comment 4:

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).
@griesemer

This comment has been minimized.

Copy link
Contributor

commented Aug 1, 2013

Comment 5:

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.
@rsc

This comment has been minimized.

Copy link
Contributor Author

commented Aug 2, 2013

Comment 6:

I am assuming you meant "I argue we can do this for Go 1.2."
Sounds good to me.

Labels changed: added go1.2.

@griesemer

This comment has been minimized.

Copy link
Contributor

commented Aug 2, 2013

Comment 7:

Yes. Typing English is (np-?) hard...
@griesemer

This comment has been minimized.

Copy link
Contributor

commented Aug 2, 2013

Comment 9:

https://golang.org/cl/12382043

Status changed to Started.

@bradfitz

This comment has been minimized.

Copy link
Member

commented Aug 3, 2013

Comment 10:

Labels changed: added languagechange.

@griesemer

This comment has been minimized.

Copy link
Contributor

commented Aug 5, 2013

Comment 11:

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.

@rsc

This comment has been minimized.

Copy link
Contributor Author

commented Nov 27, 2013

Comment 12:

Labels changed: added go1.3maybe.

@rsc

This comment has been minimized.

Copy link
Contributor Author

commented Dec 4, 2013

Comment 13:

Labels changed: added release-none, removed go1.3maybe.

@rsc

This comment has been minimized.

Copy link
Contributor Author

commented Dec 4, 2013

Comment 14:

Labels changed: added repo-main.

@griesemer

This comment has been minimized.

Copy link
Contributor

commented Mar 3, 2014

Comment 15:

Issue #7251 has been merged into this issue.

@rsc rsc added this to the Unplanned milestone Apr 10, 2015

@rsc rsc changed the title spec: boolean shortcut should allow mismatched types proposal: spec: boolean shortcut should allow mismatched types Jun 20, 2017

@rsc rsc added the Go2 label Jun 20, 2017

@ianlancetaylor ianlancetaylor added Go2Cleanup and removed LongTerm labels Dec 5, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.