Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
March 17, 2007 Rather neat way of doing multiple return values | ||||
---|---|---|---|---|
| ||||
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 |
March 17, 2007 Re: Rather neat way of doing multiple return values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Downs | 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=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
|
March 17, 2007 Re: Rather neat way of doing multiple return values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Davidl | 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 >> |
March 17, 2007 Re: Rather neat way of doing multiple return values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Downs | 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 |
March 17, 2007 Re: Rather neat way of doing multiple return values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | 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 :)
|
March 17, 2007 Re: Rather neat way of doing multiple return values | ||||
---|---|---|---|---|
| ||||
Posted in reply to kris | 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
|
April 05, 2007 Re: Rather neat way of doing multiple return values | ||||
---|---|---|---|---|
| ||||
Posted in reply to kris | 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. :)
|
April 05, 2007 Re: Rather neat way of doing multiple return values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | 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];
|
Copyright © 1999-2021 by the D Language Foundation