February 20, 2015
On 2015-02-19 05:38, thedeemon wrote:
> Creating tuples and returning them from functions is trivial in D:
>
> auto getTuple() { return tuple("Bob", 42); }
>
> but using them afterwards can be confusing and error prone
>
> auto t = getTuple();
> writeln("name is ", t[0], " age is ", t[1]);
>
> I really missed the ML syntax to write
>
> let (name, age) = getTuple();

Didn't someone create a pull request for something like:

auto(name, age) = getTuple();

Or was it a DIP?

-- 
/Jacob Carlborg
February 20, 2015
On Friday, 20 February 2015 at 09:12:26 UTC, Jacob Carlborg wrote:
> On 2015-02-19 05:38, thedeemon wrote:
>> Creating tuples and returning them from functions is trivial in D:
>>
>> auto getTuple() { return tuple("Bob", 42); }
>>
>> but using them afterwards can be confusing and error prone
>>
>> auto t = getTuple();
>> writeln("name is ", t[0], " age is ", t[1]);
>>
>> I really missed the ML syntax to write
>>
>> let (name, age) = getTuple();
>
> Didn't someone create a pull request for something like:
>
> auto(name, age) = getTuple();
>
> Or was it a DIP?

This one, by Kenji?

http://wiki.dlang.org/DIP32
February 24, 2015
Nick Treleaven, el 19 de February a las 17:25 me escribiste:
> On 19/02/2015 17:00, Nick Treleaven wrote:
> >>>Alternatively std.typetuple.TypeTuple can be used instead of let
> >>
> >>not for ranges and arrays though
> >
> >Yes, but `tuple` overloads could be added for those.
> 
> Or not - the length isn't known at compile-time.
> 
> >Tuple already
> >supports construction from a static array:
> >
> >     int a, b;
> >     TypeTuple!(a, b) = Tuple!(int, int)([3, 4]);
> 
> I'm hacking std.typecons so this does work:
> 
>     TypeTuple!(a, b) = [4, 5].tuple;

Why not to integrate this "let" to phobos, that seems to be a lot of syntactic noise compared to : let (a, b) = [4, 5];

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
You can try the best you can
If you try the best you can
The best you can is good enough
November 22, 2015
hello,
Learning here, hope i don"t excavate unnecessarily an old post

What is the reason for using pointers (alias pointerOf(T) = T*  etc...)
it works without ! what am i missing ?

Thanks



November 23, 2015
On Friday, 20 February 2015 at 09:12:26 UTC, Jacob Carlborg wrote:
> On 2015-02-19 05:38, thedeemon wrote:
>> Creating tuples and returning them from functions is trivial in D:
>>
>> auto getTuple() { return tuple("Bob", 42); }
>>
>> but using them afterwards can be confusing and error prone
>>
>> auto t = getTuple();
>> writeln("name is ", t[0], " age is ", t[1]);
>>
>> I really missed the ML syntax to write
>>
>> let (name, age) = getTuple();
>
> Didn't someone create a pull request for something like:
>
> auto(name, age) = getTuple();
>
> Or was it a DIP?

Waw! auto(name, age) = getTuple(); looks better :)
November 23, 2015
On Sunday, 22 November 2015 at 18:47:34 UTC, visitor wrote:

> What is the reason for using pointers (alias pointerOf(T) = T*  etc...)
> it works without ! what am i missing ?

What and how exactly works without?
My original solution remembers in the constructor addresses of variables to fill, then does the filling in opAssign operator, so I needed a way to store the references and used pointers for that.
November 23, 2015
On Monday, 23 November 2015 at 10:28:53 UTC, thedeemon wrote:
> On Sunday, 22 November 2015 at 18:47:34 UTC, visitor wrote:
>
>> What is the reason for using pointers (alias pointerOf(T) = T*
>>  etc...)
>> it works without ! what am i missing ?
>
> What and how exactly works without?
> My original solution remembers in the constructor addresses of variables to fill, then does the filling in opAssign operator, so I needed a way to store the references and used pointers for that.

yes, but you are using ref : "auto let(Ts...)(ref Ts vars)"
so vars are changed, no need to store anything, no?
i was wondering if there is some subtleties or efficiency reasons for using pointers

