Go's Declaration Syntax
blog.golang.org
blog.golang.org
Functions do not read from left to right. The example of
func main(argc int, argv *[]byte) int
is explained as "function main takes an int and a pointer to a slice of bytes and returns an int" but it should read "main is a function which takes an int and a pointer to a slice of bytes and returns an int" just like x int
means "x is an integer". Reading left to right the variable name should come first for functions as for other variables so the function syntax should be main func(argc int, argv *[]byte) int
But this can't be so because this appears to be the syntax that function variables use f func(func(int,int) int, int) int
which is explained as "Here's a declaration of a function variable (analogous to a function pointer in C)".Also the article says "Pointers are the exception that proves the rule" because "For familiarity, Go's pointers use the * notation from C, but we could not bring ourselves to make a similar reversal for pointer types.".
Putting these two observations together I would say that Go's declaration syntax fails in its stated mission of simplicity and regularity.
EDIT: can't seem to work out how to code markup on HN, anyway I hope I've made what I'm trying to say clear enough.
UPDATE: two spaces at the start of a line seems to work
In any case, this is just an exception that breaks the rule.
I think your points may be valid, but I don't think they lead to your conclusion that Go's syntax fails at its stated mission.
func(int, *[]byte) int
but the function _declaration_ should be (by the logic of the article and the stated intentions of their design decisions) main func(argc int, argv *[]byte) int
and not func main(argc int, argv *[]byte) int
because the variable name should come first as in x int
and not int x
In this way I fee that they have, if not failed, at least deviated from their stated or implied mission. But you're right, the type reads left to right. main func(int x, char y) int
Is an interesting idea... I don't think I've seen it in use anywhere (though I've mostly dealt with C-like). Add in the curly-braces for the definition, and you've just made functions into variables with blocks. And are they really any different anyway? The code-in-memory doesn't get duplicated when you make another instance, just the scope, so it's equivalent to a variable in a singleton.Just pondering out loud :)
var main = func() { /* etc */ }
It's a minor point, though. The article is clear about how the syntax deviates from complete regularity. Your comment seems redundant.Just a very quick thought after reading Mr Pike's closing words that the use of the asterisk for pointers makes the syntax a bit clumsier than they would have wished.
P := @X;
means assign the address of X to P. And
Y := P^;
means dereference P and assign the result to Y.
I think anyone who has written any Pascal/Delphi would prefer ^ for dereference.
In addition, & and @ are postfix, which pretty much settles the question.
It's my first tool of choice for everything now.
All in all interesting, and I definitely agree with the improvement with their "function-returning function which accepts a function as an argument" example. An interesting departure from C & languages influenced by C (ie: most).
f func(func(int,int) int, int) func(int, int) int
is a simple mechanical transformation away from being a Haskell declaration: f :: ((Int, Int) -> Int, Int) -> (Int, Int) -> IntI write almost exclusively Go day to day and I've noticed I no longer shy away from function pointers like in C. It's not that the C version can't be mastered, it's just that I'd rather not occupy a significant chunk of my brain with it.
Another interesting observation is that I can now pretty easily switch between C and Go if I need to, the declaration syntax seems different enough that my brain can do the leap. Sadly less true for semicolons (Go omits most, C doesn't)