# How to define and use a function as parameter?

**URL:** <https://ziggit.dev/t/how-to-define-and-use-a-function-as-parameter/1346>\
**Category:** Help\
**Created:** [August 2, 2023, 4:32am UTC](https://ziggit.dev/t/how-to-define-and-use-a-function-as-parameter/1346 "2023-08-02T04:32:44Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![aiac](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/db5fbb/32.png) [@aiac](https://ziggit.dev/u/aiac)\
**Post date:** [August 2, 2023, 4:32am UTC](https://ziggit.dev/t/how-to-define-and-use-a-function-as-parameter/1346/1 "2023-08-02T04:32:44Z")

</div>

I want to pass the response body handle in the code below as a parameter, how can I do it ？

```zig
fn http_get(client: *http.Client, uri: Uri, headers: http.Headers, allocator: mem.Allocator, response_body_max_len: usize, comptime T: type) !json.Parsed(T) {
    // init request
    var req = try client.request(.GET, uri, headers, .{});
    defer req.deinit();

    // send request
    try req.start();

    // wait response
    try req.wait();

    // get response
    var res = req.response;
    // TODO: body handle parameterize, e.g. a param: fn(T, allocator, response, io_reader) !T
    return switch (res.status) {
        // handle ok response
        .ok => try readJsonAs(T, allocator, req.reader(), response_body_max_len),
        else => error.HttpStatusNotOk,
    };
}

```

---

<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:** [August 2, 2023, 4:49am UTC](https://ziggit.dev/t/how-to-define-and-use-a-function-as-parameter/1346/2 "2023-08-02T04:49:25Z")

</div>

Hello @aiac! Welcome to the forum.

Please check out this related thread: [Anonymous functions/lambdas - Help - Ziggit](https://ziggit.dev/t/anonymous-functions-lambdas/1087/2)

It has several examples of what I believe you are looking for. If you still have questions, feel free to follow up!

– edit

I wanted to post a few more examples because the relation between these two threads may be a bit cryptic at a first glance. You can easily use the “anytype” parameter type as a way to generically take in functions as compile time arguments. (Please note that you can take in function pointers as well, the example that I am giving here is comptime oriented, but you can deduce the type of function pointers as well).

Here we have a dispatching function that takes in a binary function as a first parameter:

```zig
fn arithmeticDispatch(    
    comptime BinaryFunc: anytype, 
    x: anytype,
    y: anytype,
    z: anytype,
) void { ...

```

Here we have a generic function that can be passed to that parameter:

```zig
inline fn addGeneric(x: anytype, y: anytype) @TypeOf(x) {
    return x + y;
}

```

Finally, here we have the dispatching call being made that binds the two:

```zig
arithmeticDispatch(addGeneric, x, y, z);

```

Another parameter declaration pattern from that same thread was made by @krilcebre (with @dude_the_builder 's edit):

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

// ...

all(i32, arr_1[0..], struct {
    pub fn eql(val: i32) bool { return val == 1; }
}.eql)

```

The take-away from that last example is the (fn (val: T) bool) as the predicate argument in the parent function “all”

---

<div class="post-metadata">

**Author:** ![aiac](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/db5fbb/32.png) [@aiac](https://ziggit.dev/u/aiac)\
**Post date:** [August 2, 2023, 6:23am UTC](https://ziggit.dev/t/how-to-define-and-use-a-function-as-parameter/1346/3 "2023-08-02T06:23:32Z")

</div>

Thank you for your help, I modified my code, then found a new compilation error. Where did I write it wrong?

```zig
error: function prototype may not have inferred error set
    comptime response_body_handle: fn(T:type, allocator: mem.Allocator, response: http.Client.Response, io_reader: anytype) !jso
n.Parsed(T)

```

code:

```zig
fn http_get(
    client: *http.Client,
    uri: Uri,
    headers: http.Headers,
    allocator: mem.Allocator,
    comptime T:type,
    comptime response_body_handle: fn(T:type, allocator: mem.Allocator, response: http.Client.Response, io_reader: anytype) !json.Parsed(T) 
) !json.Parsed(T) {
    // init request
    var req = try client.request(.GET, uri, headers, .{});
    defer req.deinit();

    // send request
    try req.start();

    // wait response
    try req.wait();

    // get response
    var res = req.response;

    return try response_body_handle(T,allocator,res,req.reader());
}

// call 
var parsed = try http_get(&client,uri,headers,allocator, PokemonList(), struct {
    pub fn handle(comptime T:type, _allocator: mem.Allocator, response: http.Client.Response, io_reader: anytype) !json.Parsed(T) {
        return switch (response.status) {
            // handle ok response
            .ok => try readJsonAs(T, _allocator, io_reader, response_body_max_len),
            else => error.HttpStatusNotOk,
        };
    }
}.handle);
defer parsed.deinit();

```

---

<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:** [August 2, 2023, 6:31am UTC](https://ziggit.dev/t/how-to-define-and-use-a-function-as-parameter/1346/4 "2023-08-02T06:31:00Z")

</div>

Yup, so the inferred error is your issue here: [https://ziglang.org/documentation/master/#Inferred-Error-Sets](https://ziglang.org/documentation/master/#Inferred-Error-Sets)

The inferred error is coming from the non-explicitly specified error on the return type - note that you have:

```zig
!json.Parsed(T)

```

The exclamation mark is inferring what the error is. Here’s an example of a non-inferred error (from the documentation):

```zig
const A = error{
    NotDir,

    /// A doc comment
    PathNotFound,
};
const B = error{
    OutOfMemory,

    /// B doc comment
    PathNotFound,
};

const C = A || B;

fn foo() C!void {
    return error.NotDir;
}

```

Note that the function “foo” returns a “C!void” where C is a combination of error types A and B (A || B).

That is non-inferred because it is explicitly stated what the errors it can return are. In this case, you are returning an error.HttpStatusNotOk.

---

<div class="post-metadata">

**Author:** ![aiac](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/db5fbb/32.png) [@aiac](https://ziggit.dev/u/aiac)\
**Post date:** [August 2, 2023, 6:38am UTC](https://ziggit.dev/t/how-to-define-and-use-a-function-as-parameter/1346/5 "2023-08-02T06:38:48Z")

</div>

You are really awesome, I solved the problem very quickly, thank you very much 😊

I temporarily used anyerror! instead of !

But I still don’t understand the difference

---

<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:** [August 2, 2023, 6:41am UTC](https://ziggit.dev/t/how-to-define-and-use-a-function-as-parameter/1346/6 "2023-08-02T06:41:04Z")

</div>

Glad I could help 🙂

The difference really is that you may actually want to restrict the kinds of functions that people pass as a parameter because perhaps it interacts with other components that expect a specific set of error codes for various reasons.

Also, a part of the reasoning behind this is could be that there are no errors to infer from what is purely a declaration so this mechanism can’t really be deduced here. This is speculation on my part, however.