this work fine with your unittest :
auto let(Ts...)(ref Ts vars) {
    struct Let
    {
        void opAssign( Tuple!Ts xs ) {
            foreach(i, t; Ts)
                vars[i] = xs[i];
        }

        static if (sameTypes!Ts) {
            import std.conv : text;
            void opAssign(Ts[0][] xs) { // redundant but more effective
                enforce(xs.length == Ts.length, "let (...) = ...: array must have " ~ Ts.length.text ~ " elements.");
                foreach(i, t; Ts)
                    vars[i] = xs[i];
            }

            void opAssign(R)(R xs) if (isInputRange!R && is(ElementType!R == Ts[0])) {
                static if (hasLength!R) {					
                    enforce(xs.length >= Ts.length, "let (...) = ...: range must have at least " ~ Ts.length.text ~ " elements.");
                }
                foreach(i, t; Ts) {
                    enforce(!xs.empty, "let (...) = ...: range must have at least " ~ Ts.length.text ~ " elements.");
                    vars[i] = xs.front;
                    xs.popFront();
                }
            }

            void opIndexAssign(R)(R xs) if (isInputRange!R && is(ElementType!R == Ts[0])) {
                foreach(i, t; Ts) {
                    if(xs.empty) return;
                    vars[i] = xs.front;
                    xs.popFront();
                }
            }
        }
    }
    return Let();
}
November 23, 2015
On Monday, 23 November 2015 at 11:12:33 UTC, visitor wrote:

>> My original solution remembers in the constructor addresses of variables to fill, then does the filling in opAssign operator, so I needed a way to store the references and used pointers for that.
>
> yes, but you are using ref : "auto let(Ts...)(ref Ts vars)"
> so vars are changed, no need to store anything, no?
> i was wondering if there is some subtleties or efficiency reasons for using pointers

Thanks for the code!
Yep, this way it works too, by capturing input vars in a closure. So the main difference is that your variant allocates GC memory while original variant does not allocate anything in the heap (only on stack).
November 23, 2015
On Monday, 23 November 2015 at 14:54:15 UTC, thedeemon wrote:
> Yep, this way it works too, by capturing input vars in a closure. So the main difference is that your variant allocates GC memory while original variant does not allocate anything in the heap (only on stack).

Thanks for clarifying :-)
hope this will end into the language ! great work.
November 23, 2015
On Monday, 23 November 2015 at 11:12:33 UTC, visitor wrote:
> this work fine with your unittest :
> auto let(Ts...)(ref Ts vars) {
>     struct Let
>     {
>         void opAssign( Tuple!Ts xs ) {
>             foreach(i, t; Ts)
>                 vars[i] = xs[i];
>         }
>
>         static if (sameTypes!Ts) {
>             import std.conv : text;
>             void opAssign(Ts[0][] xs) { // redundant but more effective
>                 enforce(xs.length == Ts.length, "let (...) = ...: array must have " ~ Ts.length.text ~ " elements.");
>                 foreach(i, t; Ts)
>                     vars[i] = xs[i];
>             }
>
>             void opAssign(R)(R xs) if (isInputRange!R && is(ElementType!R == Ts[0])) {
>                 static if (hasLength!R) {					
>                     enforce(xs.length >= Ts.length, "let (...) = ...: range must have at least " ~ Ts.length.text ~ " elements.");
>                 }
>                 foreach(i, t; Ts) {
>                     enforce(!xs.empty, "let (...) = ...: range must have at least " ~ Ts.length.text ~ " elements.");
>                     vars[i] = xs.front;
>                     xs.popFront();
>                 }
>             }
>
>             void opIndexAssign(R)(R xs) if (isInputRange!R && is(ElementType!R == Ts[0])) {
>                 foreach(i, t; Ts) {
>                     if(xs.empty) return;
>                     vars[i] = xs.front;
>                     xs.popFront();
>                 }
>             }
>         }
>     }
>     return Let();
> }

Nice. Why first enforce is "==" rather than ">=" ? This prevents something like:

auto arr = ["hello", "world", "!"];
string hello;
string world;

let (hello, world) = arr;