Type that describes any go function - go

I want to write a function that partially applies a function to an argument, like this:
func partial(f AnyFuncType, arg interface{}) AnyFuncType {
return func(args ...interface{}) interface{} {
return f(arg, args)
}
}
type AnyFuncType func(args ...interface{}) interface{}
But that doesn't work even with the simplest function like that
func sum(a int, b int) int {
return a + b
}
func main() {
addToFive := partial(sum, 5)
}
because I get
./prog.go:16:23: cannot use sum (type func(int, int) int) as type AnyFuncType in argument to partial
compilation error. Now, I know that I could use interface{}, but is there a way to specify a more precise type for f that would work with any function?

You are trying to treat interface{} as a generic type, but interface{} is not a generic type and go will not match the signature of a function that takes interface{} as the signature of a function that takes a concrete type.

The problem is, subtyping in GO works only for interaces. Since AnyFuncType is not an interface, this won't work.

Use interface{} to represent a function of any type. There is not a more precise type that works with any function.
Use the reflect package to implement partial.
func partial(f interface{}, arg interface{}) interface{} {
v := reflect.ValueOf(f)
t := v.Type()
var in []reflect.Type
for i := 1; i < t.NumIn(); i++ {
in = append(in, t.In(i))
}
var out []reflect.Type
for i := 0; i < t.NumOut(); i++ {
out = append(out, t.Out(i))
}
var va reflect.Value
if arg != nil {
va = reflect.ValueOf(arg)
} else {
// Support `nil` as partial argument.
va = reflect.Zero(t.In(0))
}
return reflect.MakeFunc(reflect.FuncOf(in, out, t.IsVariadic()),
func(args []reflect.Value) []reflect.Value {
return v.Call(append([]reflect.Value{va}, args...))
}).Interface()
}
Use it like this:
addToFive := partial(sum, 5).(func(int) int)
fmt.Println(addToFive(1))
Run it on the playground.
I recommend using a closure to create partials instead of the partial function in this answer. The closure is more efficient and avoids tricky reflect code.
addToFive := func(x int) int { return sum(5, x) }
fmt.Println(addToFive(1))

Related

How to call closure function obtained through reflection?

