#Help understanding what I can make inline, literal, or anonymous re structs and functions as params?

1 messages · Page 1 of 1 (latest)

orchid crest
#

I've code some code for sorting working with the Context structs and the lessThan functions declared in full. But I want to gain a better understanding of which, if any, I can use literals or anonymous structs (or functions) instead?

// two context structs
const SortContext1 = struct {};
const SortContext2 = struct {
    hm: *const std.StringHashMap(u32),
};

// a lessThan function for each
fn lessThanFn1(context: SortContext1, lhs: []const u8, rhs: []const u8) bool {
    return std.mem.order(u8, lhs, rhs) == .lt;
}

fn lessThanFn2(context: SortContext2, lhs: []const u8, rhs: []const u8) bool {
    return context.hm.get(lhs).? > context.hm.get(rhs).?;
}

// examples of using each with `sort()`
std.mem.sort([]const u8, keez.items, SortContext1{}, lessThanFn1);

std.mem.sort([]const u8, keez.items, SortContext2{ .hm = stats }, lessThanFn2);

This is to help my understanding and not for best practices, so I want to know if both context structs and both lessThan functions need to be fully declared separately like this, or can I combine one or more of them into other lines as an alternative? (Even if ugly, even if there's some duplication. I just want to grok more fully)

spiral thicket
#

I'm not sure if I understood the question correctly.

For the lessThanFn1 function, you can just use void as a context if you're not using it at all. For example:

//const SortContext1 = struct {}; //SortContext1 commented. Not needed.
fn lessThanFn1(_: void, lhs: []const u8, rhs: []const u8) bool {
    return std.mem.order(u8, lhs, rhs) == .lt;
} //_: void just discards it without naming the variable.
//...
std.mem.sort([]const u8, keez.items, {}, lessThanFn1); //{} or void{}

And you can create an anonymous function (Although I'm not sure if it's called an anonymous function) by just wrapping lessThanFn1 in a struct and getting the function from the struct by its name. For example:

std.mem.sort([]const u8, keez.items, {}, struct{fn f(_: void, lhs: []const u8, rhs: []const u8) bool {
   return std.mem.order(u8, lhs, rhs) == .lt;
}}.f); //'lessThanFn1' renamed as 'f'.

For the SortContext2, I'm not sure if there is a way to make the context an "anonymous struct".

#

For SortContext2, you can also put the lessThanFn2 inside the struct and refer to it as SortContext2.lessThan in the sort function.

const SortContext2 = struct {
    hm: *const std.StringHashMap(u32),
    fn lessThan(context: SortContext2, lhs: []const u8, rhs: []const u8) bool {
        return context.hm.get(lhs).? > context.hm.get(rhs).?;
    }
};
orchid crest
#

where i can pass void can i also pass {} or .{}?

orchid crest
spiral thicket
# orchid crest is there an `.f` or `f:` or something missing in the 'anonymous function' part? ...

You can only pass {} or void{} in the context parameter. Not .{}.

var strs = [_][]const u8{ "c", "b", "a" };
std.mem.sort([]const u8, &strs, {}, struct {
    fn f(_: void, lhs: []const u8, rhs: []const u8) bool {
        return std.mem.order(u8, lhs, rhs) == .lt;
    }
}.f);
std.debug.print("{s}", .{strs});

I just renamed the function as f so it can be referenced as .f in the struct. There's no way to reference it as "nameless" regarding to or something missing in the 'anonymous function' part?