Golang returning functions - go

Can anyone explain why 0's and 1's are printed and not anything else? Thank you!
func makeFunction(name string) func() {
fmt.Println("00000")
return func() {
makeFunction2("abcef")
}
}
func makeFunction2(name string) func() {
fmt.Println("11111")
return func() {
makeFunction3("safsf")
}
}
func makeFunction3(name string) func() {
fmt.Println("33333")
return func() {
fmt.Printf("444444")
}
}
func main() {
f := makeFunction("hellooo")
f()
}
Can anyone explain why 0's and 1's are printed and not anything else? Thank you!

Let's follow the program flow:
main starts.
main calls makeFunction.
makeFunction prints 00000, and returns an anonymous function.
Back in main, we call the anonymous function returned by the previous call.
The anonymous function calls makeFunction2.
makeFunction2 prints 11111, and returns an anonymous function.
main returns.
Because the return value is discarded after step 6 above, nothing else is printed.

Let's look at your main:
Line 1
f := makeFunction("hellooo")
Side effect: printing "00000"
Return value: an anonymous function that executes makeFunction2("abcef"), assigned to the identifier f
Line 2
f()
which is equivalent to:
_ = f()
Side effect: printing "11111"
Return value: an anonymous function that executes makeFunction3("safsf"), discarded (you are not assigning the return value of f()).
makeFunction3 is never assigned to any identifier, and never called.

To prints the 3's, you have to call twice:
f()()
And to prints the 4's too, just do:
f()()()
Because ...
// prints "00000" and returns a function that if run
// will invoked `makeFunction2`
f := makeFunction("hello")
// `makeFunction2` is called, printing "11111" and returns
// a function that if run will invoked `makeFunction3`
f1 := f()
// `makeFunction3` is called, printing "33333" and returns
// a function that if run will invoked `makeFunction4`
f2 := f1()
Test question, what does it print out if you do this?
f := makeFunction("Hello")()()
f()
This is known as currying or closure, but in your example you have not closed over any local value so the latter loses its meaning.

makeFunction only return the function makeFunction2. since this is not a recursive function. If you expecting to behave like recursive function, then you should change return func(){} to (return makeFunction2 or 3)
func makeFunction(name string) func() {
fmt.Println("00000")
return makeFunction2("abcef")
}
func makeFunction2(name string) func() {
fmt.Println("11111")
return makeFunction3("safsf")
}
func makeFunction3(name string) func() {
fmt.Println("33333")
return func() {
fmt.Printf("444444")
}
}
func main() {
f := makeFunction("hellooo")
f()
}
// Output:
00000
11111
33333
444444

The Reason is it only returns the anonymous funtions.
package main
import "fmt"
func makeFunction(name string) func() {
fmt.Println("00000")
return func(){
makeFunction2("abcef")()
}
}
func makeFunction2(name string) func() {
fmt.Println("11111")
return func() {
makeFunction3("safsf")()
}
}
func makeFunction3(name string) func() {
fmt.Println("33333")
return func() {
fmt.Printf("444444")
}
}
func main() {
f := makeFunction("hellooo")
f()
}

Related

Is it safe to return and modify primitive values during func return