I'm experimenting with using Go's reflection library and have come to an issue I cannot figure out: How does one call on a function returned from calling a closure function via reflection? Is it possible to basically have a sequence of:
func (f someType) closureFn(i int) int {
return func (x int) int {
return x+i
}
}
...
fn := reflect.ValueOf(&f).MethodByName("closureFn")
val := append([]reflect.Value{}, reflect.ValueOf(99))
fn0 := fn.Call(val)[0]
fn0p := (*func(int) int)(unsafe.Pointer(&f0))
m := (*fn0p)(100)
Which should get m to equal 199?
The following is the simplified code that demonstrates the issue. The call to the "dummy" anonymous function works ok, as does the reflective call to the closure. However attempts at calling on the closure return fail with a nil pointer (the flag set on the address of the Value in the debugger is 147, which comes down to addressable).
Any suggestions on what's going on, or if it's at all possible are welcome.
Link to playground: https://play.golang.org/p/0EPSCXKYOp0
package main
import (
"fmt"
"reflect"
"unsafe"
)
// Typed Struct to hold the initialized jobs and group Filter function types
type GenericCollection struct {
jobs []*Generic
}
type Generic func (target int) int
func main() {
jjf := &GenericCollection{jobs: []*Generic{}}
jjf.JobFactoryCl("Type", 20)
}
// Returns job function with closure on jobtype
func (f GenericCollection) Job_by_Type_Cl(jobtype int) (func(int) int) {
fmt.Println("Job type is initialized to:", jobtype)
// Function to return
fc := func(target int) int {
fmt.Println("inside JobType function")
return target*jobtype
}
return fc
}
// Function factory
func (f GenericCollection) JobFactoryCl(name string, jobtype int) (jf func(int) int) {
fn := reflect.ValueOf(&f).MethodByName("Job_by_" + name + "_Cl")
val := append([]reflect.Value{}, reflect.ValueOf(jobtype))
if fn != reflect.ValueOf(nil) {
// Reflected function -- CALLING IT FAILS
f0 := fn.Call(val)[0]
f0p := unsafe.Pointer(&f0)
//Local dummy anonymous function - CALLING IS OK
f1 := func(i int) int {
fmt.Println("Dummy got", i)
return i+3
}
f1p := unsafe.Pointer(&f1)
// Named function
pointers := []unsafe.Pointer{f0p, f1p}
// Try running f1 - OK
f1r := (*func(int) int)(pointers[1])
fmt.Println((*f1r)(1))
(*f1r)(1)
// Try calling f0 - FAILS. nil pointer dereference
f0r := (*func(int) int)(pointers[0])
fmt.Println((*f0r)(1))
jf = *f0r
}
return jf
}
Type assert the method value to a function with the appropriate signature. Call that function.
First example from the question:
type F struct{}
func (f F) ClosureFn(i int) func(int) int {
return func(x int) int {
return x + i
}
}
func main() {
var f F
fn := reflect.ValueOf(&f).MethodByName("ClosureFn")
fn0 := fn.Call([]reflect.Value{reflect.ValueOf(99)})[0].Interface().(func(int) int)
fmt.Println(fn0(100))
// It's also possible to type assert directly
// the function type that returns the closure.
fn1 := fn.Interface().(func(int) func(int) int)
fmt.Println(fn1(99)(100))
}
Run it on the Playground
Second example from the question:
func (f GenericCollection) JobFactoryCl(name string, jobtype int) func(int) int {
jf := reflect.ValueOf(&f).MethodByName("Job_by_" + name + "_Cl").Interface().(func(int) func(int) int)
return jf(jobtype)
}
func main() {
jjf := &GenericCollection{jobs: []*Generic{}}
jf := jjf.JobFactoryCl("Type", 20)
fmt.Println(jf(10))
}
Run it on the Playground

Accept function in argument with empty interface return type

I would like to understand why the code snippet below does not compile. What is the Go way of accepting a function as a function argument that may have any return type?
package main
func main() {
test(a) // Error: cannot use a (type func() string) as type func() interface {} in argument to test
test(b) // Error: cannot use b (type func() int) as type func() interface {} in argument to test
}
func a() string {
return "hello"
}
func b() int {
return 1
}
func test(x func() interface{}) {
// some code...
v := x()
// some more code....
}
Play: https://play.golang.org/p/CqbuEZGy12
My solution based on Volker's answer:
package main
import (
"fmt"
)
func main() {
// Wrap function a and b with an anonymous function
// that has an empty interface return type. With this
// anonymous function, the call signature of test
// can be satisfied without needing to modify the return
// type of function a and b.
test(func() interface{} {
return a()
})
test(func() interface{} {
return b()
})
}
func a() string {
return "hello"
}
func b() int {
return 1
}
func test(x func() interface{}) {
v := x()
fmt.Println(v)
}
Play: https://play.golang.org/p/waOGBZZwN7
You tripped over a very common misconception for Go newcomers: The empty interface interface{} does not mean "any type". Really, it does not. Go is statically typed. The empty interface interface {} is an actual (strongly typed type) like e.g. string or struct{Foo int} or interface{Explode() bool}.
That means if something has the type interface{} it has that type and not "any type".
Your function
func test(x func() interface{})
takes one parameter. This parameter is a (parameterless function) which returns a specific type, the type interface{}. You can pass any function to test which matches this signature: "No parameters and return interface{}". None of your functions a and b match this signature.
As said above: interface {} is not a magical abbreviation for "whatever",it is a distinct static type.
You have to change e.g. a to:
func a() interface{} {
return "hello"
}
Now this might look strange as you return a string which is not of type interface{}. This works because any type is assignable to variables of type interface{} (as every type has at least no methods :-).
As the Go specification states:
A function type denotes the set of all functions with the same parameter and result types
In your case, your result types differ (string vs interface{})
To be able to receive a function with any kind of result type, test would have to be defined as:
func text(x interface{}) { ... }
and then you will have to use reflect package to call the function stored in x.
Edit
Such a test function would look like this:
func test(x interface{}) {
v := reflect.ValueOf(x)
if v.Kind() != reflect.Func {
panic("Test requires a function")
}
t := v.Type()
if t.NumIn() != 0 && t.NumOut() != 1 {
panic("Function type must have no input parameters and a single return value")
}
values := v.Call(nil)
val := values[0].Interface()
// some more code..
}
Playground: https://play.golang.org/p/trC2lOSLNE

