Skip to content

Discussion: The standard way of writing generic functions #670

Closed
@Hejsil

Description

@Hejsil

In Zig the compiler prevents you from passing structs (and other potentially big data) to procedures by values. This is good, cause then we avoid large copies. This does however have the side effect that all generic code have to pass &const T around, to ensure that the code is truly generic.

Now, let's say that I have some procedure for lessThan on strings ([]const u8). It would look something like this:

fn lessThan(lhs: []const u8, rhs: []const u8) -> bool { ... }

And I have a slice of strings ([][]const u8). I can't use my lessThan procedure for generic procedures like insertionSort, because it requires procedures of type fn(&const T, &const T) -> bool or fn(&const []const u8, &const []const u8) -> bool for strings specifically. This means, we have to write an ugly wrapper function whenever we wanna use "pass by value" procedures with generic procedures.

This might not be a problem, and we decide that this is indeed how it should be. I do however think this needs to be discussed before deciding on "the standard way" of writing generic procedures.

Let me kick the discussion of with one way of dealing with this. In Zig, we can actually write a user space procedure that can decide whether a type can be passed by value. With this a procedure can also be written to take a type, and return a type that can be passed to a procedure (see types.zig for implementation).

With these procedures insertionSort can now have this signature:

fn insertionSort(comptime T: type, items: []T, lessThan: fn(lhs: Pass(T), rhs: Pass(T))->bool)

And now, insertionSort can take my lessThan procedure without any wrapper.

This solution does complicate the generic code a little, as one would have to call the getValue to use values passed with Pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions