September 06, 2010
Yeah, that could work:

template isInputRange(R)
{
   enum bool isInputRange = __traits(compiles,
   {
       R r;             // can define a range object
       if (r.empty) {}  // can test for empty
       r.popFront;          // can invoke next
       auto h = r.front; // can get the front of the range
   });
}

It does look nice. It would look even nicer if __traits gets renamed to meta.

Stanislav Blinov Wrote:

> What about __traits(compiles) ?

September 06, 2010
I'd love to see this used more in Phobos. I don't know if there are any drawbacks, but this looks and works nicely:

import std.stdio : writeln;

void main()
{
    writeln(isInputRange!(N));
}

class N
{
    N test;

    bool empty()
    {
        return false;
    }

    @property
    void popFront()
    {
    }

    @property
    N front()
    {
        return test;
    }
}


template isInputRange(R)
{
    enum bool isInputRange = __traits(compiles,
    {
        R r;             // can define a range object
        if (r.empty) {}  // can test for empty
        r.popFront;          // can invoke next
        auto h = r.front; // can get the front of the range
    });
}

If you uncomment some of those methods in class N, then you get back false, which is what you want. Currently isInputRange is defined like so in Phobos:

template isInputRange(R)
{
    enum bool isInputRange = is(typeof(
    {
        R r;             // can define a range object
        if (r.empty) {}  // can test for empty
        r.popFront;          // can invoke next
        auto h = r.front; // can get the front of the range
    }()));
}

It's getting close to LISP! :)

Andrej Mitrovic Wrote:

> Yeah, that could work:
> 
> template isInputRange(R)
> {
>    enum bool isInputRange = __traits(compiles,
>    {
>        R r;             // can define a range object
>        if (r.empty) {}  // can test for empty
>        r.popFront;          // can invoke next
>        auto h = r.front; // can get the front of the range
>    });
> }
> 
> It does look nice. It would look even nicer if __traits gets renamed to meta.
> 
> Stanislav Blinov Wrote:
> 
> > What about __traits(compiles) ?
> 

September 06, 2010
On 09/06/2010 08:53 PM, Philippe Sigaud wrote:
> On Mon, Sep 6, 2010 at 18:47, Pelle <pelle.mansson@gmail.com
> <mailto:pelle.mansson@gmail.com>> wrote:
>
>     On 09/04/2010 02:11 PM, Simen kjaeraas wrote:
>
>             Is there a way you could write an isStatic(expr) template? Using
>
>
>         template isStatic( alias T ) {
>         enum isStatic = is( char[1+T] );
>         }
>
>         unittest {
>         int n = 3;
>         assert( !isStatic!n );
>         assert( isStatic!1 );
>         enum r = 5;
>         assert( isStatic!r );
>         }
>
>
>     enum s = "Hello";
>
>     assert (isStatic!s);
>
>     Gonna need more work than that.
>
>
> Why? That's exactly the behavior we want, or so it seems to me.
>
>

Sorry if I was unclear, that assert fails. Due to that you cannot add an integer and a string, not not that the string isn't static. It's an enum, so it definitely is static.
September 06, 2010
Is this legal?:

enum a = "test";
a = "test2";

Because it seems to compile. But that shouldn't work afaik..?

I can't reassign other enum types:

enum b = 4;
b = 5;  // error

which is expected.

Pelle Wrote:

> On 09/06/2010 08:53 PM, Philippe Sigaud wrote:
> > On Mon, Sep 6, 2010 at 18:47, Pelle <pelle.mansson@gmail.com <mailto:pelle.mansson@gmail.com>> wrote:
> >
> >     On 09/04/2010 02:11 PM, Simen kjaeraas wrote:
> >
> >             Is there a way you could write an isStatic(expr) template? Using
> >
> >
> >         template isStatic( alias T ) {
> >         enum isStatic = is( char[1+T] );
> >         }
> >
> >         unittest {
> >         int n = 3;
> >         assert( !isStatic!n );
> >         assert( isStatic!1 );
> >         enum r = 5;
> >         assert( isStatic!r );
> >         }
> >
> >
> >     enum s = "Hello";
> >
> >     assert (isStatic!s);
> >
> >     Gonna need more work than that.
> >
> >
> > Why? That's exactly the behavior we want, or so it seems to me.
> >
> >
> 
> Sorry if I was unclear, that assert fails. Due to that you cannot add an integer and a string, not not that the string isn't static. It's an enum, so it definitely is static.

