www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using a tuple as a function parameter

reply Andrew <arobie1992 yahoo.com> writes:
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 time
It 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
next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
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:

 Error: variable \`i\` cannot be read at compile time
It 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.
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)
Nov 22
prev sibling next sibling parent user1234 <user1234 12.de> writes:
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:

 Error: variable \`i\` cannot be read at compile time
It 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.
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 ```
Nov 22
prev sibling next sibling parent reply Inkrementator <invalid invalid.org> writes:
On Friday, 22 November 2024 at 16:36:43 UTC, Andrew wrote:
 Error: variable \`i\` cannot be read at compile time
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]; } ```
 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)
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
parent monkyyy <crazymonkyyy gmail.com> writes:
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
prev sibling next sibling parent Andy Valencia <dont spam.me> writes:
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
I'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
prev sibling next sibling parent Paul Backus <snarwin gmail.com> writes:
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:

 Error: variable \`i\` cannot be read at compile time
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"); } }
Nov 22
prev sibling parent IchorDev <zxinsworld gmail.com> writes:
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:

 Error: variable \`i\` cannot be read at compile time
It 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.
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.
Nov 23