Check if a slice contains a struct with a given field value

Trying to check if a struct in some slice contains a value of a given field so i wrote this
func main() {
//test
Objs := []Obj{{1,"xxx"},{2,"yyy"},{3,"zzz"}}
res := containsStructFieldValue(Objs,"X",1)
fmt.Println(res)
}
type Obj struct {
X int
Y string
}
func containsStructFieldValue(slice []Obj ,fieldName string,fieldValueToCheck interface {}) bool{
for _,s := range slice{
r := reflect.ValueOf(s)
f := r.FieldByName(fieldName)
if f.IsValid(){
if f.Interface() == fieldValueToCheck{
return true //a field with the given value exists
}
}
}
return false
}
i need it to work for any given struct type but when i tried slice []interface as the parameter i found out that its not possible, any idea on how to make the above method work for any struct type?
You can use reflect to range over an interface{}, for instance:
func containsStructFieldValue(slice interface{} ,fieldName string,fieldValueToCheck interface {}) bool{
rangeOnMe := reflect.ValueOf(slice)
for i := 0; i < rangeOnMe.Len(); i++ {
s := rangeOnMe.Index(i)
f := s.FieldByName(fieldName)
if f.IsValid(){
if f.Interface() == fieldValueToCheck {
return true
}
}
}
}
Note that I did not check that slice is indeed a slice... If not, this code will panic. You can use reflect.Kind to check this if you want to avoid this behaviour.

Wrapper for arbitrary function in Go

