-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Using struct method as function argument causes compiler to fail #4022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Lines 89 to 95 in 0fb3e66
Passing a bound function as a generic parameter should likely be an error. |
There's a lot of other things going on there, so I'm having trouble parsing it. What would it look like in my example? For the situations where the functor state is both pub fn TimesBy(comptime val: f32) type {
return struct {
const x = val;
pub fn func(y: f32) f32 {
return x * y;
}
};
}
test "functor arguments" {
var vals = [_]f32{1, 2, 3, 4, 5};
apply(TimesBy(3).func, vals[0..]);
std.testing.expect(vals[0] == 3);
std.testing.expect(vals[1] == 6);
std.testing.expect(vals[2] == 9);
std.testing.expect(vals[3] == 12);
std.testing.expect(vals[4] == 15);
} edit: this compiles and passes btw |
Once #1717 is done you won't need the |
const std = @import("std");
pub fn apply(func: var, ctx: var, arr: []f32) void {
for (arr) |*el| {
el.* = func(ctx, el.*);
}
}
pub fn double(_: void, x: f32) f32 {
return 2*x;
}
const TimesBy = struct {
x: f32,
pub fn func(self: TimesBy, y: f32) f32 {
return self.x * y;
}
};
test "plain function arguments" {
var vals = [_]f32{1, 2, 3, 4, 5};
apply(double, {}, vals[0..]);
std.testing.expect(vals[0] == 2);
std.testing.expect(vals[1] == 4);
std.testing.expect(vals[2] == 6);
std.testing.expect(vals[3] == 8);
std.testing.expect(vals[4] == 10);
}
test "functor arguments" {
var vals = [_]f32{1, 2, 3, 4, 5};
const functor = TimesBy{ .x = 3 };
apply(TimesBy.func, functor, vals[0..]);
std.testing.expect(vals[0] == 3);
std.testing.expect(vals[1] == 6);
std.testing.expect(vals[2] == 9);
std.testing.expect(vals[3] == 12);
std.testing.expect(vals[4] == 15);
} |
Ah, I wasn't aware of #1717, that's great. As for the context pattern, for the sake of a nicer API I'll probably just implement const std = @import("std");
pub fn apply(functor: var, arr: []f32) void {
switch (@typeInfo(@TypeOf(functor))) {
.Fn => {
for (arr) |*el| {
el.* = functor(el.*);
}
},
else => {
for (arr) |*el| {
el.* = functor.eval(el.*);
}
}
}
}
const TimesBy = struct {
x: f32,
pub fn eval(self: TimesBy, y: f32) f32 {
return self.x * y;
}
};
// This errors the compiler
test "functor arguments" {
var vals = [_]f32{1, 2, 3, 4, 5};
const functor = TimesBy{ .x = 3 };
apply(functor, vals[0..]);
std.testing.expect(vals[0] == 3);
std.testing.expect(vals[1] == 6);
std.testing.expect(vals[2] == 9);
std.testing.expect(vals[3] == 12);
std.testing.expect(vals[4] == 15);
} This works and is not too different from the user's perspective than |
The following simple "apply" function works for a top level declaration but not for a method. Resulting in a compiler error:
The output is:
I'm sure this is an indication I'm doing things in an unintended way, what is the correct way to implement this sort of behaviour in zig currently?
The text was updated successfully, but these errors were encountered: