Why Value To Variable X Increasing In Function? - go

I am unable to understand to why value of x increase even after scope end for varaiable ‘x’ in function foo(). It’s must reset to zero everytime I called a function. This this not happening why?
package main
import "fmt"
func main() {
a := foo()
fmt.Printf("%d\n", a())
fmt.Printf("%d\n", a())
fmt.Printf("%d\n", a())
}
func foo() func() int {
var x int // value should reset to zero
return func() int {
x++
return x
}
}
Go Playground

Your function foo returns a new function each time it's called. foo doesn't just create that function though, it also allocates memory for a variable called x of type int. That variable is declared in the scope of foo, and as such, the function foo returns has access to that variable.
In essence, you're returning what is often referred to as a closure. A function that has access to a scope (variables) that are invisible to any other code. To visually represent this, maybe thing of it like this:
The function is what you return, the "environment record" it holds on to is the function body of foo, and all of the variables declared there (in your case x). The next environment record would be the package (variables declared outside functions with var).
So what happens exactly:
a := foo()
Here, foo allocates variable x, and returns a function that holds on to this new variable.
a() // returns 1
a() // returns 2
The x variable created by foo is incremented, and its new value is returned each time.
Now that you know this, you should be able to work out what the output here will be:
a, b := foo(), foo() // creates 2 functions, 2 variables called x
_ = a()
_ = a()
fmt.Printf("a call returned %d\nb call returned %d\n", a(), b())
The output should be "a call returned 3 b call returned 1"

Related

Why are structure functions the same type as ordinary functions

In following codes:
type of struct Struct.Test is void func(), the function can get all parameters in Struct t, why the types of Struct.func() and func() are the same
type Struct struct {
Val string
}
func (t *Struct) Test() {
println(t.Val)
}
func main() {
t := Struct{
Val: "Struct",
}
f := t.Test
f()
f = func() {
println("Hello world!")
}
f()
}
t.Test is a method value:
If the expression x has static type T and M is in the method set of type T, x.M is called a method value. The method value x.M is a function value that is callable with the same arguments as a method call of x.M. The expression x is evaluated and saved during the evaluation of the method value; the saved copy is then used as the receiver in any calls, which may be executed later.
The x.Test() method has no parameters, so x.Test is a function without parameters. The receiver x is saved internally and used when you call the x.Test function value later. Its type will be func(), so type of f is also func(), to which you can assign any value that also has a type of func().
Don't confuse method values with method expressions:
If M is in the method set of type T, T.M is a function that is callable as a regular function with the same arguments as M prefixed by an additional argument that is the receiver of the method.
The method expression is "applied" on a type, while a method value is "applied" on a value. Method expression results in a function value that includes the receiver type (as the first parameter), method value does not (the receiver is saved internally).
So in your case the method expression would be (*Struct).Test (note the pointer: Test() has pointer receiver), and it's a function with type func(Struct). It may be used / called like this:
f2 := (*Struct).Test
f2(&t)
Which again outputs Struct, try it on the Go Playground.

Go - The difference between var and func to define a function

I'm coming from an Scala background, and in Scala, you could define functions both as a single value, or an actual function, for instance:
val inc1: Int => Int = _ + 1 // single FUNCTION value
def inc2(x: Int): Int = x + 1 // normal function definition
// in this case "inc1 eq inc1" is true, since this is a single instance
// but "inc2 eq inc2" is false
And these 2 have some differences (i.e., size allocation, first one is a single instance, while the other one returns an instance each time it is invoked, ...), so based on the use case, we could kind of reason which one to use. Now I'm new to golang, and wanted to know if the below 2 function definitions (correct me if I'm wrong with the phrase) differ in Golang, and if so, what are differences?
var inc1 = func(x int) int { return x + 1 }
func inc2(x int) int { return x + 1 }
Thanks in advance!
Scala borrows a lot from functional programming. Go does not.
(If you've used multiple other programming languages, you should definitely read the Go specification. It's not very long as Go is not a very large language, although the new generics definitely complicate things a bit.)
In Go, the func keyword introduces a function definition or function type, with the details being context-dependent. The var keyword introduces a variable declaration.1 So:
func inc2(x int) int { return x + 1 }
defines a function, inc2, whose code is as shown. But:
var inc1 = // ...
declares and then initializes a variable, inc1. The type and initial value of the variable are determined by the commented-out section, so:
var inc1 = func(x int) int { return x + 1 }
defines a function (with no name) whose code is as shown. That function is then assigned to the variable as its initial value, so that the implied type of the variable is func (int) int or function taking one argument of type int and returning one value of type int.
Having created a variable, you can now either call the function currently stored in that variable:
func callit(arg int) {
result := inc1(arg)
// ... do something with the result ...
}
Or you can assign a new value into the variable, e.g.:
func overwrite() {
inc1 = func(a int) int { return a * 2 } // name `inc1` is now misleading
}
Because inc2 is a function, you can't re-assign a new value to it: it's just a function, not a variable.
1Note that a variable declaration with an initialization can use the "short declaration" form:
func f() {
v := 3
// ...
}
where we leave out the type and just say "use the type of the expression to figure out the type of the declaration". This declares and initializes the variable. Short declarations can only appear in block scope, so these must be inside some function. Other than omitting the var keyword they do nothing that you couldn't do by including the var keyword, or sometimes multiple var keywords:
result, err := doit()
might require:
var result someType
var err error
result, err = doit()
when written without using the short-declaration form.