Is it possible to create a wrapper for arbitrary function in Go that would take the same arguments and return the same value?
I'm not talking about the wrapper that would look exactly the same, it may look differently, but it should solve the problem.
For example the problem might be to create a wrapper of arbitrary function that first looks for the result of the function call in cache and only in case of cache miss executes the wrapped function.
Here's a solution using reflect.MakeFunc. This particular solution assumes that your transformation function knows what to do with every different type of function. Watch this in action: http://play.golang.org/p/7ZM4Hlcqjr
package main
import (
"fmt"
"reflect"
)
type genericFunction func(args []reflect.Value) (results []reflect.Value)
// A transformation takes a function f,
// and returns a genericFunction which should do whatever
// (ie, cache, call f directly, etc)
type transformation func(f interface{}) genericFunction
// Given a transformation, makeTransformation returns
// a function which you can apply directly to your target
// function, and it will return the transformed function
// (although in interface form, so you'll have to make
// a type assertion).
func makeTransformation(t transformation) func(interface{}) interface{} {
return func(f interface{}) interface{} {
// g is the genericFunction that transformation
// produced. It will work fine, except that it
// takes reflect.Value arguments and returns
// reflect.Value return values, which is cumbersome.
// Thus, we do some reflection magic to turn it
// into a fully-fledged function with the proper
// type signature.
g := t(f)
// typ is the type of f, and so it will also
// be the type that of the function that we
// create from the transformation (that is,
// it's essentially also the type of g, except
// that g technically takes reflect.Value
// arguments, so we need to do the magic described
// in the comment above).
typ := reflect.TypeOf(f)
// v now represents the actual function we want,
// except that it's stored in a reflect.Value,
// so we need to get it out as an interface value.
v := reflect.MakeFunc(typ, g)
return v.Interface()
}
}
func main() {
mult := func(i int) int { return i * 2 }
timesTwo := func(f interface{}) genericFunction {
return func(args []reflect.Value) (results []reflect.Value) {
// We know we'll be getting an int as the only argument,
// so this type assertion will always succeed.
arg := args[0].Interface().(int)
ff := f.(func(int) int)
result := ff(arg * 2)
return []reflect.Value{reflect.ValueOf(result)}
}
}
trans := makeTransformation(timesTwo)
// Since mult multiplies its argument by 2,
// and timesTwo transforms functions to multiply
// their arguments by 2, f will multiply its
// arguments by 4.
f := trans(mult).(func(int) int)
fmt.Println(f(1))
}
The answer based on #joshlf13 idea and answer, but seems more simple to me.
http://play.golang.org/p/v3zdMGfKy9
package main
import (
"fmt"
"reflect"
)
type (
// Type of function being wrapped
sumFuncT func(int, int) (int)
// Type of the wrapper function
wrappedSumFuncT func(sumFuncT, int, int) (int)
)
// Wrapper of any function
// First element of array is the function being wrapped
// Other elements are arguments to the function
func genericWrapper(in []reflect.Value) []reflect.Value {
// this is the place to do something useful in the wrapper
return in[0].Call(in[1:])
}
// Creates wrapper function and sets it to the passed pointer to function
func createWrapperFunction(function interface {}) {
fn := reflect.ValueOf(function).Elem()
v := reflect.MakeFunc(reflect.TypeOf(function).Elem(), genericWrapper)
fn.Set(v)
}
func main() {
var wrappedSumFunc wrappedSumFuncT
createWrapperFunction(&wrappedSumFunc)
// The function being wrapped itself
sumFunc := func (a int, b int) int {
return a + b
}
result := wrappedSumFunc(sumFunc, 1, 3)
fmt.Printf("Result is %v", result)
}
The best I've come up with is to take a function def and return an interface, which will need type assertion afterwards:
func Wrapper(metaParams string, f func() (interface{}, string, error)) (interface{}, error) {
// your wrapper code
res, metaResults, err := f()
// your wrapper code
return res, err
}
Then to use this also takes a little work to function like a wrapper:
resInterface, err := Wrapper("data for wrapper", func() (interface{}, string, error) {
res, err := YourActualFuntion(whatever, params, needed)
metaResults := "more data for wrapper"
return res, metaResults, err
}) // note f() is not called here! Pass the func, not its results
if err != nil {
// handle it
}
res, ok := resInterface.(actualType)
if !ok {
// handle it
}
The upside is this is somewhat generic, can handle anything with 1 return type + error, and doesn't require reflection.
The downside is this takes a lot of work to use as it's not a simple wrapper or decorator.
Building on previous answers and using Go's new generic capabilities, I believe this can be implemented quite elegantly (playground link):
package main
import (
"fmt"
"reflect"
)
// Creates wrapper function and sets it to the passed pointer to function
func wrapFunction[T any](function T) T {
v := reflect.MakeFunc(reflect.TypeOf(function), func(in []reflect.Value) []reflect.Value {
// This is the place to intercept your call.
fmt.Println("Params are:", in)
f := reflect.ValueOf(function)
return f.Call(in)
})
return v.Interface().(T)
}
func main() {
// The function being wrapped itself
sum := func(a int, b int) int {
return a + b
}
wrapped := wrapFunction(sum)
fmt.Printf("Result is %v", wrapped(1, 3))
}
Like this?
var cache = make(map[string]string)
func doStuff(key string) {
//do-something-that-takes-a-long-time
cache[key] = value
return value
}
fun DoStuff(key string) {
if v, ok := cache[key]; ok {
return v
}
return doStuff(key)
}