(question reworded based on discussion, original question below)
The Go Language Specification gives examples showing that order of evaluation for primitives is unspecified with respect to function calls during assignment to slices and maps. None of the examples mention multi-value return though, so I'm not sure if they apply in this case or not.
Examples from the spec
a := 1
f := func() int { a++; return a }
x := []int{a, f()} // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
m := map[int]int{a: 1, a: 2} // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified
n := map[int]int{a: f()} // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified
Using the language of the spec, is this functions return also unspecified:
func run() (int, int) {
a := 1
f := func() int { a++; return a }
return a, f() // always return 1,2 OR always returns 2,2 OR can return either?
}
If the order of evaluation is not specified then a non-toy example like the following could break at some time in the future if the compiler is updated:
func CountRows(ctx context.Context, db *pgxpool.Pool) (int, error) {
row := db.QueryRow(ctx, "SELECT COUNT(*)")
var count int
return count, row.Scan(&count)
}
Original Question
I'm unclear whether the go language specification is clear on whether values returned from funcs are "returned" one at a time or once all expressions are evaluated.
Aka is this code guaranteed to always output 10 <nil> (as it does in the playground) or can it ever output 0 <nil>?
package main
import "fmt"
func main() {
fmt.Println(run())
// Output: 10 <nil>
}
func run() (int, error) {
var i int
return i, inc(&i)
}
func inc(i *int) error {
*i = *i + 10
return nil
}
Edit
This related question suggests that order of evaluation of the primitive return value is not specified by the specification
"Is this function return also unspecified?"
Yes. As you found, the language specifies the evaluation order for some things:
when evaluating the operands of an expression, assignment, or return statement, all function calls, method calls, and communication operations are evaluated in lexical left-to-right order.
Naturally, anything that is not a function call, method call or communication operation is left unspecified with respect to evaluation order in an expression, assignment or return statement.
"a non-toy example like the following could break at some time in the future if the compiler is updated"
Yes. Even if the compiler doesn't update. If you expect it to have any particular result that's reliant on evaluation order, then the code is already broken in the sense that the language does not say the code will do what you think it will do.
"are values returned from funcs "returned" one at a time or once all expressions are evaluated."
There is no such distinction to be made.
"is this code guaranteed to always output 10 <nil> (as it does in the playground) or can it ever output 0 <nil>?"
Yes, it can output 0, <nil>. This is essentially the same as the previous run example, where now the closure f has been refactored as a function called inc.
Yes! This is a really great question.
Another way to write this code is
package main
import "fmt"
func main() {
fmt.Println(run())
// Output: 10 <nil>
}
func run() (int, error) {
var i int
err := inc(&i)
return i, err
}
func inc(i *int) error {
*i = *i + 10
return nil
}
This is the same reason why you can do the following
func main() {
callIt()
}
func callIt() (int, error) {
return multiReturn()
}
func multiReturn() (int, error) {
return 0, nil
}
And additionally, you can do this as well, which can be useful if you wrap a db transaction (for example) in an error handler
func main() {
result, err := assignInReturn()
if err != nil {
panic(err)
}
// the result here, assuming no error occurred, will be 1...
fmt.Println(result)
}
func assignInReturn() (int, error) {
var i int
return i, wrapErrFunc(func() error {
// db call
if err := dbCall(); err != nil {
return err
}
i = 1 // ...because of this. This will set `i` to 1 before `assignInReturn` returns to its caller
return nil
})
}
func wrapErrFunc(fn func() error) error {
return fn()
}
func dbCall() error {
// db query
return nil
}
In these situations, you can be certain that the items in the top-level return will evaluate prior to being returned to its caller

Go type for function call

Keywords like go and defer expect a function call as parameters. Is there a type available that can be used the same way? (e.g. to write a function that expects a function call - opposed to a function - as argument).
No there is not. You can't do the same with your function.
go and defer are backed by the language spec and the rule is enforced by the compiler.
What you may do is use a variable / value of function type, which you may call later / at any time as if it would be a function.
For example:
func myFunc() {
fmt.Println("hi")
}
func main() {
var f func()
f = myFunc
f() // This calls the function value stored in f: myFunc in this example
}
Edit: To have the functionality you mentioned in the comment: just wrap the function call with its arguments in a func(), and use / pass that.
For example:
func launch(f func()) {
fmt.Println("Before launch")
go func() {
defer fmt.Println("After completion")
f()
}()
}
Using it:
func main() {
launch(func() {
fmt.Println("Hello, playground")
})
time.Sleep(time.Second)
}
Which outputs (try it on the Go Playground):
Before launch
Hello, playground
After completion
Yes, this is not an exact workaround. If the params may change, you have to make a copy of them before calling launch(), and use the copy in the function literal (closure), like in this example:
s := "Hello, playground"
s2 := s // make a copy
launch(func() {
fmt.Println(s2) // Use the copy
})
s = "changed"
Mimicing automatic parameter saving
For a concrete function type we may construct a helper function which provides us automatic parameter saving. This helper function must have identical signature, and return a function without parameters. The returned function is a closure which calls the original function with the parameters. The act of calling this helper function is the mechanism to save the parameters, so the usage is identical to that of defer.
For example the helper for fmt.Println(s) is:
func wrapPrintln(s string) func() {
return func() {
fmt.Println(s)
}
}
And using it:
launch(wrapPrintln(s))
Example for a function with 2 int parameters:
func Sum(a, b int) {
fmt.Println("Sum:", a+b)
}
func WrapSum(a, b int) func() {
return func() {
Sum(a, b)
}
}
launch(WrapSum(a, b))
The above WrapPrintln() and WrapSum() wrapped a concrete function, and it can't be used for other functions (the wrapped function is "wired in"). We can make the wrapped functions a parameter too:
func WrapFuncIntInt(f func(a, b int), a, b int) func() {
return func() {
f(a, b)
}
}
And we may use it like this:
launch(WrapFuncIntInt(Sum, a, b))
Try this one on the Go Playground.
Using reflection to avoid the manual copies
You may use reflection to avoid having to make manual copies, but in this solution we're not actually calling the function, just passing it. Also due to using reflection, it will be slower. Another advantage is that this "feels" generic (we may use functions with different signatures), but we lose compile-time safety.
func launch(f interface{}, params ...interface{}) {
fmt.Println("Before launch")
go func() {
defer fmt.Println("After completion")
pv := make([]reflect.Value, len(params))
for i, v := range params {
pv[i] = reflect.ValueOf(v)
}
reflect.ValueOf(f).Call(pv)
}()
}
Example calling it:
func main() {
i, s := 1, "Hello, playground"
launch(fmt.Printf, "%d %q\n", i, s)
i, s = 2, "changed"
time.Sleep(time.Second)
}
Which outputs (try it on the Go Playground):
Before launch
1 "Hello, playground"
After completion
Single exception where you can utilize automatic parameter saving
There is a single exception which we may use. This is the Method value. If x has static type T and T's method set contains the method M, we may use x.M (without calling it).
The expression x.M is a method value, and it saves a copy of x which will be used as the receiver when the expression's result (which is a function value) is called.
Example:
type myParams struct {
format string
i int
s string
}
func (mp myParams) Call() {
fmt.Printf(mp.format, mp.i, mp.s)
}
func main() {
p := myParams{format: "%d %q\n", i: 1, s: "Hello, playground"}
launch(p.Call) // p is saved here
p.i, p.s = 2, "changed"
time.Sleep(time.Second)
}
func launch(f func()) {
fmt.Println("Before launch")
go func() {
defer fmt.Println("After completion")
f()
}()
}
It outputs the same. Try it on the Go Playground.

why input.Text() is evaluated in the main goroutine

