View mode: basic / threaded / horizontal-split · Log in · Help
April 21, 2012
Recursive aliases?
alias int delegate(out ItemGetter next) ItemGetter;

We currently can't do the above^ in D, but what do people think about 
allowing it?
i.e. More specifically, I think an alias expression should be able to refer 
to the identifier (unless it doesn't make sense, like including a struct 
inside itself).
(It would require a look-ahead.)
April 21, 2012
Re: Recursive aliases?
On Saturday, 21 April 2012 at 19:46:29 UTC, Mehrdad wrote:
> alias int delegate(out ItemGetter next) ItemGetter;
>
> We currently can't do the above^ in D, but what do people think 
> about allowing it?
> i.e. More specifically, I think an alias expression should be 
> able to refer to the identifier (unless it doesn't make sense, 
> like including a struct inside itself).
> (It would require a look-ahead.)

I've needed exactly this thing once.Or should I say: I needed
this exactly once*?



* Though I don't code very much in D.
April 23, 2012
Re: Recursive aliases?
On Sat, 21 Apr 2012 15:46:29 -0400, Mehrdad <wfunction@hotmail.com> wrote:

> alias int delegate(out ItemGetter next) ItemGetter;
>
> We currently can't do the above^ in D, but what do people think about  
> allowing it?
> i.e. More specifically, I think an alias expression should be able to  
> refer to the identifier (unless it doesn't make sense, like including a  
> struct inside itself).
> (It would require a look-ahead.)

It doesn't work.

If I do this:

alias int delegate() dtype;

alias int delegate(dtype d) ddtype;

pragma(msg, ddtype.stringof);

I get:

int delegate(int delegate() d)

Note how it's not:

int delegate(dtype d)

Why?  Because alias does not create a new type.  It's a new symbol that  
*links* to the defined type.

How shall the compiler expand your example so it can know the type?  It  
works for classes because classes are a new type which do not need to have  
another type backing it.

The solution?  Well, there are two possible ones.  One is you create a  
ficticious type (or use void *) and cast when inside the delegate.  The  
other is to not use delegates, but use types instead.  Either a struct or  
a class/interface will do, something for the compiler to anchor on.

-Steve
April 23, 2012
Re: Recursive aliases?
On 04/23/2012 01:44 PM, Steven Schveighoffer wrote:
> On Sat, 21 Apr 2012 15:46:29 -0400, Mehrdad <wfunction@hotmail.com> wrote:
>
>> alias int delegate(out ItemGetter next) ItemGetter;
>>
>> We currently can't do the above^ in D, but what do people think about
>> allowing it?
>> i.e. More specifically, I think an alias expression should be able to
>> refer to the identifier (unless it doesn't make sense, like including
>> a struct inside itself).
>> (It would require a look-ahead.)
>
> It doesn't work.
>
> If I do this:
>
> alias int delegate() dtype;
>
> alias int delegate(dtype d) ddtype;
>
> pragma(msg, ddtype.stringof);
>
> I get:
>
> int delegate(int delegate() d)
>
> Note how it's not:
>
> int delegate(dtype d)
>
> Why? Because alias does not create a new type. It's a new symbol that
> *links* to the defined type.
>
> How shall the compiler expand your example so it can know the type?

Basically the same way it detects recursive aliases. It is not really an 
implementation problem, but it would add a special case (don't expand 
recursive aliases). In general, it would get a little bit challenging to 
resolve recursive types in a reliable way:

typeof(dg) delegate(typeof(dg(dg)(dg)), typeof(dg(dg)) = 
typeof(dg(dg(dg))).init) dg; // type safe!

Implementing those infinite types would be a fun exercise though :o)

> It works for classes because classes are a new type which do not need to
> have another type backing it.
>
> The solution? Well, there are two possible ones. One is you create a
> ficticious type (or use void *) and cast when inside the delegate. The
> other is to not use delegates, but use types instead. Either a struct or
> a class/interface will do, something for the compiler to anchor on.
>
> -Steve

Sure, but it shouldn't be necessary. There is no reason why it could not 
work except for the added complexity.
April 27, 2012
Re: Recursive aliases?
On 04/23/2012 04:44 AM, Steven Schveighoffer wrote:
> On Sat, 21 Apr 2012 15:46:29 -0400, Mehrdad <wfunction@hotmail.com> wrote:
>
>> alias int delegate(out ItemGetter next) ItemGetter;
>>
>> We currently can't do the above^ in D, but what do people think about
>> allowing it?
>> i.e. More specifically, I think an alias expression should be able to
>> refer to the identifier (unless it doesn't make sense, like including
>> a struct inside itself).
>> (It would require a look-ahead.)
>
> It doesn't work.
>
> If I do this:
>
> alias int delegate() dtype;
>
> alias int delegate(dtype d) ddtype;
>
> pragma(msg, ddtype.stringof);
>
> I get:
>
> int delegate(int delegate() d)
>
> Note how it's not:
>
> int delegate(dtype d)
>
> Why? Because alias does not create a new type. It's a new symbol that
> *links* to the defined type.
>

The only problem is that the text representation of the type contains 
it's self as a proper sub-string. As far as the compiler is concerned, 
this should be no harder to handle than a linked list node or the 
curiously recurring template pattern.

Another use for it would be one of the cleaner state machine 
implementations I've ever seen:


alias foo delegate() foo;

foo = start();
while ((foo = foo())) {}
April 28, 2012
Re: Recursive aliases?
On 21/04/2012 21:11, Tobias Pankrath wrote:
<snip>
> I've needed exactly this thing once.Or should I say: I needed
> this exactly once*?
<snip>

I don't know.  Which do you mean?

"I've needed exactly this thing once" - "exactly" is modifying "this thing" - means you 
needed this feature as opposed to some other possibly similar feature.

"I needed this exactly once" - "exactly" is modifying "once" - means you needed it once 
upon a time and then never again.

Stewart.
Top | Discussion index | About this forum | D home