99

Does Go support lambda expressions or anything similar?

I want to port a library from another language that uses lambda expressions (Ruby).

Bruno Brant
  • 7,874
  • 6
  • 43
  • 80
loyalflow
  • 13,363
  • 26
  • 99
  • 162
  • 4
    Go has [anonymous functions](https://en.wikipedia.org/wiki/Anonymous_function#Go), but not short function literals like `x -> x+1`. – Ferran Maylinch Mar 02 '21 at 11:10

7 Answers7

86

Yes.

Here is an example, copied and pasted carefully:

package main

import fmt "fmt"

type Stringy func() string

func foo() string{
  return "Stringy function"
}

func takesAFunction(foo Stringy){
  fmt.Printf("takesAFunction: %v\n", foo())
}

func returnsAFunction()Stringy{
  return func()string{
    fmt.Printf("Inner stringy function\n");
    return "bar" // have to return a string to be stringy
  }
}

func main(){
  takesAFunction(foo);
  var f Stringy = returnsAFunction();
  f();
  var baz Stringy = func()string{
    return "anonymous stringy\n"
  };
  fmt.Printf(baz());
}
Lodewijk Bogaards
  • 19,296
  • 2
  • 27
  • 51
perreal
  • 90,214
  • 20
  • 145
  • 172
  • 30
    I’d love to see more on your question than copied code. First and foremost, you could add a "yes"/"no"/"partly" etc. Then a bit of description, what your code actually does. – Kissaki Aug 02 '12 at 08:55
  • 3
    Kissaki basically he is passing functions to other functions and returning functions from functions, the code is self descriptive and th names are clever, takesaFunction receive a function than return string, returnsAFunction return a function than return a string.....so..yes...go support lambdas perfectly :D .... – clagccs Dec 09 '12 at 04:32
  • 2
    One example that would be really nice to have in here is an example of a lambda function that takes an argument and is called in the same expression it's declared. – Omnifarious Dec 07 '17 at 21:24
  • unfortunatly this example is confusing cause it is using the same name for a function (foo) and a parameter of another function (foo Stringy). I should have not been copied so carefully :) – SeB.Fr Jul 31 '19 at 14:23
  • Any reson not to do baz := func()string{ return "anonymous stringy\n" } – Paul Miller Mar 03 '20 at 01:18
  • Why are there some semicolons in the main? Would that even compile against some version of a Go compiler? – Szymon Brych Apr 03 '20 at 09:24
  • I just note that `type` is not mandatory. You can directly declare `func takesAFunction(foo func()string)` – Ferran Maylinch Oct 18 '21 at 10:17
51

Lambda expressions are also called function literals. Go supports them completely.

See the language spec: http://golang.org/ref/spec#Function_literals

See a code-walk, with examples and a description: http://golang.org/doc/codewalk/functions/

Tim Ford
  • 511
  • 3
  • 2
  • 5
    This is the best answer. I'd add that by "lambdas" people usually consider short function literals like `x -> x+1`, but Go doesn't support that kind of syntax, so you have to write the full `func (x int) { return x+1 }`. – Ferran Maylinch Mar 02 '21 at 11:12
20

Yes

In computer programming, an anonymous function or lambda abstraction (function literal) is a function definition that is not bound to an identifier, and Go supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

    package main
    import "fmt"

    func intSeq() func() int {
        i := 0
        return func() int {
            i += 1
            return i
        }
    }


    func main() {
       nextInt := intSeq()
       fmt.Println(nextInt())
       fmt.Println(nextInt())
       fmt.Println(nextInt())
       newInts := intSeq()
       fmt.Println(newInts())
    }

function intSeq returns another function, which we define anonymously in the body of intSeq. The returned function closes over the variable i to form a closure.

Output
$ go run closures.go
1
2
3
1
dinesh kandpal
  • 723
  • 7
  • 15
8

The golang does not seem to make lambda expressions, but you can use a literal anonymous function, I wrote some examples when I was studying comparing the equivalent in JS, I hope it helps !!

no args return string:

func() string {
    return "some String Value"
}
//Js similar: () => 'some String Value'

with string args and return string

func(arg string) string {
    return "some String" + arg
}
//Js similar: (arg) => "some String Value" + arg

no arguments and no returns (void)

func() {
   fmt.Println("Some String Value")
} 
//Js similar: () => {console.log("Some String Value")}

with Arguments and no returns (void)

func(arg string) {
    fmt.Println("Some String " + arg)
}
//Js: (arg) => {console.log("Some String Value" + arg)}
Sagiruddin Mondal
  • 4,769
  • 2
  • 28
  • 44
Notim_
  • 89
  • 1
  • 1
1

An example that hasn't been provided yet that I was looking for is to assign values directly to variable/s from an anonymous function e.g.

test1, test2 := func() (string, string) {
    x := []string{"hello", "world"}
    return x[0], x[1]
}()

Note: you require brackets () at the end of the function to execute it and return the values otherwise only the function is returned and produces an assignment mismatch: 2 variable but 1 values error.

James Burke
  • 2,039
  • 1
  • 22
  • 31
1

Here is a 'curried function' example. However the syntax seems unclear, relative to the lambda function syntax in other languages such as Swift, C#, etc.

func main() int { 
  var f func(string) func(string) int
  f = func(_x1 string) func(string) int { return func(_x2 string) int { return strings.Compare(_x1,_x2) } }
  return ((f)("b"))("a")
}
Kevin Lano
  • 41
  • 2
-3

Yes, since it is a fully functional language, but has no fat arrow (=>) or thin arrow (->) as the usual lambda sign, and uses the func keyword for the sake of clarity and simplicity.

LEMUEL ADANE
  • 7,472
  • 15
  • 55
  • 69