What is the result of a single variable expression evaluation

Running the following snippet of Go code one can realize that function foo receives the value of the first argument actually set while evaluating the second argument of the function. This behavior might look counterintuitive so that we need to prove this to be a part of language spec, not something implementation-specific.
package main
import (
"fmt"
)
func setVal(s *int, v int) int {
old := *s
*s = v
return old
}
func foo(s int, p int) {
fmt.Printf("s = %d, p = %d\n", s, p)
}
func main() {
var s int
foo(s, setVal(&s, 99))
}
Programm outputs s = 99, p = 0, which means a modified value of variable s has been passed to the function.
Here is what the Go spec says regarding the case.
In a function call, ...arguments must be single-valued expressions ... arguments are evaluated in the usual order. After they are evaluated, the parameters of the call are passed by value to the function... Where usual order is the lexical left-to-right order.
A variable is a storage location for holding a value. ...A variable's value is retrieved by referring to the variable in an expression; it is the most recent value assigned to the variable.
Therefore foo(s, setVal(&s, 99)) is a function call, variable s and function setVal() are the single-valued expressions, and s is evaluated first. The last spec statement makes one assume the result of a variable evaluation is its value, so if that is true, function foo should receive initial value of the variable s.
But it in fact it appears that the function receives the value of the first argument been set at the moment of evaluating the second argument, which is a bit confusing.
Does that mean the evaluation order is broken or the result of a variable evaluation is not its value?
What you "miss" from the spec is Spec: Calls:
In a function call, the function value and arguments are evaluated in the usual order. After they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution.
Evaluating the parameters does not mean their values are read or "taken". The first parameter is s, its evaluation is s itself, but its value is not yet read. The second parameter is evaluated, which means setVal() is called and will modify the value of s.
Now that we have evaluated the parameters, their values are read, so s will have the value 99.
Evaluating s in the example is trivial, but of course that could be a more complex expression just like the second argument. Here's a more complex example:
s, s2 := new(int), new(int)
getFunc := func() func(s int, p int) { return foo }
first := func(a, b *int) *int { return a }
getFunc()(*first(s, s2), setVal(s, 99))
Call of the last function involves the following steps:
function value is evaluated: getFunc() is called, it's return value will be the function value
parameters are evaluated:
(a) first() is called, its return value is dereferenced;
(b) setVal() is called, its return value will be used
And now the values are taken: value of *s and the old value of s (value returned by setVal()).
This will output the same as your example, try it on the Go Playground.

golang reflect get closure function pointer

