digitalmars.D - Rather neat way of doing multiple return values
- Downs <default_357-line yahoo.de> Mar 17 2007
- Davidl 126.com Mar 17 2007
- BCS <ao pathlink.com> Mar 17 2007
- Tom S <h3r3tic remove.mat.uni.torun.pl> Mar 17 2007
- kris <foo bar.com> Mar 17 2007
- Chris Nicholson-Sauls <ibisbasenji gmail.com> Mar 17 2007
- nobody <nobody nix.de> Apr 04 2007
- Jesse Phillips <Jesse.K.Phillips+Digitalmars gmail.com> Apr 04 2007
Here's a (imnsho) rather neat implementation of multiple return values from
functions.
import std.stdio;
template tuple(T...) { alias T tuple; } // basics
template ptr(T...) { // the typetuple ptr!(T) consists of pointers to the types
in T
static if (T.length>1) alias tuple!(T[0]*, ptr!(T[1..$])) ptr;
else alias T[0]* ptr;
}
struct multival(T...) { /// Simple holder for multiple values
tuple!(T) v=void;
static multival!(T) opCall(T t) { multival!(T) res=void; foreach (i, e; t)
res.v[i]=e; return res; }
}
struct ptrlist(T...) { /// List of pointers to variables
tuple!(ptr!(T)) v=void;
static ptrlist!(T) opCall(inout T t) {
ptrlist!(T) res=void;
foreach (i, e; t) res.v[i]=&t[i]; // Ignore e because I can't make it
inout anyway.
return res;
}
void opAssign(multival!(T) res) {
foreach (i, e; res.v) *v[i]=e;
}
}
multival!(int, float) test() { return typeof(test())(2, 3.0); }
ptrlist!(T) list(T...)(inout T v) { return ptrlist!(T)(v); }
void main() {
int e=4;
float f=5;
list(e, f)=test;
writefln(e, ", ", f); // 2, 3
}
Have fun! :D
Mar 17 2007
Nice implementation!!! i am thinking about how to get rid of those temp object pointers.Here's a (imnsho) rather neat implementation of multiple return values=
from functions. import std.stdio; template tuple(T...) { alias T tuple; } // basics template ptr(T...) { // the typetuple ptr!(T) consists of pointers to =
the types in T static if (T.length>1) alias tuple!(T[0]*, ptr!(T[1..$])) ptr; else alias T[0]* ptr; } struct multival(T...) { /// Simple holder for multiple values tuple!(T) v=3Dvoid; static multival!(T) opCall(T t) { multival!(T) res=3Dvoid; foreach =
e; t) res.v[i]=3De; return res; } } struct ptrlist(T...) { /// List of pointers to variables tuple!(ptr!(T)) v=3Dvoid; static ptrlist!(T) opCall(inout T t) { ptrlist!(T) res=3Dvoid; foreach (i, e; t) res.v[i]=3D&t[i]; // Ignore e because I can't m=
it inout anyway. return res; } void opAssign(multival!(T) res) { foreach (i, e; res.v) *v[i]=3De; } } multival!(int, float) test() { return typeof(test())(2, 3.0); } ptrlist!(T) list(T...)(inout T v) { return ptrlist!(T)(v); } void main() { int e=3D4; float f=3D5; list(e, f)=3Dtest; writefln(e, ", ", f); // 2, 3 } Have fun! :D
Mar 17 2007
Reply to davidl,Nice implementation!!! i am thinking about how to get rid of those temp object pointers.
It's all structs and pass by value. It's a little more verbose than a solution I played with, but I like the result better in other regards (mine had a left to right assignment thing going).Here's a (imnsho) rather neat implementation of multiple return values from functions. import std.stdio; template tuple(T...) { alias T tuple; } // basics template ptr(T...) { // the typetuple ptr!(T) consists of pointers to the types in T static if (T.length>1) alias tuple!(T[0]*, ptr!(T[1..$])) ptr; else alias T[0]* ptr; } struct multival(T...) { /// Simple holder for multiple values tuple!(T) v=void; static multival!(T) opCall(T t) { multival!(T) res=void; foreach (i, e; t) res.v[i]=e; return res; } } struct ptrlist(T...) { /// List of pointers to variables tuple!(ptr!(T)) v=void; static ptrlist!(T) opCall(inout T t) { ptrlist!(T) res=void; foreach (i, e; t) res.v[i]=&t[i]; // Ignore e because I can't make it inout anyway. return res; } void opAssign(multival!(T) res) { foreach (i, e; res.v) *v[i]=e; } } multival!(int, float) test() { return typeof(test())(2, 3.0); } ptrlist!(T) list(T...)(inout T v) { return ptrlist!(T)(v); } void main() { int e=4; float f=5; list(e, f)=test; writefln(e, ", ", f); // 2, 3 } Have fun! :D
Mar 17 2007
Downs wrote:Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :D
Hehehe nice :) Here's my version: --- import std.stdio; import std.bind; struct PtrTuple(P, V) { P ptrs; void opAssign(V v) { foreach (i, x; v.value) { *ptrs.value[i] = x; } } } PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) tup(T ...)(inout T t) { PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) ptrs; foreach (i, dummy_; t) { ptrs.ptrs.value[i] = &t[i]; } return ptrs; } Tuple!(int, float, char) someFunc(int i) { return tuple(i, 0.1f * i, cast(char)i); } void main() { int a; float b; char c; tup(a, b, c) = someFunc(55); writefln("a = %s", a); writefln("b = %s", b); writefln("c = %s", c); } --- Maybe Phobos could use such a utility, as it (apparently) gets reimplemented numerous times ? -- Tomasz Stachowiak
Mar 17 2007
Tom S wrote:Downs wrote:Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :D
Hehehe nice :) Here's my version: --- import std.stdio; import std.bind; struct PtrTuple(P, V) { P ptrs; void opAssign(V v) { foreach (i, x; v.value) { *ptrs.value[i] = x; } } } PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) tup(T ...)(inout T t) { PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) ptrs; foreach (i, dummy_; t) { ptrs.ptrs.value[i] = &t[i]; } return ptrs; } Tuple!(int, float, char) someFunc(int i) { return tuple(i, 0.1f * i, cast(char)i); } void main() { int a; float b; char c; tup(a, b, c) = someFunc(55); writefln("a = %s", a); writefln("b = %s", b); writefln("c = %s", c); } --- Maybe Phobos could use such a utility, as it (apparently) gets reimplemented numerous times ? -- Tomasz Stachowiak
Cool, but it's worth pointing out that this is probably Latin to most people :)
Mar 17 2007
kris wrote:Tom S wrote:Downs wrote:Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :D
Hehehe nice :) Here's my version: --- import std.stdio; import std.bind; struct PtrTuple(P, V) { P ptrs; void opAssign(V v) { foreach (i, x; v.value) { *ptrs.value[i] = x; } } } PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) tup(T ...)(inout T t) { PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) ptrs; foreach (i, dummy_; t) { ptrs.ptrs.value[i] = &t[i]; } return ptrs; } Tuple!(int, float, char) someFunc(int i) { return tuple(i, 0.1f * i, cast(char)i); } void main() { int a; float b; char c; tup(a, b, c) = someFunc(55); writefln("a = %s", a); writefln("b = %s", b); writefln("c = %s", c); } --- Maybe Phobos could use such a utility, as it (apparently) gets reimplemented numerous times ? -- Tomasz Stachowiak
Cool, but it's worth pointing out that this is probably Latin to most people :)
Not I; in fact, I'm loving it. (Although I liked the PHP'ish use of list() for assignment. I'm strange.) Maybe we could evolve this toward a LambdaMOO/ColdC style scatter assignment. Contrived ColdC example: protected method ._cmd_viewCacheInfo { var width, depth, map, row; [width, depth, map] = cache_info(); // <- scatter .tell("Cache Width = ", width); .tell("Cache Depth = ", depth); .tell("Map: (Legend: i/I = Inactive, a/A = Active, I/A = Dity)"); for row in (map) { .tell(" ", row); // <- list spice, also available in scatter } .tell(); } I can dream. And this comes right up against it, just need a way to specify a catch-all at the end for trailing elements. -- Chris Nicholson-Sauls
Mar 17 2007
Jesse Phillips Wrote:On Sat, 17 Mar 2007 13:00:03 -0700, kris wrote:Tom S wrote:Downs wrote:Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :D
Hehehe nice :) Here's my version: --- import std.stdio; import std.bind; struct PtrTuple(P, V) { P ptrs; void opAssign(V v) { foreach (i, x; v.value) { *ptrs.value[i] = x; } } } PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) tup(T ...)(inout T t) { PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) ptrs; foreach (i, dummy_; t) { ptrs.ptrs.value[i] = &t[i]; } return ptrs; } Tuple!(int, float, char) someFunc(int i) { return tuple(i, 0.1f * i, cast(char)i); } void main() { int a; float b; char c; tup(a, b, c) = someFunc(55); writefln("a = %s", a); writefln("b = %s", b); writefln("c = %s", c); } --- Maybe Phobos could use such a utility, as it (apparently) gets reimplemented numerous times ? -- Tomasz Stachowiak
Cool, but it's worth pointing out that this is probably Latin to most people :)
I agree with you here, I tried to follow how it works but am so unfamiliar with the tools used I got lost and surprised by the result. :)
Very cool. I hope, some day we can do this, like perl ($one,$two) = (split (/,/,$line))[0,2];
Apr 04 2007
On Sat, 17 Mar 2007 13:00:03 -0700, kris wrote:Tom S wrote:Downs wrote:Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :D
Hehehe nice :) Here's my version: --- import std.stdio; import std.bind; struct PtrTuple(P, V) { P ptrs; void opAssign(V v) { foreach (i, x; v.value) { *ptrs.value[i] = x; } } } PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) tup(T ...)(inout T t) { PtrTuple!(PointerTuple!(Tuple!(T)), Tuple!(T)) ptrs; foreach (i, dummy_; t) { ptrs.ptrs.value[i] = &t[i]; } return ptrs; } Tuple!(int, float, char) someFunc(int i) { return tuple(i, 0.1f * i, cast(char)i); } void main() { int a; float b; char c; tup(a, b, c) = someFunc(55); writefln("a = %s", a); writefln("b = %s", b); writefln("c = %s", c); } --- Maybe Phobos could use such a utility, as it (apparently) gets reimplemented numerous times ? -- Tomasz Stachowiak
Cool, but it's worth pointing out that this is probably Latin to most people :)
I agree with you here, I tried to follow how it works but am so unfamiliar with the tools used I got lost and surprised by the result. :)
Apr 04 2007









BCS <ao pathlink.com> 