In chapter 8 of The Go Programming Language, there is a description to the concurrency echo server as below:
The arguments to the function started by go are evaluated when the go statement itself is executed; thus input.Text() is evaluated in the main goroutine.
I don't understand this. Why the input.Text() is evaluated at the main goroutine? Shouldn't it be in the go echo() goroutine?
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
// See page 224.
// Reverb2 is a TCP server that simulates an echo.
package main
import (
"bufio"
"fmt"
"log"
"net"
"strings"
"time"
)
func echo(c net.Conn, shout string, delay time.Duration) {
fmt.Fprintln(c, "\t", strings.ToUpper(shout))
time.Sleep(delay)
fmt.Fprintln(c, "\t", shout)
time.Sleep(delay)
fmt.Fprintln(c, "\t", strings.ToLower(shout))
}
//!+
func handleConn(c net.Conn) {
input := bufio.NewScanner(c)
for input.Scan() {
go echo(c, input.Text(), 1*time.Second)
}
// NOTE: ignoring potential errors from input.Err()
c.Close()
}
//!-
func main() {
l, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := l.Accept()
if err != nil {
log.Print(err) // e.g., connection aborted
continue
}
go handleConn(conn)
}
}
code is here: https://github.com/adonovan/gopl.io/blob/master/ch8/reverb2/reverb.go
How go keyword works in Go, see
Go_statements:
The function value and parameters are evaluated as usual in the calling goroutine, but unlike with a regular call, program execution does not wait for the invoked function to complete. Instead, the function begins executing independently in a new goroutine. When the function terminates, its goroutine also terminates. If the function has any return values, they are discarded when the function completes.
The function value and parameters are evaluated in place with the go keyword (same for the defer keyword see an example for defer keyword).
To understand the evaluation order, let's try this:
go have()(fun("with Go."))
Let's run this and read the code comments for the evaluation order:
package main
import (
"fmt"
"sync"
)
func main() {
go have()(fun("with Go."))
fmt.Print("some ") // evaluation order: ~ 3
wg.Wait()
}
func have() func(string) {
fmt.Print("Go ") // evaluation order: 1
return funWithGo
}
func fun(msg string) string {
fmt.Print("have ") // evaluation order: 2
return msg
}
func funWithGo(msg string) {
fmt.Println("fun", msg) // evaluation order: 4
wg.Done()
}
func init() {
wg.Add(1)
}
var wg sync.WaitGroup
Output:
Go have some fun with Go.
Explanation go have()(fun("with Go.")):
First in place evaluation takes place here:
go have()(...) first have() part runs and the result is fmt.Print("Go ") and return funWithGo, then fun("with Go.") runs, and the result is fmt.Print("have ") and return "with Go."; now we have go funWithGo("with Go.").
So the final goroutine call is go funWithGo("with Go.")
This is a call to start a new goroutine so really we don't know when it will run. So there is a chance for the next line to run: fmt.Print("some "), then we wait here wg.Wait(). Now the goroutine runs this funWithGo("with Go.") and the result is fmt.Println("fun", "with Go.") then wg.Done(); that is all.
Let's rewrite the above code, just replace named functions with anonymous one, so this code is same as above:
For example see:
func have() func(string) {
fmt.Print("Go ") // evaluation order: 1
return funWithGo
}
And cut this code select the have part in the go have() and paste then select the have part in func have() and press Delete on the keyboard, then you'll have this:
This is even more beautiful, with the same result, just replace all functions with anonymous functions:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() func(string) {
fmt.Print("Go ") // evaluation order: 1
return func(msg string) {
fmt.Println("fun", msg) // evaluation order: 4
wg.Done()
}
}()(func(msg string) string {
fmt.Print("have ") // evaluation order: 2
return msg
}("with Go."))
fmt.Print("some ") // evaluation order: ~ 3
wg.Wait()
}
Let me explain it with a simple example:
1. Consider this simple code:
i := 1
go fmt.Println(i) // 1
This is clear enough: the output is 1.
But if the Go designers decided to evaluate the function argument at the function run-time nobody knows the value of i; you might change the i in your code (see the next example)
Now let's do this closure:
i := 1
go func() {
time.Sleep(1 * time.Second)
fmt.Println(i) // ?
}()
The output is really unknown, and if the main goroutine exits sooner, it even won't have a chance to run: Wake up and print the i, which is i itself may change to that specific moment.
Now let's solve it like so:
i := 1
go func(i int) {
fmt.Printf("Step 3 i is: %d\n", i) // i = 1
}(i)
This anonymous function argument is of type int and it is a value type, and the value of i is known, and the compiler-generated code pushes the value 1 (i) to the stack, so this function, will use the value 1, when the time comes (A time in the future).
All (The Go Playground):
package main
import (
"fmt"
"sync"
"time"
)
func main() {
i := 1
go fmt.Println(i) // 1 (when = unknown)
go fmt.Println(2) // 2 (when = unknown)
go func() { // closure
time.Sleep(1 * time.Second)
fmt.Println(" This won't have a chance to run", i) // i = unknown (when = unknown)
}()
i = 3
wg := new(sync.WaitGroup)
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Printf("Step 3 i is: %d\n", i) // i = 3 (when = unknown)
}(i)
i = 4
go func(step int) { // closure
fmt.Println(step, i) // i=? (when = unknown)
}(5)
i = 5
fmt.Println(i) // i=5
wg.Wait()
}
Output:
5
5 5
2
1
Step 3 i is: 3
The Go Playground output:
5
5 5
1
2
Step 3 i is: 3
As you may be noticed, the order of 1 and 2 is random, and your output may differ (See the code comments).

Why isn't the return value returned when this deferred statement (without a return) runs?

I am reading through the go specification and don't fully understand the behavior of an example for defer.
// f returns 1
func f() (result int) {
defer func() {
result++
}()
return 0
}
The function has a named return, which an anonymous deferred function increments. The function ends with "return 0". This value is not returned, but the incremented variable instead.
In trying to understand this behavior, I've run into more questions. If I assign a value to the return variable, that seems to have no effect on the return value.
//b returns 1
func b() (result int) {
result = 10
defer func() {
result++
}()
return 0
}
However, if the last line is changed to:
return result
Things behave as I would expect.
https://play.golang.org/p/732GZ-cHPqU
Can someone help me better understand why these values get returned and the scope of these functions.
The specification says this about deferred functions:
if the deferred function is a function literal and the surrounding function has named result parameters that are in scope within the literal, the deferred function may access and modify the result parameters before they are returned.
and and this about return statements:
A "return" statement that specifies results sets the result parameters before any deferred functions are executed.
Example 1:
func f() (result int) {
defer func() {
result++
}()
return 0
}
The result variable is initialized to zero; the return statement sets result to zero; the deferred function increments result to 1; the function returns 1.
Example 2:
func b() (result int) {
result = 10
defer func() {
result++
}()
return 0
}
The result variable is set to 10 in the first statement of the function; the return statement sets result to zero; the deferred function increments result to 1; the function returns 1.
Example 3:
func c() (result int) {
result = 10
defer func() {
result++
}()
return result
}
The result variable is set to 10 in the first statement of the function; the return statement sets result to 10; the deferred function increments result to 11, the function returns 11.

How does defer and named return value work?

I just started learning Go and I got confused with one example about using defer to change named return value in the The Go Blog - Defer, Panic, and Recover.
The example says:
Deferred functions may read and assign to the returning function's named return values.
In this example, a deferred function increments the return value i after the surrounding function returns. Thus, this function returns 2:
func c() (i int) {
defer func() { i++ }()
return 1
}
But as what I have learned from A Tour of Go - Named return values
A return statement without arguments returns the named return values. This is known as a "naked" return.
I tested in the following code and in function b it returns 1 because it wasn't the "A return statement without arguments" case mentioned above.
func a() (i int) { // return 2
i = 2
return
}
func b() (i int) { // return 1
i = 2
return 1
}
So my question is in the first example, the surrounding function c has a named return value i, but the function c uses return 1 which in the second example we can see it should have return 1 no matter what value i is. But why after i changes in the deferred function the c function returns the value of i instead the value 1?
As I was typing my question, I might have guessed the answer. Is it because:
return 1
is equals to:
i = 1
return
in a function with a named return value variable i?
Please help me confirm, thanks!
A defer statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns. -- The Go Blog: Defer, Panic, and Recover
Another way to understand the above statement:
A defer statements pushes a function call onto a stack. The stack of saved calls popped out (LIFO) and deferred functions are invoked immediately before the surrounding function returns.
func c() (i int) {
defer func() { i++ }()
return 1
}
After 1 is returned, the defer func() { i++ }() gets executed. Hence, in order of executions:
i = 1 (return 1)
i++ (defer func pop out from stack and executed)
i == 2 (final result of named variable i)
For understanding sake:
func c() (i int) {
defer func() { fmt.Println("third") }()
defer func() { fmt.Println("second") }()
defer func() { fmt.Println("first") }()
return 1
}
Order of executions:
i = 1 (return 1)
"first"
"second"
"third"
According to the Go Specification:
Return Statements
A "return" statement that specifies results sets the result parameters before any deferred functions are executed.
Defer Statements
"...deferred functions are invoked immediately before the surrounding function returns..."
So yes, as you assumed, the named return variable is assigned, then the deferred statement increments it.
I would add that named return parameters can lead to subtle bugs, and generally should be avoided unless there's no alternative.
I think the confusion is about function in function how about if you classified like this:
func main() {
fmt.Println(c()) //the result is 5
}
// the c function returned value is named j
func c() (j int) {
defer changei(&j)
return 6
}
func changei(j *int) {
//now j is 6 because it was assigned by return statement
// and if i change guess what?! i changed the returned value
*j--;
}
but if the return value is not named like this:
func main() {
fmt.Println(c()) //the result will become 6
}
// the c function returned value is not named at this time
func c() int {
j := 1
defer changei(&j)
return 6
}
func changei(j *int) {
//now j = 1
// and if i change guess what?! it will not effects the returned value
*j--;
}
I hope this will clear the confusion and that is how i did happy Go coding

Resources