please review code
package main
import (
"fmt"
"reflect"
)
func main() {
factory := func (name string) func(){
return func (){
fmt.Println(name)
}
}
f1 := factory("f1")
f2 := factory("f2")
pf1 := reflect.ValueOf(f1)
pf2 := reflect.ValueOf(f2)
fmt.Println(pf1.Pointer(), pf2.Pointer())
fmt.Println(pf1.Pointer() == pf2.Pointer())
f1()
f2()
}
the result:
4199328 4199328
true
f1
f2
Why get to the same address of the closure function!
Or to how to get a unique address!
Function pointers denote the code of the function. And the code of an anonymous function created by function literal is only stored once in memory, no matter how many times the code that returns the anonymous function value runs. This means all function values (or more precisely the function pointers) will be the same.
So you can't distinguish between the values stored in f1 and f2: they denote the same code block to be executed when they are called.
The function value that is returned by the function value stored in your factory variable is a closure. The environment (local variables and function parameters) referred by it survives for as long as it is accessible. In your case this means since the function values in f1 and f2 refer to the name argument of the enclosing anonymous function, they ("they" as from multiple calls) will be retained as long as the function values (in f1 and f2) are accessible. This is the only thing that makes them "different" or unique, but this is invisible from the "outside".
Would you go ahead and print the address of name in the closure, you'd see they are different variables for multiple values of the closure, but it is the same if the same closure (function value) is called again. First modify the closure to also print the address of name:
factory := func(name string) func() {
return func() {
fmt.Println(name, &name)
}
}
And call f1 and f2 multiple times:
f1()
f2()
f1()
f2()
Output:
f1 0x1040a120
f2 0x1040a130
f1 0x1040a120
f2 0x1040a130
As you can see, the name argument is retained and the same name argument is used again if the same closure is invoked again.
https://golang.org/pkg/reflect/#Value.Pointer
If v's Kind is Func, the returned pointer is an underlying code
pointer, but not necessarily enough to identify a single function
uniquely. The only guarantee is that the result is zero if and only if
v is a nil func Value.
Actually, *func() type in Go is equivalent to void (*)(void) type in C. (I know this because I use cgo often.)
And a Go func() is defined as a literal, meaning that it's something like a blob of bytes that represent machine code, rather than a function pointer.
Note that everything is passed by value in Go, and even a function is not an exception.
var f1 func() = ...
reflect.ValueOf(f1)
When you do that, I think you're trying to get the first 8 bytes of a code block called f1, and that is not an address to that function.
In current version of Go you can't take an address of a func() because an anonymous func() is only a literal denoting a code block that's located nowhere in memory. So you can't get an address to that.

Go passing parameters of pointers or copies to functions

I am contemplating on the Go pointers, passing variables as parameters to functions by value or by reference. In a book I have encountered a good example, which is the first code snippet below, on passing a pointer.
The first version is working as expected, in function that takes parameter of a pointer makes changes to the variable itself, not on a copy of it. But the second example below I am tinkering with works on a copy of it. I have thought they should behave equivalently, and second one to work on the variable passed as parameter, not on copy of it.
Essentially, what these two versions of the function is behaving different?
version in the book, passing parameters by reference:
package main
import (
"fmt"
)
// simple function to add 1 to a
func add1(a *int) int {
*a = *a+1 // we changed value of a
return *a // return new value of a
}
func main() {
x := 3
fmt.Println("x = ", x) // should print "x = 3"
x1 := add1(&x) // call add1(&x) pass memory address of x
fmt.Println("x+1 = ", x1) // should print "x+1 = 4"
fmt.Println("x = ", x) // should print "x = 4"
}
my alternative tinkering version, passing pointer parameter:
package main
import (
"fmt"
)
// simple function to add 1 to a
func add1(a int) int {
p := &a
*p = *p+1 // we changed value of a
return *p // return new value of a
}
func main(){
fmt.Println("this is my go playground.")
x := 3
fmt.Println("x = ", x) // should print "x = 3"
x1 := add1(x) // call add1(&x) pass memory address of x
fmt.Println("x+1 = ", x1) // should print "x+1 = 4"
fmt.Println("x = ", x) // should print "x = 4"
}
Why should they behave equivalently? In the first example you pass a pointer (to int), in the second example you pass an int value.
What happens in the 2nd example is that you pass an int value. Parameters in functions work like local variables. A local variable called a of type int will be created, and will be initialized with the value you passed (3 which is the value of x). This local variable is addressable like any other variables.
You take its address (p := &a) and you increment the value pointed by this pointer (which is variable a itself). And you return the value pointed by it which is the incremented value of a.
Outside from where you called this add1() function, the value of x is not modified because only the local copy a was modified.
Everything in golang is pass by value, which means the function always gets a copy of the thing being passed.
In your second example, the value of x is actually sent to the function add, so any modification you made to the copy wont affect the original x.
See pass by value

Resources