View mode: basic / threaded / horizontal-split · Log in · Help
September 23, 2012
Re: Testing for template argument being result of takeExactly
On Sunday, September 23, 2012 14:47:27 Timon Gehr wrote:
> template Hello(R) if(is(typeof(R._input.takeExactly(2)) == R)){
>      alias R Hello;
> }

Thanks. That does the trick quite cleanly, though you'd think that it would be 
possible to test whether a template argument is the result of takeExactly 
without caring or knowing about the guts of takeExactly. So, this isn't a 
general purpose solution at all, when I think that there should be one. Still, 
I don't need a general purpose one for what I'm doing, so this should work 
just fine.

- Jonathan M Davis
September 24, 2012
Re: Testing for template argument being result of takeExactly
On Sunday, 23 September 2012 at 21:52:23 UTC, Timon Gehr wrote:
> On 09/23/2012 10:57 PM, Ali Çehreli wrote:
>> ...
>>
>> Also, I think your code should have passed a range like R.init 
>> to
>> takeExactly, not R, which is a type:
>>
>>   takeExactly(R.init, 1)
>>
>> I don't know why your code compiles.
>>
>
> See discussion here:
> http://d.puremagic.com/issues/show_bug.cgi?id=8220

Interesting. Thanks.

On Sunday, 23 September 2012 at 21:53:20 UTC, Jonathan M Davis 
wrote:
> On Sunday, September 23, 2012 14:47:27 Timon Gehr wrote:
>> template Hello(R) if(is(typeof(R._input.takeExactly(2)) == R)){
>>      alias R Hello;
>> }
>
> Thanks. That does the trick quite cleanly, though you'd think 
> that it would be
> possible to test whether a template argument is the result of 
> takeExactly
> without caring or knowing about the guts of takeExactly. So, 
> this isn't a
> general purpose solution at all, when I think that there should 
> be one. Still,
> I don't need a general purpose one for what I'm doing, so this 
> should work
> just fine.
>
> - Jonathan M Davis

What is wrong with my proposed solution?

----
import std.range;

template Hello(R)
    if ( is(typeof(takeExactly(R.init, 1))) &&
         is(R == typeof(takeExactly(R.init, 1)))
    )
{
    alias R Hello;
}

struct R
{
    enum empty = false;
    @property int front();
    void popFront();
}

struct S{}

void main( ) {
     Hello!(int[]) a; //OK
     Hello!R b;       //Fails second Check: R == typeof(...)
     Hello!S c;       //Fails first check: 
is(typeof(takeExactly(...)))
}
----

Forgive me again if there is something wrong with it, but this 
time, I think it is correct...?
September 24, 2012
Re: Testing for template argument being result of takeExactly
On Monday, 24 September 2012 at 06:20:57 UTC, monarch_dodra wrote:
> What is wrong with my proposed solution?

I think I forgot this test, when R is already a type returned by 
takeExactly:

void main( ) {
     alias typeof(takeExactly(R.init, 5)) G;
     Hello!G g;
}

Which also works.
September 24, 2012
Re: Testing for template argument being result of takeExactly
On Monday, 24 September 2012 at 06:29:25 UTC, monarch_dodra wrote:
> On Monday, 24 September 2012 at 06:20:57 UTC, monarch_dodra 
> wrote:
>> What is wrong with my proposed solution?
>
> I think I forgot this test, when R is already a type returned 
> by takeExactly:
>
> void main( ) {
>      alias typeof(takeExactly(R.init, 5)) G;
>      Hello!G g;
> }
>
> Which also works.

Er, sorry for triple post, no edit button.

This is R:

struct R
{
    enum empty = false;
    @property int front();
    void popFront();
}

I meant when "Hello' R is already the result of a Take exactly", 
sorry for the confusion.
September 24, 2012
Re: Testing for template argument being result of takeExactly
On Monday, September 24, 2012 08:21:46 monarch_dodra wrote:
> template Hello(R)
>      if ( is(typeof(takeExactly(R.init, 1))) &&
>           is(R == typeof(takeExactly(R.init, 1)))
>      )
> {
>      alias R Hello;
> }

> What is wrong with my proposed solution?

It may work, but again, it's relying on how takeExactly works. It's testing 
that you can call takeExactly on R.init and then that R is the same type as 
that result, which means that it's relies on the fact that takeExactly returns 
itself if you call takeExactly on it. It also relies on init, which can be 
risky, given the fact that it can be disabled.

So, between your prosposal and the other that Philippe and Timon gave, theirs 
seems better. But unfortunately, none of the proposals work generically. 
Ideally, there would be a way to generically test that a type is the type 
returned by particular function, and I would _think_ that that's possible, but 
the way that I would expect to work doesn't.

Regardless, thanks for your help.

- Jonathan M Davis
September 24, 2012
Re: Testing for template argument being result of takeExactly
On Monday, 24 September 2012 at 07:07:16 UTC, Jonathan M Davis
wrote:
> On Monday, September 24, 2012 08:21:46 monarch_dodra wrote:
>> template Hello(R)
>>      if ( is(typeof(takeExactly(R.init, 1))) &&
>>           is(R == typeof(takeExactly(R.init, 1)))
>>      )
>> {
>>      alias R Hello;
>> }
>
>> What is wrong with my proposed solution?
>
> It may work, but again, it's relying on how takeExactly works. 
> It's testing
> that you can call takeExactly on R.init and then that R is the 
> same type as
> that result, which means that it's relies on the fact that 
> takeExactly returns
> itself if you call takeExactly on it. It also relies on init, 
> which can be
> risky, given the fact that it can be disabled.
>
> So, between your prosposal and the other that Philippe and 
> Timon gave, theirs
> seems better. But unfortunately, none of the proposals work 
> generically.
> Ideally, there would be a way to generically test that a type 
> is the type
> returned by particular function, and I would _think_ that 
> that's possible, but
> the way that I would expect to work doesn't.
>
> Regardless, thanks for your help.
>
> - Jonathan M Davis