How to define a function type which accepts any number of arguments in Go?

I try to write a function which takes any other function and wraps a new function around it. This is what I have tried so far:
package main
import (
"fmt"
)
func protect (unprotected func (...interface{})) (func (...interface{})) {
return func (args ...interface{}) {
fmt.Println ("protected");
unprotected (args...);
};
}
func main () {
a := func () {
fmt.Println ("unprotected");
};
b := protect (a);
b ();
}
When I compile this I get the error:
cannot use a (type func()) as type func(...interface { }) in function argument
Why is a function without arguments not compatible to a function with a variable number of arguments? What can I do to make them compatible?
Update:
The protected function should be compatible with the original:
func take_func_int_int (f func (x int) (y int)) (int) {
return f (1)
}
func main () {
a := func (x int) (y int) {
return 2 * x
}
b := protect (a)
take_func_int_int (a)
take_func_int_int (b)
}
Types are pretty concrete in Go. You could try
a := func(_ ...interface{}) {
fmt.Println("unprotected")
}
func (...interface{}) does not mean "any function that takes any number of any kind of arguments", it means "only a function which takes a variable number of interface{} arguments"
Alternatively rather than func(...interface{}) you can just use interface{} and the reflect package. See http://github.com/hoisie/web.go for an example.
EDIT: Specifically, this:
package main
import (
"fmt"
"reflect"
)
func protect(oldfunc interface{}) (func (...interface{})) {
if reflect.TypeOf(oldfunc).Kind() != reflect.Func {
panic("protected item is not a function")
}
return func (args ...interface{}) {
fmt.Println("Protected")
vargs := make([]reflect.Value, len(args))
for n, v := range args {
vargs[n] = reflect.ValueOf(v)
}
reflect.ValueOf(oldfunc).Call(vargs)
}
}
func main() {
a := func() {
fmt.Println("unprotected")
}
b := func(s string) {
fmt.Println(s)
}
c := protect(a)
d := protect(b)
c()
d("hello")
}
Ouput is
Protected
unprotected
Protected
hello
EDIT: To answer the update
Like I said above, types are pretty concrete in Go. The protect function returns a type func(...interface{}) which will never be assignable to func(int)int. I think you're probably either over-engineering your problem or misunderstanding it. However, here's a highly discouraged code snippet that would make it work.
First change protect to also return values:
func protect(oldfunc interface{}) (func (...interface{}) []interface{}) {
if reflect.TypeOf(oldfunc).Kind() != reflect.Func {
panic("protected item is not a function")
}
return func (args ...interface{}) []interface{} {
fmt.Println("Protected")
vargs := make([]reflect.Value, len(args))
for n, v := range args {
vargs[n] = reflect.ValueOf(v)
}
ret_vals := reflect.ValueOf(oldfunc).Call(vargs)
to_return := make([]interface{}, len(ret_vals))
for n, v := range ret_vals {
to_return[n] = v.Interface()
}
return to_return
}
}
Then make a convert function:
func convert(f func(...interface{}) (func(int) int) {
return func(x int) int {
r := f(x)
return r[0].(int)
}
}
Then your call would look like
take_func_int_int(convert(b))
But I promise this isn't what you actually want to do.
Step back and try to rework the problem. I've completely killed type-safety in these examples. What are you trying to accomplish?
package main
import "fmt"
// Here's a function that will take an arbitrary number
// of `int`s as arguments.
func sum(nums ...int) {
fmt.Print(nums, " ")
total := 0
for _, num := range nums {
total += num
}
fmt.Println(total)
}
func main() {
// Variadic functions can be called in the usual way
// with individual arguments.
sum(1, 2)
sum(1, 2, 3)
// If you already have multiple args in a slice,
// apply them to a variadic function using
// `func(slice...)` like this.
nums := []int{1, 2, 3, 4}
sum(nums...)
}

Resources