Thread overview
[phobos] phobos commit, revision 1670
Jun 19, 2010
dsource.org
Jun 19, 2010
Sean Kelly
Jun 19, 2010
Philippe Sigaud
Jun 20, 2010
Masahiro Nakagawa
Jun 20, 2010
Sean Kelly
June 19, 2010
phobos commit, revision 1670


user: sean

msg:
Cleaned up ctor def.  I can still get bizarre compile errors in some cases, but I don't think the remaining ones are ctor-related.

http://www.dsource.org/projects/phobos/changeset/1670

June 19, 2010
Yah, I noticed such errors too. Some come with the wrong file and line number. FWIW, I think the definition should be writable as:

this(U)(U another) if (is(U == Tuple!(V), V...)) { ... }

IOW, we should be able to express all type constraints as an if-constraint.


Andrei

On 06/19/2010 01:53 PM, dsource.org wrote:
> phobos commit, revision 1670
>
>
> user: sean
>
> msg:
> Cleaned up ctor def.  I can still get bizarre compile errors in some cases, but I don't think the remaining ones are ctor-related.
>
> http://www.dsource.org/projects/phobos/changeset/1670
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
June 19, 2010
Is that 'is' syntax correct?  I get a compile error at the comma. I've got to say that tuples are proving to be both incredibly powerful and incredibly frustrating to work with. I'm still trying to sort out a working test to tell these two functions apart:

void fnA(Tuple!int) {}
void fnB(int) {}

Alternately, a way to pass a Tuple!int to either one automatically would be even better.  Or instead, make Variant.convertsTo distinguish between the two.  Right now it doesn't.

Sent from my iPhone

On Jun 19, 2010, at 12:03 PM, Andrei Alexandrescu <andrei at erdani.com> wrote:

> Yah, I noticed such errors too. Some come with the wrong file and line number. FWIW, I think the definition should be writable as:
>
> this(U)(U another) if (is(U == Tuple!(V), V...)) { ... }
>
> IOW, we should be able to express all type constraints as an if- constraint.
>
>
> Andrei
>
> On 06/19/2010 01:53 PM, dsource.org wrote:
>> phobos commit, revision 1670
>>
>>
>> user: sean
>>
>> msg:
>> Cleaned up ctor def.  I can still get bizarre compile errors in
>> some cases, but I don't think the remaining ones are ctor-related.
>>
>> http://www.dsource.org/projects/phobos/changeset/1670
>>
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
June 19, 2010
Andrei:
>> this(U)(U another) if (is(U == Tuple!(V), V...)) { ... }

Sean:

> Is that 'is' syntax correct?


No, halas you can't put a V... inside an is expression. Only is(U ==
Tuple!V, V) is authorized.
To detect a Tuple, I use the following workaround: std.typecons.Tuple has a
.Types member, so test for it (and btw .Types will give you the V tuple):

this(U)(U another) if (is(U.Types)) // U is a Tuple

{
alias U.Types V;
...
}

also, testing for U.stringof beginning with "Tuple!("... But I don't like this.


> I've got to say that tuples are proving to be both incredibly powerful and incredibly frustrating to work with.


Agreed.



> I'm still trying to sort out a working test to tell these two functions apart:
>
> void fnA(Tuple!int) {}
> void fnB(int) {}
>

Like this?



template isTuple(T)
{
    static if (is(T.Types))
        enum bool isTuple = true;
    else
        enum bool isTuple = false;
}

template InternalTypes(T) if (isTuple!T) // Gosh, I need it later, DMD
doesn't like some complex types expressions
{
    alias T.Types InternalTypes;
}

template isTupleFunction(alias fun)
{
    static if (ParameterTypeTuple!fun.length == 1 &&
isTuple!(ParameterTypeTuple!fun[0]))
        enum bool isTupleFunction = true;
    else
        enum bool isTupleFunction = false;
}


But you also need to test for fun to be a standard function.



>
> Alternately, a way to pass a Tuple!int to either one automatically would be even better.  Or instead, make Variant.convertsTo distinguish between the two.  Right now it doesn't.
>

One thing nice to know (sorry if that's common knowledge) is that you can send a Tuple to a standard function by using its .field/.expand member.

int foo(int i, double d, string s) { return i*s.length;}

auto t = tuple(2, 3.14, "abc");

foo(t.expand); // 2*3


To automate the process, you can use a function adaptor:

/**
Transforms a tuple-taking function into a standard function.
*/
template untuplify(alias fun)
{
    static if (isTupleFunction!fun)
        ReturnType!fun untuplify(InternalTypes!(ParameterTypeTuple!fun[0])
args)
        {
            return fun(tuple(args));
        }
    else // consider fun to be a function, that should be tested
        alias fun untuplify;
}

/**
Transforms a standard function into a tuple-accepting one.
*/
template tuplify(alias fun)
{
    static if (isTupleFunction!fun)
        alias fun tuplify;
    else
        ReturnType!fun tuplify(Tuple!(ParameterTypeTuple!fun) args)
        {
            return fun(args.expand);
        }
}


It's too bad I have to use a secondary template like InternalTypes, but

    InternalTypes!(ParameterTypeTuple!fun[0])

is accepted, whereas

    ParameterTypeTuple!fun[0].Types

 is not.



 Philippe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/phobos/attachments/20100619/7183c1fb/attachment.html>
June 20, 2010
On Sun, 20 Jun 2010 06:18:46 +0900, Philippe Sigaud <philippe.sigaud at gmail.com> wrote:

> Andrei:
>>> this(U)(U another) if (is(U == Tuple!(V), V...)) { ... }
>
> Sean:
>
>> Is that 'is' syntax correct?
>
>
> No, halas you can't put a V... inside an is expression. Only is(U ==
> Tuple!V, V) is authorized.
> To detect a Tuple, I use the following workaround: std.typecons.Tuple
> has a
> .Types member, so test for it (and btw .Types will give you the V tuple):
>
> this(U)(U another) if (is(U.Types)) // U is a Tuple
>
> {
> alias U.Types V;
> ...
> }
>
> also, testing for U.stringof beginning with "Tuple!("... But I don't like this.
>

I use following isTuple.

template isTuple(T)
{
     enum isTuple = __traits(compiles, { void f(X...)(Tuple!X t) {};
f(T.init); });
}


Masahiro
June 19, 2010
On Jun 19, 2010, at 8:07 PM, Masahiro Nakagawa wrote:
> 
> I use following isTuple.
> 
> template isTuple(T)
> {
>    enum isTuple = __traits(compiles, { void f(X...)(Tuple!X t) {}; f(T.init); });
> }

Thanks!  I still want to look into why the simple version* doesn't work, but that at least solves my immediate problem.

* template isTuple(T : Tuple!(U), U...) { enum isTuple = true; }

This approach even gives an invalid line number for where the problem lies.  I'll also have to submit a bug report for the compiler.