View mode: basic / threaded / horizontal-split · Log in · Help
May 18, 2009
Re: The Final(ize) Challenge
Christian Kamm wrote:
> Andrei Alexandrescu wrote:
> 
>> Ok, now with the advent (or rediscovery) of allMembers which I had no
>> idea existed, we're ready to start some serious butt-kick reflection
>> facilities.
>>
>> For starters, I'd like to present you with the following challenge.
> 
> Unless there's been a change in D2 I have missed, I don't think you can 
> forward functions with ref/out or default arguments correctly unless you 
> parse certain mangles or stringofs.
> 
> 

Time for a bug report.

Andrei
May 18, 2009
Re: The Final(ize) Challenge
>> Unless there's been a change in D2 I have missed, I don't think you can
>> forward functions with ref/out or default arguments correctly unless you
>> parse certain mangles or stringofs.
>> 
>> 
> 
> Time for a bug report.
> 
> Andrei

See
http://d.puremagic.com/issues/show_bug.cgi?id=1818
or the related
http://d.puremagic.com/issues/show_bug.cgi?id=1411
http://d.puremagic.com/issues/show_bug.cgi?id=1424

Treating default arguments or storage classes with the current scheme is 
difficult though - they are not part of the type. While the concept of an 
'function argument description' including type, storage class, default 
argument and identifier (!) exists in the frontend, it is not exposed to the 
user - except through tuples in a fairly accidental and inconsistent manner.
May 18, 2009
Re: The Final(ize) Challenge
Christian Kamm wrote:
>>> Unless there's been a change in D2 I have missed, I don't think you can
>>> forward functions with ref/out or default arguments correctly unless you
>>> parse certain mangles or stringofs.
>>>
>>>
>> Time for a bug report.
>>
>> Andrei
> 
> See
> http://d.puremagic.com/issues/show_bug.cgi?id=1818
> or the related
> http://d.puremagic.com/issues/show_bug.cgi?id=1411
> http://d.puremagic.com/issues/show_bug.cgi?id=1424
> 
> Treating default arguments or storage classes with the current scheme is 
> difficult though - they are not part of the type. While the concept of an 
> 'function argument description' including type, storage class, default 
> argument and identifier (!) exists in the frontend, it is not exposed to the 
> user - except through tuples in a fairly accidental and inconsistent manner.

Yes. All we need is a module std.reflection that does all that gruntwork 
and exposes a simple and nice interface for people who want to use 
reflection.

Andrei
May 18, 2009
Re: The Final(ize) Challenge
On Mon, May 18, 2009 at 1:23 PM, Jarrett Billingsley
<jarrett.billingsley@gmail.com> wrote:

> The first is a more general statement about trying to generate
> functions with D's metaprogramming.  It is a huge pain in the ass to
> actually create a function with a given name, because the only way
> that I know this can be done is with a string mixin.  As soon as we
> venture into that territory, we have to consider things like how to
> convert a parameter type tuple into a string, and whether or not the
> .stringof a type will be correctly qualified (I've run into problems
> with this before, where some code in a library is not able to mix in a
> string because it doesn't import the same modules that the calling
> code does, and then you just get undefined identifier errors).  For
> the love of all that is holy, can we PLEASE get something like
> __ident("blah")?  This would be so much easier and would probably
> drastically reduce my use of string mixins in general.

What about this front?  Is it out of the realm of possibility to get
an identifier-izer?
May 18, 2009
Re: The Final(ize) Challenge
Jarrett Billingsley wrote:
> On Mon, May 18, 2009 at 1:23 PM, Jarrett Billingsley
> <jarrett.billingsley@gmail.com> wrote:
> 
>> The first is a more general statement about trying to generate
>> functions with D's metaprogramming.  It is a huge pain in the ass to
>> actually create a function with a given name, because the only way
>> that I know this can be done is with a string mixin.  As soon as we
>> venture into that territory, we have to consider things like how to
>> convert a parameter type tuple into a string, and whether or not the
>> .stringof a type will be correctly qualified (I've run into problems
>> with this before, where some code in a library is not able to mix in a
>> string because it doesn't import the same modules that the calling
>> code does, and then you just get undefined identifier errors).  For
>> the love of all that is holy, can we PLEASE get something like
>> __ident("blah")?  This would be so much easier and would probably
>> drastically reduce my use of string mixins in general.
> 
> What about this front?  Is it out of the realm of possibility to get
> an identifier-izer?

I want this too, but first let's become able to do things we can't do 
and then to do things we can do, easier. The __ident thing has been on 
the table for literally years, I seem to recall I called it new 
alias("blah").

Andrei
May 18, 2009
Re: The Final(ize) Challenge
On Mon, 18 May 2009 12:12:40 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail@erdani.org> wrote:

> Ok, now with the advent (or rediscovery) of allMembers which I had no  
> idea existed, we're ready to start some serious butt-kick reflection  
> facilities.
>
> For starters, I'd like to present you with the following challenge.  
> Given any class C, e.g.:
>
> class C
> {
>      void foo(int) { ... }
>      int bar(string) { ... }
> }
>
> define a template class Finalize(T) such that Finalize!(C) is the same  
> as the following hand-written class:
>
> final class FinalizeC : C
> {
>      final void foo(int a) { return super.foo(a); }
>      final int bar(string a) { return super.bar(a); }
> }
>
> Finalize is cool when you need some functionality from an exact class  
> and you don't want to pay indirect calls throughout. All calls through  
> Finalize!(C)'s methods will resolve to static calls.
>
>
> Have at it!

1 minor issue, if super.foo(a) calls bar, then it's still a virtual call...

Not that it's not a good idea, but you might get a lot less mileage out of  
it than you think.

I think you'd need compiler help to get rid of that problem.  It'd be like  
a flattening of a class to recompile all base class virtual calls with the  
notion that any internal calls it makes are final.  If you casted to a  
base class, the initial call would be virtual, but the internal calls  
would be nonvirtual.  This would be impossible unless you had the source  
to all the base classes, it might just be better to do it as a separate  
code-generator tool.

Back to your idea...

This feature that you suggest seems very trivial for the compiler to  
implement, while extremely hard to do it via reflection.  I've longed for  
this for a while:

interface I
{
  int foo();
}

class A
{
  int foo() {return 0;}
}

class B: A, I
{
  alias A.foo foo;
}

which makes B implement the interface by simply copying the vtable entry  
from A's.  This even saves on the double call (having a derived class  
function that simply calls the base class function).  You could then allow:

class B: A, I
{
  final alias A.foo foo;
}

and the compiler knows it doesn't need a virtual lookup.  Then the  
template to do it to all virtual methods would be trivial.

-Steve
May 18, 2009
Re: The Final(ize) Challenge
On Mon, May 18, 2009 at 2:20 PM, Andrei Alexandrescu
<SeeWebsiteForEmail@erdani.org> wrote:
>
> I want this too, but first let's become able to do things we can't do and
> then to do things we can do, easier. The __ident thing has been on the table
> for literally years, I seem to recall I called it new alias("blah").

I'm more worried that this will just slip through the cracks and not
make it into D2.  Then it'd be implemented in some post-D2 version of
DMD, and then D3 will be forked, so it'll _kind of_ be part of D2 but
not _really_ since it wasn't part of the spec when it was 'frozen'..
we've been here before :P

It seems like such low-hanging fruit.  So many of my string mixins
only exist to parameterize the names of things that this would almost
completely replace them.  It's on the same level as static foreach -
not essential, but it'd certainly make a lot of metaprogramming
simpler.
May 18, 2009
Re: The Final(ize) Challenge
Jarrett Billingsley wrote:
> On Mon, May 18, 2009 at 2:20 PM, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>> I want this too, but first let's become able to do things we can't do and
>> then to do things we can do, easier. The __ident thing has been on the table
>> for literally years, I seem to recall I called it new alias("blah").
> 
> I'm more worried that this will just slip through the cracks and not
> make it into D2.  Then it'd be implemented in some post-D2 version of
> DMD, and then D3 will be forked, so it'll _kind of_ be part of D2 but
> not _really_ since it wasn't part of the spec when it was 'frozen'..
> we've been here before :P
> 
> It seems like such low-hanging fruit.  So many of my string mixins
> only exist to parameterize the names of things that this would almost
> completely replace them.  It's on the same level as static foreach -
> not essential, but it'd certainly make a lot of metaprogramming
> simpler.

I think you need to operate exclusively with string mixins in Finalize, 
so __ident would be of marginal help there. Also, static foreach is much 
more necessary.

Andrei
May 18, 2009
Re: The Final(ize) Challenge
Steven Schveighoffer wrote:
> Back to your idea...
> 
> This feature that you suggest seems very trivial for the compiler to 
> implement, while extremely hard to do it via reflection.

The problem is, there are a million things that are trivial for the 
compiler to implement and harder with libraries. But that approach just 
doesn't scale. Finalize is only the beginning and pretty much a working 
example to flesh out library primitives. Don't get bogged down by it.

Andrei
May 18, 2009
Re: The Final(ize) Challenge
On Mon, May 18, 2009 at 2:34 PM, Andrei Alexandrescu
<SeeWebsiteForEmail@erdani.org> wrote:

> I think you need to operate exclusively with string mixins in Finalize, so
> __ident would be of marginal help there. Also, static foreach is much more
> necessary.

I have used string mixins extensively in my own code, not just in this
one example.  Most of the time it's to replace a name.  With something
like __ident, I wouldn't have to use them nearly as much, and in fact
I probably wouldn't need them here.  Think about it:

template CreateOverload(alias func, char[] name)
{
	ReturnType!(func) __ident(name)(ParameterTypeTuple!(func) args)
	{
		return super.__ident(name)(args);
	}
}

Then later, I could just use a template mixin.

You say static foreach is much more necessary than this.  Why?  It's
just a convenience, so you don't have to use template recursion.  Is
it more important because you want to use it?
1 2 3 4 5 6
Top | Discussion index | About this forum | D home