Thread overview
Rather neat way of doing multiple return values
Mar 17, 2007
Downs
Mar 17, 2007
Davidl
Mar 17, 2007
BCS
Mar 17, 2007
Tom S
Mar 17, 2007
kris
Apr 05, 2007
Jesse Phillips
Apr 05, 2007
nobody
March 17, 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
March 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=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
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
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
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
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
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
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];