|
|
Descriptionspec: var x = 'a' defaults to type rune
Patch Set 1 #Patch Set 2 : diff -r e41b00eb8b9c https://go.googlecode.com/hg/ #Patch Set 3 : diff -r e41b00eb8b9c https://go.googlecode.com/hg/ #
Total comments: 11
Patch Set 4 : diff -r e41b00eb8b9c https://go.googlecode.com/hg/ #Patch Set 5 : diff -r e41b00eb8b9c https://go.googlecode.com/hg/ #
Total comments: 6
Patch Set 6 : diff -r e41b00eb8b9c https://go.googlecode.com/hg/ #
Total comments: 7
Patch Set 7 : diff -r 6601a8eea95a https://go.googlecode.com/hg/ #MessagesTotal messages: 42
Hello golang-dev@googlegroups.com, I'd like you to review this change to https://go.googlecode.com/hg/
Sign in to reply to this message.
I am strongly in favor of the ordering character, integer, floating point, complex (32bit -> 32/64bit -> 32/64bit -> 64/128bit) As we have seen, it removes extra casts as well. I have not seen a good argument for the proposed order yet. http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html File doc/go_spec.html (right): http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode2 doc/go_spec.html:2: <!-- subtitle Version of December 5, 2011 --> December 7 http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode517 doc/go_spec.html:517: <i>character constants</i>, I would mention them before integer constants http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode519 doc/go_spec.html:519: and <i>string constants</i>. Integer, character, floating-point, Character, integer, floating-point, ... http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode527 doc/go_spec.html:527: <a href="#Character_literals">character</a>, same here - before integer http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode3420 doc/go_spec.html:3420: the kind that appears later the list: integer, character, floating-point, complex. the sentence is garbled (later in the list) - but even with the missing "in", it's not easy to understand what is meant. Also, I am still much in favor of the order: character, integer, floating-point, complex. It's really odd the other way around. http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode3447 doc/go_spec.html:3447: const j = 'w' + 1 // j == 'x' (untyped character constant) integer constant http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode3455 doc/go_spec.html:3455: integer, character, or floating-point constants yields character, integer, or ... http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode3761 doc/go_spec.html:3761: respectively, depending on whether the value is a boolean, integer, boolean, character, integer...
Sign in to reply to this message.
On Wed, Dec 7, 2011 at 17:12, <gri@golang.org> wrote: > I am strongly in favor of the ordering > > character, integer, floating point, complex > (32bit -> 32/64bit -> 32/64bit -> 64/128bit) I am equally strongly in favor of the ordering in this CL: if 'x' defaults to rune, so should 'x'+1. Ultimately it affects very little code; the rules in this CL are less surprising than the ones you are proposing. > As we have seen, it removes extra casts as well. It removed one conversion in one line of code. > I have not seen a good argument for the > proposed order yet. The proposed order is very easy to remember: if you see an i anywhere, it's complex; if you see an e or . anywhere, it's float; if you see a ' anywhere, it's rune; otherwise it's an integer. The argument is that it is the least surprising. Reversing rune and integer breaks the symmetry. I have not seen an argument for putting character before integer. You mentioned n*10 + digit - '0' at one point, but that typically n and digit are variables, so it would not be affected by the ordering here. Russ
Sign in to reply to this message.
On Wed, Dec 7, 2011 at 2:22 PM, Russ Cox <rsc@golang.org> wrote: > On Wed, Dec 7, 2011 at 17:12, <gri@golang.org> wrote: >> I am strongly in favor of the ordering >> >> character, integer, floating point, complex >> (32bit -> 32/64bit -> 32/64bit -> 64/128bit) > > I am equally strongly in favor of the ordering > in this CL: if 'x' defaults to rune, so should 'x'+1. > Ultimately it affects very little code; the rules > in this CL are less surprising than the ones > you are proposing. > >> As we have seen, it removes extra casts as well. > > It removed one conversion in one line of code. Actually two, in two lines of code. > >> I have not seen a good argument for the >> proposed order yet. > > The proposed order is very easy to remember: > if you see an i anywhere, it's complex; > if you see an e or . anywhere, it's float; > if you see a ' anywhere, it's rune; > otherwise it's an integer. unless the values are constant names, in which case one has to look them up, of course the proposal I am suggestion is just as simple: unless it's all characters, the current rules apply (and formulated out it's the same list as yours with the last two lines swapped) > > The argument is that it is the least surprising. > Reversing rune and integer breaks the symmetry. I don't understand this argument at all. Which symmetry? Runes are "smaller" than ints. > > I have not seen an argument for putting > character before integer. You mentioned > n*10 + digit - '0' at one point, but that typically > n and digit are variables, so it would not be > affected by the ordering here. - possibly fewer casts (we have 2 cases) - sizeof(rune) <= sizeof(int) - gri > > Russ
Sign in to reply to this message.
http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html File doc/go_spec.html (right): http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode517 doc/go_spec.html:517: <i>character constants</i>, On 2011/12/07 22:12:37, gri wrote: > I would mention them before integer constants integer constants seem more fundamental. i'm happy to have them first. http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode3420 doc/go_spec.html:3420: the kind that appears later the list: integer, character, floating-point, complex. i'm fine with the order but agree this is a peculiar sentence. it's not clear what list you mean. be clear. http://codereview.appspot.com/5444053/diff/5001/doc/go_spec.html#newcode3447 doc/go_spec.html:3447: const j = 'w' + 1 // j == 'x' (untyped character constant) character constant
Sign in to reply to this message.
On Wed, Dec 7, 2011 at 19:30, <r@golang.org> wrote: >> I would mention them before integer constants > integer constants seem more fundamental. i'm happy to have them first. Does anyone have arguments one way or another to bring up? I don't see an easy resolution right now. Russ
Sign in to reply to this message.
On Dec 7, 2011, at 6:56 PM, Russ Cox wrote: > On Wed, Dec 7, 2011 at 19:30, <r@golang.org> wrote: >>> I would mention them before integer constants >> integer constants seem more fundamental. i'm happy to have them first. > > Does anyone have arguments one way or another to bring up? > I don't see an easy resolution right now. The only one I have is that 'x'+1 should be of type rune because the runeness should color the type, just as 1.0+1 colors it to float. It seems bizarre to me even to argue that it should promote to int, the most generic type. -rob
Sign in to reply to this message.
edit: Just saw Rob's mail, and my point is essentially the same. On 8 December 2011 13:56, Russ Cox <rsc@golang.org> wrote: > Does anyone have arguments one way or another to bring up? > I don't see an easy resolution right now. I am strongly in favor of var x = 'a' + 1 being of type rune. Were it an int, I would have a hard time explaining it. So far that's been a pretty good litmus test (for me) as to whether we're heading in the right direction or not. Andrew
Sign in to reply to this message.
[resending - this time to everybody - GMail flaking out on me] On Wed, Dec 7, 2011 at 8:11 PM, Rob 'Commander' Pike <r@google.com> wrote: > > On Dec 7, 2011, at 6:56 PM, Russ Cox wrote: > >> On Wed, Dec 7, 2011 at 19:30, <r@golang.org> wrote: >>>> I would mention them before integer constants >>> integer constants seem more fundamental. i'm happy to have them first. >> >> Does anyone have arguments one way or another to bring up? >> I don't see an easy resolution right now. > > The only one I have is that 'x'+1 should be of type rune because the runeness should color the type, just as 1.0+1 colors it to float. It seems bizarre to me even to argue that it should promote to int, the most generic type. I find that argument not convincing. Why should rune-ness color the type and not int-ness? Is it because a rune literal is a more complex literal with special characters (')? And a float has even more special chars (. and e), and complex even more (., e, and i)? The fact is that every rune can be represented by an int, but not every int fits into a rune. For any rune constant r var v = r + 0 will work if r + 0 defaults to int. However, if the expression defaults to rune type var v = i + '\x00' will not work for any int constant i, since i might be too large (a 64bit int value) to fit into a (32bit) rune. Finally, by setting the order as rune -> int -> float -> complex the behavior of untyped constant expressions is exactly as now unless all operands are untyped runes. I would call _that_ following the principle of least surprise. Untyped constant expressions where all operands are runes are not that common, and those would be the only ones behaving differently from what we have now (and most likely are of the form ch := 'a', where it makes a lot of sense for ch to be of type rune). - gri
Sign in to reply to this message.
Russ Cox <rsc@golang.org> writes: > On Wed, Dec 7, 2011 at 19:30, <r@golang.org> wrote: >>> I would mention them before integer constants >> integer constants seem more fundamental. i'm happy to have them first. > > Does anyone have arguments one way or another to bring up? > I don't see an easy resolution right now. The issue is all about the type to give to an untyped constant expression, right? I mean, we're agreed that in a := 1 b := 'a' then a has type int and b has type rune aka int32. The only question is given c := 'a' + 1 whether the type of c is int or rune. The rune type is a little funny because we normally expect a variable of type rune to hold some sort of character. If we write '9' - '0' we get a rune, even though that doesn't make much sense; an int 9 would be more natural than a rune '\x09'. On the other hand if we write 'a' + 1 then we would expect type rune, namely 'b', rather than an int 98, and if we write '9' - 1 we expect '8' rather than an int 56. In fact the naïve ideal approach seems pretty simple: combining two values of type rune always yields a value of type int, except that adding or subtracting an int from a rune yields a rune. But clearly we don't want to make rune be different from other types in this regard. Still, perhaps this can show us the way. I assume we can all agree that '9' - '0' is going to (counterintuitively) give us a rune. And I assume we can all agree that 'a' + 1, the expression in question, should ideally give us a rune. Given that we are definitely going to get a rune in the case where we probably don't want it, and that we do want a rune in a common case of combining a rune and an int, it seems to me that we ought to lean toward making a combination of an int and a rune be a rune. Otherwise we will get a rune when we don't want it and an int when we don't want it. It seems like it might be better to at least get one of those right. Ian
Sign in to reply to this message.
On 8 December 2011 16:27, Robert Griesemer <gri@golang.org> wrote: > The fact is that every rune can be represented by an int, but not > every int fits into a rune. For any rune constant r > > var v = r + 0 > > will work if r + 0 defaults to int. However, if the expression > defaults to rune type > > var v = i + '\x00' > > will not work for any int constant i, since i might be too large (a > 64bit int value) to fit into a (32bit) rune. IMO the compiler error generated in that case would be a help, not a hindrance. Why would you want to add a rune value to some huge integer constant? Seems like an error to me. Better to be explicit in that case: var v = i + int('\x00') // yep, I really mean this Andrew
Sign in to reply to this message.
On Wed, Dec 7, 2011 at 9:33 PM, Ian Lance Taylor <iant@google.com> wrote: > Still, perhaps this can show us the way. I assume we can all agree that > '9' - '0' is going to (counterintuitively) give us a rune. And I assume > we can all agree that 'a' + 1, the expression in question, should > ideally give us a rune. Given that we are definitely going to get a > rune in the case where we probably don't want it, and that we do want a > rune in a common case of combining a rune and an int, it seems to me > that we ought to lean toward making a combination of an int and a rune > be a rune. Otherwise we will get a rune when we don't want it and an > int when we don't want it. It seems like it might be better to at least > get one of those right. That sounds great but the fact is that this appears to require more casts in the current code than my alternative proposal. To me that means that either our code is not representative (possible), or that this intuition is wrong (also possible). Looking at rsc's CL again, by far the majority of places where a rune cast can be avoided are of the form v := 'x' which makes a lot of sense, of course. There are two places where int casts have to be introduced because the standing proposal (calling it #1) changes current behavior: http://codereview.appspot.com/5448091/diff/4001/src/pkg/math/big/nat.go?conte... http://codereview.appspot.com/5448091/diff/4001/src/pkg/strings/strings_test.... Those casts wouldn't be needed with my proposal (calling it #2) which does not change current behavior in this case (principle of least surprise). Here's another proposal (calling it #3): #3) If and only if an expression consists of a single untyped rune, the default type is rune. Otherwise, things remain as before. This is a bit irregular, but it would not change anything except for the really common case. It would also make 'a' - 'b' an int (as before). That said, I still believe #2 is the correct approach. It's regular, does the job, is easy to explain (rune -> int -> float -> complex), and doesn't lead to weird corner case errors (an int always fits into a rune). - gri
Sign in to reply to this message.
PS: I meant to say at the end: "a rune always fits into an int", of course. - gri On Thu, Dec 8, 2011 at 8:59 AM, Robert Griesemer <gri@golang.org> wrote: > On Wed, Dec 7, 2011 at 9:33 PM, Ian Lance Taylor <iant@google.com> wrote: >> Still, perhaps this can show us the way. I assume we can all agree that >> '9' - '0' is going to (counterintuitively) give us a rune. And I assume >> we can all agree that 'a' + 1, the expression in question, should >> ideally give us a rune. Given that we are definitely going to get a >> rune in the case where we probably don't want it, and that we do want a >> rune in a common case of combining a rune and an int, it seems to me >> that we ought to lean toward making a combination of an int and a rune >> be a rune. Otherwise we will get a rune when we don't want it and an >> int when we don't want it. It seems like it might be better to at least >> get one of those right. > > That sounds great but the fact is that this appears to require more > casts in the current code than my alternative proposal. To me that > means that either our code is not representative (possible), or that > this intuition is wrong (also possible). Looking at rsc's CL again, by > far the majority of places where a rune cast can be avoided are of the > form > > v := 'x' > > which makes a lot of sense, of course. There are two places where int > casts have to be introduced because the standing proposal (calling it > #1) changes current behavior: > > http://codereview.appspot.com/5448091/diff/4001/src/pkg/math/big/nat.go?conte... > http://codereview.appspot.com/5448091/diff/4001/src/pkg/strings/strings_test.... > > Those casts wouldn't be needed with my proposal (calling it #2) which > does not change current behavior in this case (principle of least > surprise). > > Here's another proposal (calling it #3): > > #3) If and only if an expression consists of a single untyped rune, > the default type is rune. Otherwise, things remain as before. > > This is a bit irregular, but it would not change anything except for > the really common case. It would also make 'a' - 'b' an int (as > before). > > That said, I still believe #2 is the correct approach. It's regular, > does the job, is easy to explain (rune -> int -> float -> complex), > and doesn't lead to weird corner case errors (an int always fits into > a rune). > > - gri
Sign in to reply to this message.
Robert Griesemer <gri@golang.org> writes: > Looking at rsc's CL again, by > far the majority of places where a rune cast can be avoided are of the > form > > v := 'x' > > which makes a lot of sense, of course. I don't quite understand this. I thought we all agreed that in a statement like v := 'x' that v would get type rune. Are you saying that we do not all agree on that? Ian
Sign in to reply to this message.
A counterproposal for your consideration: 'a' is an untyped integer constant. That's the status quo, and it's easy to understand and doesn't introduce any of this confusion. It also requires no code changes relative to the current tip. -rob
Sign in to reply to this message.
On Thu, Dec 8, 2011 at 9:48 AM, Ian Lance Taylor <iant@google.com> wrote: > Robert Griesemer <gri@golang.org> writes: > >> Looking at rsc's CL again, by >> far the majority of places where a rune cast can be avoided are of the >> form >> >> v := 'x' >> >> which makes a lot of sense, of course. > > I don't quite understand this. I thought we all agreed that in a > statement like > v := 'x' > that v would get type rune. Are you saying that we do not all agree on > that? No. We do all agree on that. With all proposals we will get that effect, which is what we want. - gri
Sign in to reply to this message.
On Thu, Dec 8, 2011 at 11:59, Robert Griesemer <gri@golang.org> wrote: > There are two places where int > casts have to be introduced because the standing proposal (calling it > #1) changes current behavior: Let's look at both of these. Here's the first: const MaxBase = 'z' - 'a' + 10 + 1 // = hexValue('z') + 1 func hexValue(ch rune) Word { - d := MaxBase + 1 // illegal base + d := int(MaxBase + 1) // illegal base This was not the right change. The right change is const MaxBase = 36. MaxBase should be an integer constant, not a character constant, because it is 36, not '$'. Then there's no conversion. This, Robert, seems to be the heart of your argument: that occasionally you are doing math on characters and want an int. But in every other case in the language, we require a conversion for a concept change like that. It is inconsistent to drop the conversion here. Here's the second: // Make a string of all the runes. - numRunes := unicode.MaxRune + 1 + numRunes := int(unicode.MaxRune + 1) This is converting from a rune value to an integer. I'm not describing the type system; I'm describing the actual operation: unicode.MaxRune is clearly a rune, and numRunes is clearly an int. So there's a conversion. That is far less magical than the +1 turning it into int. Russ
Sign in to reply to this message.
On Thu, Dec 8, 2011 at 9:59 AM, Russ Cox <rsc@golang.org> wrote: > On Thu, Dec 8, 2011 at 11:59, Robert Griesemer <gri@golang.org> wrote: >> There are two places where int >> casts have to be introduced because the standing proposal (calling it >> #1) changes current behavior: > > Let's look at both of these. Here's the first: > > const MaxBase = 'z' - 'a' + 10 + 1 // = hexValue('z') + 1 > > func hexValue(ch rune) Word { > - d := MaxBase + 1 // illegal base > + d := int(MaxBase + 1) // illegal base > > This was not the right change. The right change is const MaxBase = 36. > MaxBase should be an integer constant, not a character constant, > because it is 36, not '$'. Then there's no conversion. I agree, the change was not correct. It should have been in the const declaration - which then would have needed an int type (same as doing the cast there). MaxBase would be an integer constant with my proposal #2 w/o any changes. > > This, Robert, seems to be the heart of your argument: that occasionally > you are doing math on characters and want an int. But in every other > case in the language, we require a conversion for a concept change > like that. It is inconsistent to drop the conversion here. Exactly: I am doing math and I want the right thing to happen for the mathematically exact constants we have in Go. Like when I write 1 + 2.3 I want this to become a floating point constant expression. And why? Because 1 + 2.3 can be represented as float type when it needs to default, but not as int type in general. The same is true for 'a' + 1 - there is no difference whatsoever. > Here's the second: > > // Make a string of all the runes. > - numRunes := unicode.MaxRune + 1 > + numRunes := int(unicode.MaxRune + 1) > > This is converting from a rune value to an integer. > I'm not describing the type system; I'm describing the > actual operation: unicode.MaxRune is clearly a rune, > and numRunes is clearly an int. So there's a conversion. There should be no conversion - they are both untyped numerical constants. I don't understand why all of a sudden 'a' should become so special in a situation like 'a' + 1 when until now we were perfectly happy with it defaulting to int type. After all, the rune type _is_ int32. Why should a constant expression a + b where a defaults to int32 and b defaults to int together default to int32? Makes no sense to me at all. - gri
Sign in to reply to this message.
It seems to me that at the heart of proposal #1 is the feeling that a rune 'a' is now some special new type. But it's not. An 'a' is still just a plain vanilla integer value, and a short one at that. There's no reason to make it anything better. Proposal #2 accepts that and simply fits it into the existing hierarchy. - gri
Sign in to reply to this message.
On Thu, Dec 8, 2011 at 13:22, Robert Griesemer <gri@golang.org> wrote: > I don't understand why all of a sudden 'a' should become so special in > a situation like 'a' + 1 when until now we were perfectly happy with > it defaulting to int type. After all, the rune type _is_ int32. Why > should a constant expression a + b where a defaults to int32 and b > defaults to int together default to int32? Makes no sense to me at > all. int32 and 'character constant' are different concepts. We are not talking about int32 + int. We are talking about character constant + integer constant. You keep mentioning representation, but that's not actually relevant, since these are ideal constants. You can have a 100-bit character constant the same as you can have a 100-bit integer constant. I never want to have to explain this error to someone: var ( x = 'a' y = 'a'+1 alpha = []rune{x, y} // ER ) x.go:6: cannot use y (type int) as type rune in array element Russ
Sign in to reply to this message.
On Thu, Dec 8, 2011 at 13:29, Robert Griesemer <gri@golang.org> wrote: > It seems to me that at the heart of proposal #1 is the feeling that a > rune 'a' is now some special new type. But it's not. An 'a' is still > just a plain vanilla integer value, and a short one at that. There's > no reason to make it anything better. Proposal #2 accepts that and > simply fits it into the existing hierarchy. You seem to be the only one arguing against what's in this CL, it almost never matters in practice, there have been no truly new points made in this discussion, and I'd like to move on to other, less controversial work. I think we've spent far more time on this than it merits. I am uncomfortable that we have not reached an actual consensus on 'x'+1, but we all seem to agree that 'x' should default to rune, and that is 99% of what this CL is about. I propose that we close the discussion, check in the current CL, and get some experience with this behavior. If something more compelling arises in actual use, we still have time to change it later. Objections? Russ
Sign in to reply to this message.
I spoke to Ken and he suggested comparing these two declarations, x := rune(61)+1 y := 'a' + 1 Under gri's approach as we understand it, x and y would have different types. That seems bizarre. Under rsc's approach they would both have type rune. -rob
Sign in to reply to this message.
I am all for moving forward.
But I am not convinced that this is the right step. I believe I have
brought up concrete evidence why #2 is more sound than #1 (fewer casts
or type declarations in existing code, behavior closer to what we have
now, mathematically makes more sense). I'd like to hear a concrete
argument in favor of #1 (as opposed to an emotional one).
Also, let's be frank: "moving forward and gaining experience with this
CL" actually means: "let's get used to it, and in a couple of weeks
it's not important enough to change", especially because #1 is
"workable". So, no, I am not really in favor of that.
We can either democracy or The Decider make the decision. I am for #2
or the status quo: #2 for all the stated reasons, and status quo
because it's simpler and doesn't introduce irregularities.
- gri
PS: Regarding your last argument: 'a' + 1 is a numerical constant
expression. It may not fit into an int32, so the error is not unusual.
The same applies to this piece of code. There's no difference:
var (
x = 1
y = 1 + 2.0
vector = []int{x, y} // ER
)
On Thu, Dec 8, 2011 at 10:37 AM, Russ Cox <rsc@golang.org> wrote:
> On Thu, Dec 8, 2011 at 13:29, Robert Griesemer <gri@golang.org> wrote:
>> It seems to me that at the heart of proposal #1 is the feeling that a
>> rune 'a' is now some special new type. But it's not. An 'a' is still
>> just a plain vanilla integer value, and a short one at that. There's
>> no reason to make it anything better. Proposal #2 accepts that and
>> simply fits it into the existing hierarchy.
>
> You seem to be the only one arguing against
> what's in this CL, it almost never matters in
> practice, there have been no truly new points
> made in this discussion, and I'd like to move on
> to other, less controversial work. I think we've
> spent far more time on this than it merits.
>
> I am uncomfortable that we have not reached
> an actual consensus on 'x'+1, but we all seem
> to agree that 'x' should default to rune, and that
> is 99% of what this CL is about. I propose that
> we close the discussion, check in the current CL,
> and get some experience with this behavior.
> If something more compelling arises in actual use,
> we still have time to change it later.
>
> Objections?
>
> Russ
Sign in to reply to this message.
How is it different from: x := int(61)+1.0 y := 61 + 1.0 ? x will have type int, but y is float64. With the same argument one could say that y should be int. It may look bizarre, but it makes perfect sense (just maybe not emotional sense). - gri On Thu, Dec 8, 2011 at 11:01 AM, Rob 'Commander' Pike <r@google.com> wrote: > I spoke to Ken and he suggested comparing these two declarations, > > x := rune(61)+1 > y := 'a' + 1 > > Under gri's approach as we understand it, x and y would have different types. That seems bizarre. Under rsc's approach they would both have type rune. > > -rob >
Sign in to reply to this message.
On Dec 8, 2011, at 11:22 AM, Robert Griesemer wrote: > How is it different from: > > x := int(61)+1.0 > y := 61 + 1.0 > > ? > > x will have type int, but y is float64. With the same argument one > could say that y should be int. It may look bizarre, but it makes > perfect sense (just maybe not emotional sense). It's different because 61 is an untyped integer constant, so in isolation int(61) is different in effect from rune(61). -rob
Sign in to reply to this message.
On Thu, Dec 8, 2011 at 11:37 AM, Rob 'Commander' Pike <r@google.com> wrote: > > On Dec 8, 2011, at 11:22 AM, Robert Griesemer wrote: > >> How is it different from: >> >> x := int(61)+1.0 >> y := 61 + 1.0 >> >> ? >> >> x will have type int, but y is float64. With the same argument one >> could say that y should be int. It may look bizarre, but it makes >> perfect sense (just maybe not emotional sense). > > It's different because 61 is an untyped integer constant, so in isolation int(61) is different in effect from rune(61). > > -rob > Maybe I should have written: x := byte(61.0)+1.0 y := 0x3d + 1.0 In isolation 61.0 is float64 (61 is int in Ken's example), and 0x3d is int ('a' is rune). But x is byte (rune in Ken's example), y is float64 (int). 0x3d + 1.0 "looks line a byte" but defaults to float64; similarly, 'a' + 1 looks like a rune but defaults to int (with #2). But all these examples are contrived. I think if an untyped constant expression should default to rune type, it better not have anything but character literals in it. Most of the time it's exactly one (probably 99% of the time). In all other cases, we have some kind of computation and the result should probably not be a rune (it's a difference, or some maximum, or what have you). One more argument in favor of #2: If 'a' + 1 should default to a rune, one can always write 'a' + '\x01' with prop #2. But I have no way to make 'a' + 1 be an untyped constant that defaults to int with #1. - gri
Sign in to reply to this message.
i do not understand robert's argument.
'a' is a typed constant with a value.
rune(0x61) is a typed constant with a value.
they should have the exact same semantic meaning.
it seems that everyone knows what
rune(0x61)+1
means, but can't decide what
'a'+1
means. they are the same. it should all fall out from the
addition of a typed constant and an untyped constant.
i think it is the same as 'b' (not by definition, but by ascii.)
On Thu, Dec 8, 2011 at 11:37 AM, Rob 'Commander' Pike <r@google.com> wrote:
>
> On Dec 8, 2011, at 11:22 AM, Robert Griesemer wrote:
>
>> How is it different from:
>>
>> x := int(61)+1.0
>> y := 61 + 1.0
>>
>> ?
>>
>> x will have type int, but y is float64. With the same argument one
>> could say that y should be int. It may look bizarre, but it makes
>> perfect sense (just maybe not emotional sense).
>
> It's different because 61 is an untyped integer constant, so in isolation
int(61) is different in effect from rune(61).
>
> -rob
>
Sign in to reply to this message.
they would be the same if 'a' were a typed constant
but 'a' is an untyped constant that defaults to rune type by itself,
and may default to something else in context. for:
ch := 'a' + 1
prop #1 says: ch is of type rune (because there's a character literal
in the untyped constant expression)
prop #2 says: ch is of type int (because there's an int literal in the
untyped constant expression)
- robert
On Thu, Dec 8, 2011 at 12:56 PM, Ken Thompson <ken@google.com> wrote:
> i do not understand robert's argument.
> 'a' is a typed constant with a value.
> rune(0x61) is a typed constant with a value.
> they should have the exact same semantic meaning.
> it seems that everyone knows what
> rune(0x61)+1
> means, but can't decide what
> 'a'+1
> means. they are the same. it should all fall out from the
> addition of a typed constant and an untyped constant.
> i think it is the same as 'b' (not by definition, but by ascii.)
>
> On Thu, Dec 8, 2011 at 11:37 AM, Rob 'Commander' Pike <r@google.com> wrote:
>>
>> On Dec 8, 2011, at 11:22 AM, Robert Griesemer wrote:
>>
>>> How is it different from:
>>>
>>> x := int(61)+1.0
>>> y := 61 + 1.0
>>>
>>> ?
>>>
>>> x will have type int, but y is float64. With the same argument one
>>> could say that y should be int. It may look bizarre, but it makes
>>> perfect sense (just maybe not emotional sense).
>>
>> It's different because 61 is an untyped integer constant, so in isolation
int(61) is different in effect from rune(61).
>>
>> -rob
>>
Sign in to reply to this message.
On Thu, Dec 8, 2011 at 16:49, Robert Griesemer <gri@golang.org> wrote: > but 'a' is an untyped constant that defaults to rune type by itself, > and may default to something else in context. for: > > ch := 'a' + 1 > > prop #1 says: ch is of type rune (because there's a character literal > in the untyped constant expression) > prop #2 says: ch is of type int (because there's an int literal in the > untyped constant expression) This is definitely the key distinction. I just can't imagine a time when you'd write ch := 'a'+1 and expect to get ch := 98 instead of ch := 'b'. As Rob said last night, integers feel like the most generic of the constants. Making them more special than character constants, in the same way that floating-point constants are currently more special than integers, seems very strange. Ultimately I don't think we will come up with technical arguments that will satisfy everyone. Russ
Sign in to reply to this message.
On Thu, Dec 8, 2011 at 1:53 PM, Russ Cox <rsc@golang.org> wrote: > On Thu, Dec 8, 2011 at 16:49, Robert Griesemer <gri@golang.org> wrote: >> but 'a' is an untyped constant that defaults to rune type by itself, >> and may default to something else in context. for: >> >> ch := 'a' + 1 >> >> prop #1 says: ch is of type rune (because there's a character literal >> in the untyped constant expression) >> prop #2 says: ch is of type int (because there's an int literal in the >> untyped constant expression) > > This is definitely the key distinction. > I just can't imagine a time when you'd write > > ch := 'a'+1 > > and expect to get ch := 98 instead of ch := 'b'. Except that in all cases in our code where we have code like that, we actually want an int (and #1 requires conversions that didn't exist before). I understand the emotional feel but it is contrary to the evidence we have. I can always write: ch := 'a' + '\01' and get exactly 'b' with both #1 and #2. But with proposal #1 I cannot write ch := 'a' + 1 and get 98 with a cast or type specification. In the past, we decided in favor of the more powerful mechanism. > > As Rob said last night, integers feel like the most > generic of the constants. Making them more special > than character constants, in the same way that > floating-point constants are currently more special > than integers, seems very strange. With emphasis on feeling; and I actually share that feeling. But it seems mathematically incorrect. Floating-point constants are more special than ints because typically a floating point constant cannot be represented as an integral value. Arguably, an int value is more special because typically an an arbitrary integer constant cannot be represented as a character literal (e.g., a '\U...' value goes only to 32bits); also when defaulting to a rune, an int value may not fit into 32bits and lead to a hard to explain error. Anyway, I give up. I've made my point. - Robert > > Ultimately I don't think we will come up with > technical arguments that will satisfy everyone. > > Russ
Sign in to reply to this message.
PTAL On Wed, Dec 7, 2011 at 19:30, <r@golang.org> wrote: > doc/go_spec.html:3420: the kind that appears later the list: integer, > character, floating-point, complex. > i'm fine with the order but agree this is a peculiar sentence. it's not > clear what list you mean. be clear. changed to "this list": Except for shift operations, if the operands of a binary operation are different kinds of untyped constants, the operation and result use the kind that appears later in this list: integer, character, floating-point, complex. For example, an untyped integer constant divided by an untyped complex constant yields an untyped complex constant.
Sign in to reply to this message.
Independent of the outcome of the rune default discussion, I think the enumeration of the various literal types should be boolean, character, integer, floating-point, complex Having the character literal between integer and floating point is odd. booleans are before ints, for instance. Especially if #1 is chosen, a character feels even less like a numeric type. Certainly not one between int and float. - gri On Thu, Dec 8, 2011 at 2:11 PM, Russ Cox <rsc@golang.org> wrote: > PTAL > > On Wed, Dec 7, 2011 at 19:30, <r@golang.org> wrote: >> doc/go_spec.html:3420: the kind that appears later the list: integer, >> character, floating-point, complex. >> i'm fine with the order but agree this is a peculiar sentence. it's not >> clear what list you mean. be clear. > > changed to "this list": > > Except for shift operations, if the operands of a binary operation are > different kinds of untyped constants, the operation and result use > the kind that appears later in this list: integer, character, > floating-point, complex. > For example, an untyped integer constant divided by an > untyped complex constant yields an untyped complex constant.
Sign in to reply to this message.
http://codereview.appspot.com/5444053/diff/27001/doc/go_spec.html File doc/go_spec.html (right): http://codereview.appspot.com/5444053/diff/27001/doc/go_spec.html#newcode520 doc/go_spec.html:520: and <i>string constants</i>. Integer, character, floating-point, Character, integer, ... http://codereview.appspot.com/5444053/diff/27001/doc/go_spec.html#newcode3760 doc/go_spec.html:3760: to type <code>bool</code>, <code>int</code>, <code>rune</code>, <code>float64</code>, bool, rune, int, float64 ... http://codereview.appspot.com/5444053/diff/27001/doc/go_spec.html#newcode3762 doc/go_spec.html:3762: respectively, depending on whether the value is a boolean, integer, boolean, character, integer, floating-point,
Sign in to reply to this message.
PTAL http://codereview.appspot.com/5444053/diff/27001/doc/go_spec.html File doc/go_spec.html (right): http://codereview.appspot.com/5444053/diff/27001/doc/go_spec.html#newcode520 doc/go_spec.html:520: and <i>string constants</i>. Integer, character, floating-point, On 2011/12/08 22:45:41, gri wrote: > Character, integer, ... Done. http://codereview.appspot.com/5444053/diff/27001/doc/go_spec.html#newcode3760 doc/go_spec.html:3760: to type <code>bool</code>, <code>int</code>, <code>rune</code>, <code>float64</code>, On 2011/12/08 22:45:41, gri wrote: > bool, rune, int, float64 ... Done. http://codereview.appspot.com/5444053/diff/27001/doc/go_spec.html#newcode3762 doc/go_spec.html:3762: respectively, depending on whether the value is a boolean, integer, On 2011/12/08 22:45:41, gri wrote: > boolean, character, integer, floating-point, Done.
Sign in to reply to this message.
Leaving for r. http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html File doc/go_spec.html (right): http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html#newcode3421 doc/go_spec.html:3421: the kind that appears later in this list: integer, character, floating-point, complex. I would write: character, integer, floating-point, complex. leaving for r. http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html#newcode3448 doc/go_spec.html:3448: const j = 'w' + 1 // j == 'x' (untyped character constant) const 'w' + '\x01' would be my choice
Sign in to reply to this message.
LGTM but there's a wording change here others might want to check http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html File doc/go_spec.html (right): http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html#newcode364 doc/go_spec.html:364: A character literal represents a <a href="#Constants">character constant</a>, this should be called a character literal representing a rune constant http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html#newcode3421 doc/go_spec.html:3421: the kind that appears later in this list: integer, character, floating-point, complex. keep the order but s/character/rune/ http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html#newcode3448 doc/go_spec.html:3448: const j = 'w' + 1 // j == 'x' (untyped character constant) add gri's example also s/character/rune/ http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html#newcode3456 doc/go_spec.html:3456: integer, character, or floating-point constants yields s/character/rune/ http://codereview.appspot.com/5444053/diff/23005/doc/go_spec.html#newcode3763 doc/go_spec.html:3763: character, integer, floating-point, complex, or string constant. s/character/rune/
Sign in to reply to this message.
I chose 'character constant' to avoid the type name rune. It has rune type by default, but var x int64 = 'x' is still okay. And you can make a typed constant with type rune const x rune = 100 (and then var y int64 = x is not okay) so in all it seemed clearer not to reuse the type name. We write integer or floating-point constant, not int constant or float64 constant. Russ
Sign in to reply to this message.
On Dec 8, 2011, at 4:52 PM, Russ Cox wrote: > I chose 'character constant' > to avoid the type name rune. > It has rune type by default, but > > var x int64 = 'x' > > is still okay. And you can make a typed constant > with type rune > > const x rune = 100 > > (and then var y int64 = x is not okay) > so in all it seemed clearer not to reuse the type > name. We write integer or floating-point constant, > not int constant or float64 constant. that's fine, and i'm happy with 'character constant'. my point was to push back on the idea that it's just a byte (char), but maybe i don't need to worry about that any more. LGTM either way -rob
Sign in to reply to this message.
*** Submitted as http://code.google.com/p/go/source/detail?r=1100c91c2087 *** spec: var x = 'a' defaults to type rune R=gri, r, r, adg, iant, ken CC=golang-dev http://codereview.appspot.com/5444053
Sign in to reply to this message.
i dont understand the line const Σ = 1 - 0.707 // (untyped complex constant) there should be an i in there somewhere. On Thu, Dec 8, 2011 at 6:48 PM, <rsc@golang.org> wrote: > *** Submitted as > http://code.google.com/p/go/source/detail?r=1100c91c2087 *** > > spec: var x = 'a' defaults to type rune > > R=gri, r, r, adg, iant, ken > CC=golang-dev > http://codereview.appspot.com/5444053 > > > http://codereview.appspot.com/5444053/
Sign in to reply to this message.
On Sat, Dec 10, 2011 at 03:13, Ken Thompson <ken@google.com> wrote: > i dont understand the line > > const Σ = 1 - 0.707 // (untyped complex constant) > > there should be an i in there somewhere. oops. i lost the i in 0.707i during copy+paste. thanks. russ
Sign in to reply to this message.
|
