-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Currently a function parameter is only visible to the @TypeOf
after next parameter's scope starts.
fn example1(x: @TypeOf(x)) void {}
// error: use of undeclared identifier 'x'
fn example2(x: anytype, y: @TypeOf(x)) void {}
// works; when used as `example2(arg, arg)` it is equivalent to example1
I propose to allow to use @TypeOf
after only a name of a parameter is declared. Can it be useful? Yes, that would allow to put type constraints in a function signature instead of a function body. This basically #1669 without the new syntax.
// status quo
fn isWriter(comptime T: type) bool {...}
fn write1(w: anytype, data: []const u8) void {
if (!comptime isWriter(@TypeOf(w))) @compileError("wrong type");
w.write(data);
}
// with this proposal
fn Constraint(comptime T: type, predicate: fn (type) bool) type {
if (!comptime predicate(T)) @compileError("wrong type");
return T;
}
fn write2(w: Constraint(@TypeOf(w), isWriter), data: []const u8) void {
w.write(data);
}
What happens when i provide a type which is different from the type that @TypeOf
returned? Compiler will check if the value of the argument is coerceable to the new type, if it is not then its a compile error.
Optional Part
If this proposal is implemented then these two expression will be equivalent:
fn example1(x: @TypeOf(x)) void {}
fn example2(x: anytype) void {}
This means we could remove keyword 'anytype'. x: @TypeOf(x)
looks a bit verbose to me, see #1669 (comment) for an alternative builtin @Infer()
, in short instead of overloading @TypeOf
create a new builtin that implements proposed functionality x: @Infer()
, x: Constraint(@Infer(), isWriter)
.