September 06, 2010
Andrej Mitrovic wrote:
> I'd love to see this used more in Phobos. I don't know if there are any drawbacks, but this looks and works nicely:
> 
> import std.stdio : writeln;
> 
> void main()
> {
>     writeln(isInputRange!(N));
> }
> 
> class N
> {
>     N test;
>         bool empty()
>     {
>         return false;
>     }
>         @property
>     void popFront()
>     {
>     }
>         @property
>     N front()
>     {
>         return test;
>     }
> }
> 
> 
> template isInputRange(R)
> {
>     enum bool isInputRange = __traits(compiles,
>     {
>         R r;             // can define a range object
>         if (r.empty) {}  // can test for empty
>         r.popFront;          // can invoke next
>         auto h = r.front; // can get the front of the range
>     });
> }
> 
> If you uncomment some of those methods in class N, then you get back false, which is what you want. Currently isInputRange is defined like so in Phobos:
> 
> template isInputRange(R)
> {
>     enum bool isInputRange = is(typeof(
>     {
>         R r;             // can define a range object
>         if (r.empty) {}  // can test for empty
>         r.popFront;          // can invoke next
>         auto h = r.front; // can get the front of the range
>     }()));
> }
> 
> It's getting close to LISP! :)
> 

If I remember correctly, it has been discussed not long ago that those is(typeof(...))s should really be __traits(compiles). Maybe it's just some code was written before those lovely __traits were introduced?..
September 06, 2010
Andrej Mitrovic wrote:

> It does look nice. It would look even nicer if __traits gets renamed to meta.

By the way, there's no stopping writing

template isValidCode(alias code) { enum bool isValidCode = __traits(compiles, code); }

:)
September 06, 2010
is(typeof( is used a lot in Phobos. There's some ~260 calls like that, a quick search revealed. :p

Stanislav Blinov Wrote:

> If I remember correctly, it has been discussed not long ago that those is(typeof(...))s should really be __traits(compiles). Maybe it's just some code was written before those lovely __traits were introduced?..

September 06, 2010
That still won't work. Observe:

import std.stdio : writeln;

void main()
{
   writeln(isInputRange!(N));
}

class N
{
    N test;

    //~ bool empty()     // oops, we"re not an input range anymore
    //~ {
    //~     return false;
    //~ }

    @property
    void popFront()
    {
    }

    @property
    N front()
    {
        return test;
    }
}


template isInputRange(R)
{
    enum bool isInputRange = isValidCode!(
    {
        R r;                // can define a range object
        if (r.empty) {}     // can test for empty
        r.popFront;         // can invoke next
        auto h = r.front;   // can get the front of the range
    });
}

template isValidCode(alias code) { enum bool isValidCode = __traits(compiles, code); }

Instead of returning false, it will give out a compiler error.

Stanislav Blinov Wrote:

> 
> Andrej Mitrovic wrote:
> 
> > It does look nice. It would look even nicer if __traits gets renamed to meta.
> 
> By the way, there's no stopping writing
> 
> template isValidCode(alias code) { enum bool isValidCode = __traits(compiles, code); }
> 
> :)

September 06, 2010
Andrej Mitrovic wrote:
> is(typeof( is used a lot in Phobos. There's some ~260 calls like that, a quick search revealed. :p

Hush! You're spoiling it! It's a part of intergalactic obfuscation plot ;p
September 06, 2010
Andrej Mitrovic wrote:
> That still won't work. Observe:
> 


Oops, sorry, I was too quick to conclude.