4 ms·
item = item That is a no-op a := b Declares a new variable a and assigns it. It's sugar for: var a = b So read it as: var item = item Many languages have
by ithkuil 4y ago
item = item
That is a no-op
a := b
Declares a new variable a and assigns it. It's sugar for:
var a = b
So read it as:
var item = item
Many languages have scopes and variable shadowing. You can argue this is bad practice or whatever, but it's only confusing if you think := is assignment which is covered in the first page of the Go language tutorial.
- valenterry 4y agoNot a go dev, but var item = item should still be a noop imo. If it does some magic like dereferencing, make it explicit. And no, other languages making the same mistake is not a good excuse. Especially not for a language focused on inexperienced newgrads.
- ithkuil 4y agoIt introduces a new variable called "item" initialized with the value of another variable called "item" from the parent scope
- Cthulhu_ 4y agoExactly; the difference is in scope, the `item` in the range is scoped to the enclosing block, the `item` inside of the block is loop-block-scoped, shadowing the parent block. That said, it looks and feels dirty and buggy and it's a known workaround for a Go issue, so I'm glad they're at least talking about fixing it.
- valenterry 4y agoWhat value does the first item contain (and what is its type)? What value does the second item contain (and what is its type)? What does the print function exactly do if I pass a variable to it.
- ithkuil 4y agoI see your point. I think we're just using a different definition of "no-op". The statement by itself doesn't produce any visible side effect. However it creates a new logical variable in the abstract machine, and that can have real consequence in the real underlying machine, depending on which statements happen next. In particular, the new variable and the old variable are independent and thus the new variable may require to allocate some storage location (e.g. on the stack, a register, ...) to keep track of further mutations to its value (I say "may" because an optimising compiler may do without that extra location)
- valenterry 4y agoYeah, so what my "problem" is is that in the code item := item item := item the two lines doing different things even though looking exactly the same. I'm a Scala dev and in Scala we have a similar thing, where a new import or definition in the middle of the code can change line semantics between two equal lines. But the difference is that this is not a mistake but a concious design to switch "contexts" and is heavily guarded by the typesystem, where GOs typesystem is incredibly weak in comparison, which is not an inherent drawback, but here it is. I do feel that I'll stick to my feelings that this design is confusing and should have been avoided from the beginning. Ku udos to the go team for breaking compatibility here. This is necessary for a language to not become another COBOL.
- ithkuil 4y agoThis code is illegal in Go item := item item := item "no new variables on left side of :=" You can't declare the same variable twice in the same scope. item := item works only because it declares a new variable in the current scope, initialized with a variable with the same name (but different variable) from the outer scope. Go distinguishes declarations from assignments. In this example, the second assignment is a no-op indeed. item := item item = item
- valenterry 4y agoOkay fair enough, thx for the explanation. Doesn't make it good, but better!
- int_19h 4y agoWhy should it be a no-op? Even if you interpret the identifier on the right as referring to the same variable, it just means that you're trying to initialize the variable to an unspecified value. Surely that ought to be an error, not a no-op?
- colonwqbang 4y agoThe thing which surprised me was not the variable shadowing, rather that the name "item" resovles to different variables on the left and right sides of the :=. This is unusual language design, most languages assign a single meaning to each name in each scope.
- int_19h 4y agoIt's unusual for the C-style family, but very common in functional languages outside of it, such as the ML family. It's not uncommon to see repeated lines of the form: let x = ... x ... and every such line is a declaration of a new variable that shadows the preceding one.
- colonwqbang 4y agoNot in Haskell at least. What ML language are you thinking of?