# Anonymous functions/lambdas

**URL:** <https://ziggit.dev/t/anonymous-functions-lambdas/1087>\
**Category:** Help\
**Tags:** language\
**Created:** [July 7, 2023, 12:26pm UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087 "2023-07-07T12:26:10Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![krilcebre](https://ziggit.dev/letter_avatar_proxy/v4/letter/k/977dab/32.png) [@krilcebre](https://ziggit.dev/u/krilcebre)\
**Post date:** [July 7, 2023, 12:26pm UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087/1 "2023-07-07T12:26:10Z")

</div>

Is there any way to create anonymous functions and pass them as function arguments, and if not, is something like that planned for some future release?

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [July 7, 2023, 3:26pm UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087/2 "2023-07-07T15:26:20Z")

</div>

Technically, yes you can but it’s not quite like a Java/C++ lambda (where there is a specific syntax for an anonymous function or closure).

Basically, because struct declarations are anonymous, you can declare a struct and return the member function from said struct. So for instance, in the HashMap implementation, here you can see they are creating a generic equality function:

```zig
pub fn getAutoEqlFn(comptime K: type, comptime Context: type) (fn (Context, K, K) bool) {
    return struct {
        fn eql(ctx: Context, a: K, b: K) bool {
            _ = ctx;
            return meta.eql(a, b);
        }
    }.eql;
}

```

Now this example is stateless so you’ll probably want to play around with stateful alternatives.

Basically Zig really, really does not like to allocate things if it isn’t absolutely necessary and a lot of closure implementations will take that liberty on your behalf - Zig won’t. Besides, you’d have to pass an allocator to the closure itself to give it the capability to allocate in the canonical sense. I don’t see closures making it into the language any time soon or even at all.

Furthermore, a lot of lambda-function like behavior can be achieved using meta programming. So for instance, I can create a comptime parameter of anytype “comptime foo: anytype” and then use that to generically dispatch on internals. I do _a lot_ of that here: [ZEIN/src/tensor\_ops.zig at main · andrewCodeDev/ZEIN · GitHub](https://github.com/andrewCodeDev/ZEIN/blob/main/src/tensor_ops.zig)

For instance, I am dispatching on different arithmetic functions generically for AVX instructions:

```zig
arithmeticDispatch(addGeneric, x, y, z); // addition dispatch
arithmeticDispatch(subGeneric, x, y, z); // subtraction dispatch
arithmeticDispatch(mulGeneric, x, y, z); // multiplication dispatch

```

The two approaches can be combined to make lambda-esque functionality but to answer your question, no - there is not a current specified and particularized lambda syntax.

---

<div class="post-metadata">

**Author:** ![dude\_the\_builder](https://ziggit.dev/user_avatar/ziggit.dev/dude_the_builder/32/557_2.png) [@dude\_the\_builder](https://ziggit.dev/u/dude_the_builder)\
**Post date:** [July 7, 2023, 7:30pm UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087/3 "2023-07-07T19:30:49Z")

</div>

I remember seeing somewhere a proposed syntax like `cons foo = fn() void {...` to declare functions and at the same time allow for closures. But I can’t find it now and don’t remember where I saw that. 😵‍💫

---

<div class="post-metadata">

**Author:** ![zraineri](https://ziggit.dev/user_avatar/ziggit.dev/zraineri/32/755_2.png) [@zraineri](https://ziggit.dev/u/zraineri)\
**Post date:** [July 7, 2023, 7:51pm UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087/4 "2023-07-07T19:51:09Z")

</div>

> [@dude\_the\_builder](#):
>
> I remember seeing somewhere a proposed syntax like `cons foo = fn() void {...` to declare functions

Probably here:

> <https://github.com/ziglang/zig/issues/1717>
>
> \# Overview
> 
> This is a proposal based on \[#1048\]\[issue1048\] (thank you to every…one discussing in that thread). I opened this because I believe that conversation contains important ideas but addresses too many features at once.
> 
> \## Goals
> 
> \- Provide syntactic consistency among all statements which bind something to an identifier
> \- Provide syntactic foundation for a few features: functions-in-functions (\[#229\]\[issue229\]), passing anonymous funtions as arguments (\[#1048\]\[issue1048\])
> 
> \## Non-goals
> 
> \- Closures
> 
> \## Motivation
> 
> Almost all statements which assign a type or value to an identifier use the same syntax. Taken from today's grammar (omitting a few decorations like \`align\` for brevity):
> 
> VariableDeclaration = ("var" | "const") Symbol option(":" TypeExpr) "=" Expression
> 
> The only construct which breaks this format is a function definition. It could be argued that a normal function definition consists of:
> 
> 1. an address where the function instructions begin;
> 2. the type information (signature, calling convention) of the function;
> 3. a symbol binding the above to a constant or variable.
> 
> Ideally, number 3 could be decoupled from the other two.
> 
> \## Proposal
> 
> Make the following true:
> 
> 1. A function definition is an expression
> 2. All functions are anonymous
> 3. Binding a function to a name is accomplished with assignment syntax
> 
> \`\`\`zig
> const f = fn(a: i32) bool {
> return (a \< 4);
> };
> \`\`\`
> 
> Roughly speaking, assigning a function to a \`const\` would equate to existing behavior, while assigning to a \`var\` would equate to assigning a function pointer.
> 
> \## Benefits
> 
> \- Consistency. There is alignment with the fact that aggregate types are also anonymous.
> \- Syntactically, this paves the way for passing anonymous functions as arguments to other functions.
> \- I have a suspision that this will make things simpler for the parser, but I'd love to have that confirmed/debunked by someone who actually knows (hint: not me).
> \- Slightly shrinks the grammar surface area:
> 
> \`\`\`diff
> \- TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
> + TopLevelDecl = option("pub") (ExternDecl | GlobalVarDecl | UseDecl)
> \`\`\`
> 
> \# Examples
> 
> The \`main\` function follows the same rule.
> 
> \`\`\`zig
> pub const main = fn() void {
> @import("std").debug.warn("hello\\n");
> };
> \`\`\`
> 
> The \`extern\` qualifier still goes before \`fn\` because it qualifies the function definition, but \`pub\` still goes before the identifier because it qualifies the visibility of the top level declaration.
> 
> \`\`\`zig
> const puts = extern fn(\[\*\]const u8) void;
> 
> pub const main = fn() void {
> puts(c"I'm a grapefruit");
> };
> \`\`\`
> 
> Functions as the resulting expressions of branching constructs. As with other instances of peer type resolution, each result expression would need to implicitly castable to the same type.
> 
> \`\`\`zig
> var f = if (condition) fn(x: i32) bool {
> return (x \< 4);
> } else fn(x: i32) bool {
> return (x == 54);
> };
> 
> // Type of \`g\` resolves to \`?fn() !void\`
> var g = switch (condition) {
> 12...24 =\> fn() !void {},
> 54 =\> fn() !void { return error.Unlucky; },
> else =\> null,
> };
> \`\`\`
> 
> Defining methods of a struct. Now there is more visual consistency in a struct definition: comma-separated lines show the struct members, while semicolon-terminated statements define the types, values, and methods "namespaced" to the struct.
> 
> \`\`\`zig
> pub const Allocator = struct.{
> allocFn: fn(self: \*Allocator, byte\_count: usize, alignment: u29) Error!\[\]u8,
> reallocFn: fn(self: \*Allocator, old\_mem: \[\]u8, new\_byte\_count: usize, alignment: u29) Error!\[\]u8,
> freeFn: fn(self: \*Allocator, old\_mem: \[\]u8) void,
>     
> pub const Error = error.{OutOfMemory};
> 
> pub const alloc = fn(self: \*Allocator, comptime T: type, n: usize) !\[\]T {
> return self.alignedAlloc(T, @alignOf(T), n);
> };
> 
> // ...
> };
> \`\`\`
> 
> \---
> 
> \_Advanced mode, and possibly out of scope.\_
> 
> Calling an anonymous function directly.
> 
> \`\`\`zig
> defer fn() void {
> std.debug.warn(
> \\\\Keep it down, I'm disguised as Go.
> \\\\I wonder if anonymous functions would provide
> \\\\benefits to asynchronous programming?
> );
> }();
> \`\`\`
> 
> Passing an anonymous function as an argument.
> 
> \`\`\`zig
> const SortFn = fn(a: var, b: var) bool; // Name the type for legibility
> 
> pub const sort = fn(comptime T: type, arr: \[\]T, f: SortFn) {
> // ...
> };
> 
> pub const main = fn() void {
> var letters = \[\]u8.{'g', 'e', 'r', 'm', 'a', 'n', 'i', 'u', 'm'};
> 
> sort(u8, letters, fn(a: u8, b: u8) bool {
> return a \< b;
> });
> };
> \`\`\`
> 
> What it would look like to define a function in a function.
> 
> \`\`\`zig
> pub const main = fn() void {
> const incr = fn(x: i32) i32 {
> return x + 1;
> };
> 
> warn("woah {}\\n", incr(4));
> };
> \`\`\`
> 
> \# Questions
> 
> \## Extern?
> 
> The use of \`extern\` above doesn't seem \_quite\_ right, because the \`FnProto\` evaluates to a type:
> 
> \`\`\`zig
> extern puts = fn(\[\*\]const u8) void;
> --------------------
> this is a type
> \`\`\`
> 
> Maybe it's ok in the context of \`extern\` declaration, though. Or maybe it should look like something else instead:
> 
> \`\`\`zig
> extern puts: fn(\[\*\]const u8) void = undefined;
> \`\`\`
> 
> \## Where does the anonymous function's code get put?
> 
> I think this is more or less the same issue being discussed in \[#229\]\[issue229\].
> 
> \# Counterarguments
> 
> \- Instructions and data are fundamentally separated as far as both the programmer and the CPU are concerned. Because of this conceptual separation, a unique syntax for function body declaration is justifiable.
> \- Status quo is perfectly usable and looks familiar to those who use C.
> 
> \[issue229\]: https://github.com/ziglang/zig/issues/229
> \[issue1048\]: https://github.com/ziglang/zig/issues/1048

---

<div class="post-metadata">

**Author:** ![kristoff](https://ziggit.dev/user_avatar/ziggit.dev/kristoff/32/9_2.png) [@kristoff](https://ziggit.dev/u/kristoff)\
**Post date:** [July 7, 2023, 11:19pm UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087/5 "2023-07-07T23:19:27Z")

</div>

syntax yes, closures probably not, it’s a footgunny feature in a programming language like zig

---

<div class="post-metadata">

**Author:** ![krilcebre](https://ziggit.dev/letter_avatar_proxy/v4/letter/k/977dab/32.png) [@krilcebre](https://ziggit.dev/u/krilcebre)\
**Post date:** [July 8, 2023, 8:22am UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087/6 "2023-07-08T08:22:06Z")

</div>

Awesome. While the syntax with anonymous functions using structs is a bit cumbersome, it still allows me to not have to define every predicate as a separate function and makes the code nice and tidy. A little example for anyone interested:

```zig
const std = @import("std");

pub fn all(comptime T:type, buf: []const T, comptime predicate: (fn (val: T) bool)) bool {
    for (buf) |val| {
        if (!predicate(val))
            return false;
    }

    return true;
}

test "test all" {
    const arr_1 = [_]i32{1} ** 5;
    try std.testing.expect(
        all(i32, arr_1[0..], struct {
            pub fn eql(val: i32) bool { return val == 1; }
        }.eql)
    );
}

```

I haven’t used anytype here because showing an explicit type when reading the function signature just makes it a little more undestandable for me.

---

<div class="post-metadata">

**Author:** ![dude\_the\_builder](https://ziggit.dev/user_avatar/ziggit.dev/dude_the_builder/32/557_2.png) [@dude\_the\_builder](https://ziggit.dev/u/dude_the_builder)\
**Post date:** [July 8, 2023, 11:13am UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087/7 "2023-07-08T11:13:09Z")

</div>

I like to use the `for` as an expression when dealing with predicates, but it’s just a matter of code style preference:

```zig
return for (buf) |val| {
    if (!predicate(val)) break false;
} else true;

```

---

<div class="post-metadata">

**Author:** ![krilcebre](https://ziggit.dev/letter_avatar_proxy/v4/letter/k/977dab/32.png) [@krilcebre](https://ziggit.dev/u/krilcebre)\
**Post date:** [July 8, 2023, 12:33pm UTC](https://ziggit.dev/t/anonymous-functions-lambdas/1087/8 "2023-07-08T12:33:21Z")

</div>

Ah okay, I’m still getting used to what Zig has to offer, didn’t occur to me to use a for expression, even tho I prefer expressions to statements myself. 😀 Thanks!
