Go literal func call stmt syntax simplification?

Hi, new here,

I have a question regarding: go func() { … }() — the tail parentheses are needed to make the literal func as being called per the requirement of the go stmt. And it’s an FAQ item I know. My question is why can’t the tail paren be omitted when it’s a literal func there? Or, for that matter when we have a stmt like — go f — why can’t it being interpreted as — go f() — with the compiler adding in the omitted paren automatically. Go already has similar automation in places such as x.y when x is or is not a pointer, the x.y are automatically interpreted. It doesn’t seem as if — go f — can have any other meaning rather than simply meaning — go f() —? Isn’t it a justification for the automation? I’m slightly a little bit of tired of ever having to go back in once more to a go stmt to put in a paren there that I forgot to do the first time.

Thank you for your time!

It would be exceedingly weird to have a single place in the syntax where a function call could be done without parenthesis. It’s also assuming that no parameters are to be given in the function call, otherwise another syntax must be used. The Go language eschews weird special cases, and this would very much be a weird special case.

1 Like

While @calmh is exactly right about go avoiding weird cases, is also worth pointing out that function definition and calling need to be separate.

The following defines a function f

f := func(){...}


f := func(){...}()

defines and calls a function.

How would you deal with the following:

func(){... return func(){...} }

Would your syntax automatically invoke the returned function?

Thanks for the replies!

First @calmh, I was about to say that, for example, go is not scheme, that you have a small number of simple but powerful concepts or constructs, and then you let 'em multiply. And also, even in scheme, you’ve got ultimately strange stuff like call/cc. Almost in any language you can identify strangeness, such as python’s indent syntax, and go’s exact reversal of some aspects of C’s syntax such as []byte; those things can be argued, justified, and after a while, people defend them like an orthodoxy. Another case might be lisp’s syntax: at first, it was a problem too troublesome to be solved, so let us just write parens all over the place, and then, people began to think that’s exactly where the beauty is with lisp. etc. But, I suppose, this kind of argument can lead us to nowhere. :wink:

Then @Matt_Singletary, it’s a solid argument. But, again, say, the doc’d rules regarding uintptr and unsafe.Pointer, or the rules regarding struct embedding and method sets and x.y syntax, ie. the elimination of C’s x->y, you do have rules 1, 2, 3, … to deal with the situations. And, also, look at things such as: &a[0], why don’t we have to write &(a[0]) ie with the parens? OK it’s because the precedence rules, but it’s also because (&a)[0] does not make sense in go. So the rules just falling in place. It does not create mental burden, rather it reduces the burden.

So, if the idea is to let, say, go f stmt to automatically becomes a go f() then what about stmt go f()() and stmt go f(a, b, c)?

or stmt v := f and stmt v := f()

I personally think the cases are pretty clearly separated by themselves. BTW, you’ve to write go func() func() { … return func() {…} } Notice the type of the return value is missed in your example. But, I guess, if my idea is implemented, maybe we’ll have a different FAQ item regarding eg this example should’ve been written as go func() { … go func() {…} } since return value to a go stmt is lost and probably not what the user wanted. While nowadays we have the FAQ item being go f should be written as go f() because this is what the user wanted while everyone incl. the complier can see it, it must be fixed by the user manually.


Anoher example would be that, suppose we have

fchan := make(chan func())

and you have a goroutine receiving from fchan and run the received func in that goroutine.

Then elsewhere in your program, you would have

fchan <- func() {...}

and the func is called. And you do not have a paren at the tail. So, do we have mental burden here, that the lack of the tail paren can cause headache?

Guess I just can’t stop myself, hehehe…

I just want to add that what’s in a go stmt is not actually a func call, but rather sth like:

goroutineApply(f, args...)

If you look at it this way, then when f is a func() ie no arg needed, then the goroutineApply should be able to carry on. The question becomes, why isn’t it allowed? Why are you required to write, say, goroutineApply(f, []interface{}…)?

My wish would be for

go { 
    // Compound statement

to work as though it were go func(){ … }(). Take away the “go” and it compiles.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.