It appears to me that the compiler can distinguish the use of variable
names and typenames (since we have to use keywords like var, type,
func etc). But from programming style point of view, reusing typenames
is a bad practice. I think Go compiler should not allow using variable
names, struct or function names same as type names. Here is an
example:
return -int, -frac
This code is from math/bits.go, Modf function. I don't think libraries
should use such type-name variables in code - it will set wrong
example to Go programmers. There are lots of knowledgeable Go
programmers here and they can construct programs that can be confusing
with this feature. The current compiler allows code like this:
package main
type int struct {
val int32;
}
func main() {
var int *int = new (int);
int.val = 10;
print(int.val);
}
I don't think its a good idea to allow this code: It is easy to figure-
out such type-named-variable name in a small code segment like this,
but in a large code base, it can be difficult to understand. Also,
won't such features in language will necessitate creation of golint
(lint tool for Go)?
Is it a conscious language design decision to allow type names as
variable names? Do people in this group think its a good idea?
-Ganesh
From http://golang.org/doc/go_spec.html#Identifiers
- Some identifiers are predeclared.
From http://golang.org/doc/go_spec.html#Keywords
- The following keywords are reserved and may not be used as
identifiers.
"int" and friends are predeclared *types*, but not reserved
*keywords*, so it's IMO quite comparable, if not the same, with the
design choices of some other languages (IIRC e.g. FPC) and it doesn't
seems to me as a problem at all. At most a matter of a possibly "bad"
style in someone's eyes, but that's nothing of a general [in]validity.
In C++, the keyword "typename" was added into the language during
standardization because there were some cases where the compiler was
not able to decide if the given qualified name is a type name
(typedef, nested struct etc) or a member (static member etc). This
adds to the conceptual overload in the language: one has to remember
all the rules where typename should be used and how it should be used
etc. I don't know Go enough to understand if this would cause
ambiguity in any part of the language where the compiler would get
confused about the given reference.
But it could certainly cause confusion, for example, in a switch
statement:
case int:
A programmer reading this part of the code will expect it to be a
typeswitch, and he might discover that its an expression switch. My
question is simple: Why allow programmer to declare variable names as
typenames? Disallowing it will simplify the language and its usage,
isn't it?
-Ganesh
C++ has (I think so) the property of not being generally parsable
without the availability of the (declared) symbols table. AFAIK Go
doesn't has this, in spite of parsing/compilation speed very
unwelcome, problem.
> But it could certainly cause confusion, for example, in a switch
> statement:
It can confuse. That's why someone with that feeling would probably
rather not use this style, at least not in such places.
> typenames? Disallowing it will simplify the language and its usage,
> isn't it?
IMO, technically it would not simplify, but to certain extent
complicate some parts of the compile process. There would be some
extra checks needed which are not necessary now. Also casting of some
types in stone would prohibit some programming techniques - it may be
useful in some situations to import a package with a modified
definition of e.g. "int", although I'm not sure if it's really
possible now to do so - didn't tried this in Go yet.
> In C++, the keyword "typename" was added into the language during
> standardization because there were some cases where the compiler was
> not able to decide if the given qualified name is a type name
> (typedef, nested struct etc) or a member (static member etc). This
> adds to the conceptual overload in the language: one has to remember
> all the rules where typename should be used and how it should be used
> etc. I don't know Go enough to understand if this would cause
> ambiguity in any part of the language where the compiler would get
> confused about the given reference.
C++ requires the typename keyword to handle two-phase name lookup in
template instantiation, in order to tell the compiler that a name
depends on a template parameter even though it does not appear to.
There is nothing comparable in Go.
> But it could certainly cause confusion, for example, in a switch
> statement:
>
> case int:
>
> A programmer reading this part of the code will expect it to be a
> typeswitch, and he might discover that its an expression switch. My
> question is simple: Why allow programmer to declare variable names as
> typenames? Disallowing it will simplify the language and its usage,
> isn't it?
Separating the notion of a reserved word from the notion of a
predeclared type name seems like good practice to me, though I agree
that it can lead to confusion such as you describe. The benefit is
that it is possible to add new predeclared types without breaking
working programs.
Ian
> A programmer reading this part of the code will expect it to be a> typeswitch, and he might discover that its an expression switch. MySeparating the notion of a reserved word from the notion of a
> question is simple: Why allow programmer to declare variable names as
> typenames? Disallowing it will simplify the language and its usage,
> isn't it?
predeclared type name seems like good practice to me, though I agree
that it can lead to confusion such as you describe. The benefit is
that it is possible to add new predeclared types without breaking
working programs.
I see. One of the reasons that Go is very simple to parse is that all
names are in a single namespace (except labels, which may only be used
in very constrained ways). I think that is also a useful feature. It
follows that the name of a variable can shadow the name of a type.
Ian
You are talking about style, but there is one consideration first:
* If parser can understand, what is variable and what is type without
knowing the context, so can you. Thus, simply get experienced and you
should do the distinction very fast.
Second is about the style:
* In many cases, writing general functions, you actually don't know
much more about your variable than it's type - I have used variable
names "aint", "int1", "int2" or "_int" a lot in different languages;
also the variable name "str" everywhere when "string" is a type,
"bool" in case boolean is type name etc. That's because you have such
operations - for example, when taking absolute value, only thing you
know about input is that it might not be an absolute value of itself.
You cant call it "nonAbs" or "relative"; you mostly call it a "number"
or to be more exact, tell a kind of number. Similarly, when splitting
a string, you don't know that it haven't been split before (thus you
would lie when calling it "unsplitString" or "merged") and you end up
by having no more knowledge about this variable than that it's a
string.
* In some languages where you put some mark before variable name, like
"$" in PHP, it's simple to use $Array for some random array (I don't
remember right now if it's possible in PHP, but I think I have used
this pattern there). This is often favourable.
Thus, this other consideration is not the only way. And - if you can't
separate a variable name from it's type, find an editor, which can ;)
Simply color variables red and types bold black and you wont miss the
difference. For poor editors not suggesting me things I often try
different function names until some of them is colored blue in case of
doubt ;) This is, in such case, good to make those colors very
natively understandable - maybe storing your color profile to network
storage so that you can access it always and use. Anyway, you should
be able to differentiate variable from type without looking even local
context, because as far as I know, parsing Go at this level does not
need that.
On Dec 29, 12:18 am, Ian Lance Taylor <i...@google.com> wrote:
> SnakE <snake.sc...@gmail.com> writes:
> > 2009/12/28 Ian Lance Taylor <i...@google.com>
Go is using:
* Yacc parser in 6g
* Some other parser in gccgo
* Custom parser in gofmt etc.
There are a few things about gofmt:
* You should be able to format everything right from editor without
having any makefiles connected to it
* You should be able to paste your code to some web page without it
having the context
Declarations of types are in other packages.
Yes, disallowing the use of keywords as identifiers is a trivial
change. In the last quoted section I was replying to a comment about
a different approach.
Ian
gc/kencc use bison in the Go source tree.
--dho
They're just names. Bad names can always be created.
Restrictions add complexity without solving that problem.
I think that int is a good name in Modf. Similarly, there
are at least four methods in the tree named uint32, and
I think it's a good name in those uses too.
As a Go programmer, I'd rather be trusted to make good
decisions than expected to make bad ones. A language
with goto has no business telling programmers they can't
name a variable int.
Russ