digitalmars.D - Rather neat way of doing multiple return values
- Downs (31/31) Mar 17 2007 Here's a (imnsho) rather neat implementation of multiple return values f...
- Davidl 126.com (6/41) Mar 17 2007 =
- BCS (5/48) Mar 17 2007 It's all structs and pass by value.
- Tom S (38/43) Mar 17 2007 Hehehe nice :) Here's my version:
- kris (3/71) Mar 17 2007 Cool, but it's worth pointing out that this is probably Latin to most
- Chris Nicholson-Sauls (18/90) Mar 17 2007 Not I; in fact, I'm loving it. (Although I liked the PHP'ish use of lis...
- Jesse Phillips (3/76) Apr 04 2007 I agree with you here, I tried to follow how it works but am so unfamili...
- nobody (4/82) Apr 04 2007 Very cool.
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 =(i, =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=ake =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! :DHehehe 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:Cool, but it's worth pointing out that this is probably Latin to most people :)Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :DHehehe 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
kris wrote:Tom S wrote: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-SaulsDowns wrote:Cool, but it's worth pointing out that this is probably Latin to most people :)Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :DHehehe 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
On Sat, 17 Mar 2007 13:00:03 -0700, kris wrote:Tom S wrote: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. :)Downs wrote:Cool, but it's worth pointing out that this is probably Latin to most people :)Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :DHehehe 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
Apr 04 2007
Jesse Phillips Wrote:On Sat, 17 Mar 2007 13:00:03 -0700, kris wrote:Very cool. I hope, some day we can do this, like perl ($one,$two) = (split (/,/,$line))[0,2];Tom S wrote: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. :)Downs wrote:Cool, but it's worth pointing out that this is probably Latin to most people :)Here's a (imnsho) rather neat implementation of multiple return values from functions. (...) Have fun! :DHehehe 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
Apr 04 2007