Good points.

Regarding the ".init" issue, I hadn't thought of that, but it can
be worked around pretty easily with an is(R r):

--------
template Hello(R)
     if ( is(R r) &&
          is(typeof(takeExactly(r, 1))) &&
          is(R == typeof(takeExactly(r, 1)))
     )
{
     alias R Hello;
}
--------
After that, I guess it is indeed one implementation detail vs the
other.

IMO, it really depends on whether or not you'd want "int[]" to be
considered the return type of a takeExactly :/ Maybe it is, maybe
it ain't.
September 24, 2012
Re: Testing for template argument being result of takeExactly
On Monday, September 24, 2012 09:41:26 monarch_dodra wrote:
> Regarding the ".init" issue, I hadn't thought of that, but it can
> be worked around pretty easily with an is(R r):
> 
> --------
> template Hello(R)
>       if ( is(R r) &&
>            is(typeof(takeExactly(r, 1))) &&
>            is(R == typeof(takeExactly(r, 1)))
>       )
> {
>       alias R Hello;
> }
> --------

That was one trick that I was not aware of. I didn't think that one is 
expression could have an effect on a later one in the surrounding expression. 
Cool. Though I would point out that that probably doesn't avoid the init 
problem, because R r uses R.init (unless is expressions treat it differently, 
which they may). The normal way to avoid that is to do

R r = void;

but I don't think that that would work in that is expression. Sometimes 
disabling init is useful, but it can definitely be problematic. It may 
ultimately have been a mistake to allow it. I don't know.

- Jonathan M Davis
September 24, 2012
Re: Testing for template argument being result of takeExactly
On Monday, 24 September 2012 at 07:51:23 UTC, Jonathan M Davis 
wrote:
> On Monday, September 24, 2012 09:41:26 monarch_dodra wrote:
>> Regarding the ".init" issue, I hadn't thought of that, but it 
>> can
>> be worked around pretty easily with an is(R r):
>> 
>> --------
>> template Hello(R)
>>       if ( is(R r) &&
>>            is(typeof(takeExactly(r, 1))) &&
>>            is(R == typeof(takeExactly(r, 1)))
>>       )
>> {
>>       alias R Hello;
>> }
>> --------
>
> That was one trick that I was not aware of. I didn't think that 
> one is
> expression could have an effect on a later one in the 
> surrounding expression.
> Cool. Though I would point out that that probably doesn't avoid 
> the init
> problem, because R r uses R.init (unless is expressions treat 
> it differently,
> which they may). The normal way to avoid that is to do
>
> R r = void;
>
> but I don't think that that would work in that is expression. 
> Sometimes
> disabling init is useful, but it can definitely be problematic. 
> It may
> ultimately have been a mistake to allow it. I don't know.
>
> - Jonathan M Davis

Well, it does work...

struct S
{
    @disable this();
}

void foo(T)(T i)
    if ( is(T t))
{}

void main()
{
    //S s; //Fail
    S s = void;
    foo(s); //Works
}

I think it makes sense that it works, because "is" doesn't 
actually validate a compile time syntax, rather it is just 
declaring that "t can be used as an instance of T", but it is not 
actually declaring *the variable* "t" itself... Not sure I'm 
explaining myself.

Or I think that's how it works. I've been on a wrong streak 
lately :/
September 24, 2012
Re: Testing for template argument being result of takeExactly
On Monday, September 24, 2012 10:02:54 monarch_dodra wrote:
> Well, it does work...
> 
> struct S
> {
>      @disable this();
> }
> 
> void foo(T)(T i)
>      if ( is(T t))
> {}
> 
> void main()
> {
>      //S s; //Fail
>      S s = void;
>      foo(s); //Works
> }
> 
> I think it makes sense that it works, because "is" doesn't
> actually validate a compile time syntax, rather it is just
> declaring that "t can be used as an instance of T", but it is not
> actually declaring *the variable* "t" itself... Not sure I'm
> explaining myself.
> 
> Or I think that's how it works. I've been on a wrong streak
> lately :/

@disable this; is pretty broken, so I wouldn't really trust it at this point.

http://d.puremagic.com/issues/show_bug.cgi?id=7021

But it wouldn't surprise if is expressions are supposed to act differently. is 
expressions are arguably too fancy for their own good (well, our good anyway).

- Jonathan M Davis
September 24, 2012
Re: Testing for template argument being result of takeExactly
On 09/24/2012 09:41 AM, monarch_dodra wrote:
> ...
>
> Regarding the ".init" issue, I hadn't thought of that, but it can
> be worked around pretty easily with an is(R r):
>
> --------
> template Hello(R)
>       if ( is(R r) &&
>            is(typeof(takeExactly(r, 1))) &&
>            is(R == typeof(takeExactly(r, 1)))
>       )
> {
>       alias R Hello;
> }
> --------
> After that, I guess it is indeed one implementation detail vs the
> other.
>

I don't think this does what you think it does. The 'is(R r)' declares r 
to be an alias for R. So 'r' is a type in that code snippet.

Also, is(typeof(takeExactly(R, 1))) && is(R == typeof(takeExactly(R, 1)))

can be written in a more compact way as

is(typeof(takeExactly(R, 1)) == R)


> IMO, it really depends on whether or not you'd want "int[]" to be
> considered the return type of a takeExactly :/ Maybe it is, maybe
> it ain't.
1 2 3
Top | Discussion index | About this forum | D home