digitalmars.D.learn - Using a tuple as a function parameter
- Andrew (18/19) Nov 22 I'm getting started using D for some small personal projects and
- monkyyy (9/29) Nov 22 Thats being successfully passed, what the compiler hates is that
- user1234 (15/35) Nov 22 tuples elements must be retrieved with indexes that are known at
- Inkrementator (23/27) Nov 22 Tuple access seems to be internally coded as a template (with
- monkyyy (3/6) Nov 22 Its been a while since Ive tolerated std.tuple, is there any
- Andy Valencia (15/25) Nov 22 I'm guessing you have some Python in your background, where
- Paul Backus (15/27) Nov 22 You can do this with a `switch` statement:
- IchorDev (14/34) Nov 23 Why not this?
I'm getting started using D for some small personal projects and one thing I wanted to do was use a helper function for a tuple. I declared the function like this: string getOrZeroth(Tuple!(string, string, string) tup, int i) pure { return tup[i] == "" ? tup[0] : tup[i]; } and would like to use it like this: auto foo = tuple("a", "", "c"); writeln(foo.getOrZeroth(1)); // prints a but when I try it, I'm getting the below error:Error: variable \`i\` cannot be read at compile timeIt would probably make more sense to create a class and make that a member function, but at this point I'm mostly just curious about how to use a tuple as a function parameter. I tried using a couple different options like `tuple` and `TypeTuple` as well as trying to convert the function into a template, but didn't have any better luck with those. I feel like I'm probably missing something silly, and any help would be appreciated.
Nov 22
On Friday, 22 November 2024 at 16:36:43 UTC, Andrew wrote:I'm getting started using D for some small personal projects and one thing I wanted to do was use a helper function for a tuple. I declared the function like this: string getOrZeroth(Tuple!(string, string, string) tup, int i) pure { return tup[i] == "" ? tup[0] : tup[i]; } and would like to use it like this: auto foo = tuple("a", "", "c"); writeln(foo.getOrZeroth(1)); // prints a but when I try it, I'm getting the below error:Thats being successfully passed, what the compiler hates is that tuples could be mixed types `auto foo(tuple!(int,bool,float) t,int i)=>t[i];` should and does fail You happen to be passing in all strings but thats not what the api is for, you could probaly make it compile with an ugly cast, verbose switch, but if you know its all the same type you should use an array(`foo(T,N)(T[N] arr...)` btw)Error: variable \`i\` cannot be read at compile timeIt would probably make more sense to create a class and make that a member function, but at this point I'm mostly just curious about how to use a tuple as a function parameter. I tried using a couple different options like `tuple` and `TypeTuple` as well as trying to convert the function into a template, but didn't have any better luck with those. I feel like I'm probably missing something silly, and any help would be appreciated.
Nov 22
On Friday, 22 November 2024 at 16:36:43 UTC, Andrew wrote:I'm getting started using D for some small personal projects and one thing I wanted to do was use a helper function for a tuple. I declared the function like this: string getOrZeroth(Tuple!(string, string, string) tup, int i) pure { return tup[i] == "" ? tup[0] : tup[i]; } and would like to use it like this: auto foo = tuple("a", "", "c"); writeln(foo.getOrZeroth(1)); // prints a but when I try it, I'm getting the below error:tuples elements must be retrieved with indexes that are known at compile time (integer literals or enum members). You pass one but this becomes a value that's not known inside the body so you can use a template value parameter instead: ``` string getOrZeroth(int i)(Tuple!(string, string, string) tup) { return tup[i] == "" ? tup[0] : tup[i]; } ``` and use it like that: ``` writeln(foo.getOrZeroth!(1)); // prints a ```Error: variable \`i\` cannot be read at compile timeIt would probably make more sense to create a class and make that a member function, but at this point I'm mostly just curious about how to use a tuple as a function parameter. I tried using a couple different options like `tuple` and `TypeTuple` as well as trying to convert the function into a template, but didn't have any better luck with those. I feel like I'm probably missing something silly, and any help would be appreciated.
Nov 22
On Friday, 22 November 2024 at 16:36:43 UTC, Andrew wrote:Tuple access seems to be internally coded as a template (with unusual syntax) for the reasons already said. `i` has to be known at compile time for this to work, so a template parameter. ``` string getOrZerothT(Tuple!(string, string, string) tup, int i)() pure { //AliasSeq!(a,b,c) = tup.expand; return tup[i] == "" ? tup[0] : tup[i]; } string getOrZerothT2(int i)(Tuple!(string, string, string) tup) pure { return tup[i] == "" ? tup[0] : tup[i]; } ```Error: variable \`i\` cannot be read at compile timeyou could probaly make it compile with an ugly cast, verbose switch, but if you know its all the same type you should use an array(`foo(T,N)(T[N] arr...)` btw)Here is something that compiles ``` string getOrZeroth(Tuple!(string, string, string) tup, int i) pure { string[tup.length] s = [tup.expand]; return s[i] == "" ? s[0] : s[i]; } ```
Nov 22
On Friday, 22 November 2024 at 17:24:08 UTC, Inkrementator wrote:Tuple access seems to be internally coded as a template (with unusual syntax)Its been a while since Ive tolerated std.tuple, is there any unusual syntax?
Nov 22
On Friday, 22 November 2024 at 16:36:43 UTC, Andrew wrote:I'm getting started using D for some small personal projects and one thing I wanted to do was use a helper function for a tuple. I declared the function like this: string getOrZeroth(Tuple!(string, string, string) tup, int i) pure { return tup[i] == "" ? tup[0] : tup[i]; } and would like to use it like this: auto foo = tuple("a", "", "c"); writeln(foo.getOrZeroth(1)); // prints aI'm guessing you have some Python in your background, where "tuple" means "read-only list (e.g., array)". Your "tuple" here actually wants to be an immutable array of string, and then life is good. Tuples are a way to have an array of dissimilar types--but then run-time generated values used to index the tuple will add--in the general case--all sorts of imponderables to the compiler's type treatment. You could claim it can do it for the special case of a tuple holding only one type, but why bother? We already have arrays. You might want to study what it takes to walk the fields of a type (Type.tupleof). The foreach is actually unrolled at compile time for each field. From one of my own exercises, a mini-CSV module: https://sources.vsta.org:7100/dlang/file?name=tiny/csv.d&ci=tip
Nov 22
On Friday, 22 November 2024 at 16:36:43 UTC, Andrew wrote:I'm getting started using D for some small personal projects and one thing I wanted to do was use a helper function for a tuple. I declared the function like this: string getOrZeroth(Tuple!(string, string, string) tup, int i) pure { return tup[i] == "" ? tup[0] : tup[i]; } and would like to use it like this: auto foo = tuple("a", "", "c"); writeln(foo.getOrZeroth(1)); // prints a but when I try it, I'm getting the below error:You can do this with a `switch` statement: string getOrZeroth(Tuple!(string, string, string) tup, int i) { switch (i) { static foreach (j; 0 .. tup.length) { case j: return tup[j] == "" ? tup[0] : tup[j]; } default: assert(0, "Tuple index out of bounds"); } }Error: variable \`i\` cannot be read at compile time
Nov 22
On Friday, 22 November 2024 at 16:36:43 UTC, Andrew wrote:I'm getting started using D for some small personal projects and one thing I wanted to do was use a helper function for a tuple. I declared the function like this: string getOrZeroth(Tuple!(string, string, string) tup, int i) pure { return tup[i] == "" ? tup[0] : tup[i]; } and would like to use it like this: auto foo = tuple("a", "", "c"); writeln(foo.getOrZeroth(1)); // prints a but when I try it, I'm getting the below error:Why not this? ```d string getOrZeroth(string[3] tup, int i) pure { return tup[i] == "" ? tup[0] : tup[i]; } auto foo = ["a", "", "c"]; writeln(foo.getOrZeroth(1)); // prints a ``` No need for a class unless you want a reference type. Tuples are basically just ad-hoc structs. If you want to pass around several types of data that are also used as compile-time sequences then Tuples are for you, otherwise just make a struct for anything using multiple data types.Error: variable \`i\` cannot be read at compile timeIt would probably make more sense to create a class and make that a member function, but at this point I'm mostly just curious about how to use a tuple as a function parameter. I tried using a couple different options like `tuple` and `TypeTuple` as well as trying to convert the function into a template, but didn't have any better luck with those. I feel like I'm probably missing something silly, and any help would be appreciated.
Nov 23