Skip to content
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

Guided inference of T in generic function #470

Closed
RobinTD opened this issue Sep 12, 2017 · 8 comments
Closed

Guided inference of T in generic function #470

RobinTD opened this issue Sep 12, 2017 · 8 comments
Labels
breaking Implementing this issue could cause existing code to no longer compile or have different behavior. enhancement Solving this issue will likely involve adding new logic or components to the codebase. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@RobinTD
Copy link

RobinTD commented Sep 12, 2017

So generic functions typically look something like this:
fn cmp(comptime T: type, a: T, b: T)

Have you considered doing like Jai and let the following be short for that.
fn cmp(a: $T, b: T)

Here the dollar sign means that the type of this parameter will be picked up by the compiler and assigned to the comptime variable T. It would also work for complex types like []$T.

@andrewrk
Copy link
Member

You can currently do

fn cmp(a: var, b: @typeOf(a)) {
    const T = @typeOf(a);

}

slightly more verbose, but equivalent. I feel like we get a lot of criticism for having sigils, it seems like adding more might be asking for trouble.

@andrewrk andrewrk added this to the 0.2.0 milestone Sep 12, 2017
@andrewrk andrewrk added breaking Implementing this issue could cause existing code to no longer compile or have different behavior. enhancement Solving this issue will likely involve adding new logic or components to the codebase. labels Sep 12, 2017
@RobinTD
Copy link
Author

RobinTD commented Sep 13, 2017

that works! But I guess it doesnt solve the following for example?
fn cmp(a: []$T, b: []T)

@andrewrk
Copy link
Member

I see, so it does pattern matching. That's pretty convenient. here's how to do that in zig:

fn cmp(a: var, b: []@typeOf(a).child)

@tiehuis tiehuis added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Sep 15, 2017
@thejoshwolfe
Copy link
Contributor

fn cmp_pattern(a: []const $T, b: []const T)
fn cmp_var(a: var, b: []const @typeOf(a).child)
fn cmp_explicit(comptime T: type, a: []const T, b: []const T)

There is a semantic difference between all of these three. cmp_pattern will implicitly coerce [N]T to []const T, but cmp_var will not.

cmp_pattern("abc", "abcd");
// cmp_pattern(a: []const u8, b: []const u8)

cmp_var("abc", "abcd");
// cmp_var(a: &const [3]u8, b: []const [3]u8)
// ERROR: cannot coerce [4]u8 to []const [3]u8.

cmp_var("abc"[0..], "abcd");
// cmp_var(a: []const u8, b: []const u8)

cmp_explicit(u8, "abc", "abcd");

I struggled for a while, and couldn't figure out how provide the caller semantics of the proposed cmp_pattern with status quo Zig.

I believe this is actually a missing feature. The current recommended workaround is to explicitly give the type as in cmp_explicit above or the current @import("std").mem.cmp.

@andrewrk
Copy link
Member

I made it so that if you pass a [N]T to a var or var args parameter, it will implicitly cast to []const T because passing [N]T by value is illegal.

@andrewrk
Copy link
Member

d6b0193 #336

@thejoshwolfe
Copy link
Contributor

Ah. So it's either a regression or I did bad science. I'll look into that.

So then here's another difference between cmp_pattern and cmp_var:

const object = LargeStruct.init();
const stuff = []LargeStruct{ object };
cmp_pattern(object, stuff);
// ERROR: cannot convert arg 1 from &const LargeStruct to &const $T

cmp_var(object, stuff);
// cmp_var(a: &const LargeStruct, b: []const LargeStruct)
// no error on invocation. probably get errors from inside the function body.

This parallels the issue that a is really supposed to be a slice of something, and that's not in the function signature of cmp_var. We could get really explicit and add comptime assert(@typeOf(a).kind == TypeKind.Slice); or however you would express that, but that's not realistically going to happen when people write functions like this.

@andrewrk
Copy link
Member

andrewrk commented May 9, 2019

I don't think Zig is going to have this. #1669 is closer to the direction zig is going.

@andrewrk andrewrk closed this as completed May 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Implementing this issue could cause existing code to no longer compile or have different behavior. enhancement Solving this issue will likely involve adding new logic or components to the codebase. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

4 participants