Re: Defining some stuff for each class in turn

2009-10-02 Thread Steven Schveighoffer
On Thu, 01 Oct 2009 13:53:46 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Jarrett Billingsley wrote:

On Thu, Oct 1, 2009 at 12:25 PM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

[code injection]

What do you think?

 I think it sounds interesting enough, but I can't help but wonder if
this is a feature that you've really thought through (especially wrt.
how it interacts with mechanisms such as template mixins and normal
symbol inheritance), or if you just want it to support some pattern
you want to use in Phobos 2.


I've known for a long time this was in store if we want to define decent  
reflection. It's also been a perennial source of trouble with a lot of  
code that needs to inject members.


Let me give another example. When we discussed opCmp around here, people  
said that's the old way of doing things and that the right way is to use  
an interface Comparator!T, akin to Java's ComparatorT:


http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html

That only solves exactly one level of inheritance. It's a more elaborate  
solution that doesn't quite help that much. Consider:


interface Comparator(T)
{
 int opCmp(T rhs); // yum, exact type
}

class Widget : Comparator!Widget
{
 override opCmp(Widget rhs) { ... } // yum, exact type
}

class Gadget : Widget
{
 override opCmp(Gadget rhs) { ... } // ERROR
}

Of course that didn't work. Gadget.opCmp doesn't override anything.  
Gadget needs to remember to inherit Comparator!Gadget:


class Gadget : Widget, Comparator!Gadget
{
 override opCmp(Gadget rhs) { ... } // oh ok
}

So any class X in Widget's hierarchy that forgets to inherit  
Comparator!X undergoes the risk of having the wrong opCmp called for it.


With injection, Comparator can be made to work for any interface:

interface Comparator(T)
{
 int opCmp(Comparator!T rhs);
 mixin(Impl) // for each implementation Impl
 {
 int opCmp(Impl rhs);
 override int opCmp(Comparator!T rhs)
 {
 return opCmp(cast(Impl) rhs);
 }
 }
}

class Widget : Comparator!Widget { ... }

Now every derived class of Widget, including Widget itself, commits to  
define a opCmp with the proper signature (failure to do so results in a  
linker error), and also defines the interface function in terms of it.


This still isn't optimal.  For example, two different derivatives of the  
same class could try to compare to eachother and end up passing null into  
your opCmp.  It would be nice if the compiler could reject unrelated  
comparisons:


class X: Comparator!X
{
  int opCmp(X) {}
}

class Y: X
{
  int opCmp(Y) {}
}

class Z: X
{
  int opCmp(Z) {}
}

void main()
{
  auto y = new Y;
  auto z = new Z;
  z  y; // error, rejected because they can't possibly be related
}

If there was a way to do that it would be cool.  I also think the  
auto-defined opCmp should look like this:


override int opCmp(Comparator!T rhs)
{
  if(auto imp = cast(Impl) rhs)
 return opCmp(imp);
  return false;
}

That would cut down on calls into your actual opCmp function with a null  
argument.


-Steve


Re: Defining some stuff for each class in turn

2009-10-02 Thread Christopher Wright

Andrei Alexandrescu wrote:

Christopher Wright wrote:

Andrei Alexandrescu wrote:
I am becoming increasingly aware that we need to provide some means 
to define certain members (data and functions) for each class as if 
they were pasted there.


Most of the examples given would be well served by decent builtin 
reflection. Walter thinks reflection is too expensive to be active by 
default. Find a cheaper way to provide runtime reflection. It's not as 
sexy as using templates, but it's DRY and easier to use. Slower, but 
you don't pay the cost of reflection multiple times if you have 
multiple libraries requiring reflection.


What cheaper way would be than allowing a base class to prescribe 
reflection for its hierarchy? Where do templates even enter the mix? 
What's slower and why? Why do reflection as a language feature 
(increases base language size, buggy, rigid) instead of allowing it as a 
library if we so can? I'm totally against that.


Andrei


Once you get two or three libraries using reflection, it's cheaper to 
have the language provide it than to have separate, incompatible 
reflection systems.


It doesn't matter whether the language provides reflection or the 
standard library. (The only way for me to tell is whether I'm importing 
from core or from std.) Either way, it should be standardized and easy 
to opt in or out (depending on the default), and there should be no way 
or no cost for opting in twice.


You have to use templates to get reflection info, currently. Unless CTFE 
has gotten a lot better, in which case it's effectively the same as 
using templates, but with a bit less executable bloat.


Template-based solutions can be faster than reflection-based solutions 
because you can access fields and methods directly. But runtime 
reflection doesn't disallow templates.


Defining some stuff for each class in turn

2009-10-01 Thread Andrei Alexandrescu
I am becoming increasingly aware that we need to provide some means to 
define certain members (data and functions) for each class as if they 
were pasted there.


Right now that right is reserved to the compiler, which generates e.g. 
one static classinfo object for each class. But users would want to also 
define members for each class automatically. This is often the case with 
contravariant-argument functions (that we discussed recently) and other 
important cases such as factories and cloning.


For starters, assume I want to define one static int for each class in a 
hierarchy.


class Counted {
static uint counter;
...
}

Then subclasses of Counted would all share counter, something I don't 
want. I want each subclass to have its own counter, so I need to ask 
derived classes to *also* define counter:


class A : Counted {
static uint counter;
...
}

With the suggested feature, there would be the ability to define counter 
 for each class in turn.


class Counted {
mixin(Derived)
{
// Insert here stuff that must be pasted for each subclass
// of Counted (including Counted itself).
// Use Derived as the name of the current subtype of Counter
static uint counter;
static if (is(Counted == Derived))
ref uint getCounter() { return counter; }
else
override ref uint getCounter() { return counter; }
}
...
}

The code above does something quite neat - it defines an overridable 
function Counted.getCounter in the base class, and then overrides it in 
*every* class inheriting that base class, to return that class' own 
counter.


The same should go in interface definitions - the feature should allow 
you to


There are quite a few immediate applications of this: opEquals, opCmp, 
clone, various factories and object pools, and most importantly 
reflection. To enable custom reflection with today's D, we'd have to 
require each class to insert some code inside the class body. With the 
mechanism described above, we allow the base class or an interface (e.g. 
Reflectable) to inject the code into the derived class' body.


What do you think?


Andrei


Re: Defining some stuff for each class in turn

2009-10-01 Thread Jarrett Billingsley
On Thu, Oct 1, 2009 at 12:25 PM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 I am becoming increasingly aware that we need to provide some means to
 define certain members (data and functions) for each class as if they were
 pasted there.

 Right now that right is reserved to the compiler, which generates e.g. one
 static classinfo object for each class. But users would want to also define
 members for each class automatically. This is often the case with
 contravariant-argument functions (that we discussed recently) and other
 important cases such as factories and cloning.

 For starters, assume I want to define one static int for each class in a
 hierarchy.

 class Counted {
    static uint counter;
    ...
 }

 Then subclasses of Counted would all share counter, something I don't want.
 I want each subclass to have its own counter, so I need to ask derived
 classes to *also* define counter:

 class A : Counted {
    static uint counter;
    ...
 }

 With the suggested feature, there would be the ability to define counter
  for each class in turn.

 class Counted {
    mixin(Derived)
    {
        // Insert here stuff that must be pasted for each subclass
        // of Counted (including Counted itself).
        // Use Derived as the name of the current subtype of Counter
        static uint counter;
        static if (is(Counted == Derived))
            ref uint getCounter() { return counter; }
        else
            override ref uint getCounter() { return counter; }
    }
    ...
 }

 The code above does something quite neat - it defines an overridable
 function Counted.getCounter in the base class, and then overrides it in
 *every* class inheriting that base class, to return that class' own counter.

 The same should go in interface definitions - the feature should allow you
 to

 There are quite a few immediate applications of this: opEquals, opCmp,
 clone, various factories and object pools, and most importantly reflection.
 To enable custom reflection with today's D, we'd have to require each class
 to insert some code inside the class body. With the mechanism described
 above, we allow the base class or an interface (e.g. Reflectable) to inject
 the code into the derived class' body.

 What do you think?

I think it sounds interesting enough, but I can't help but wonder if
this is a feature that you've really thought through (especially wrt.
how it interacts with mechanisms such as template mixins and normal
symbol inheritance), or if you just want it to support some pattern
you want to use in Phobos 2.


Re: Defining some stuff for each class in turn

2009-10-01 Thread Andrei Alexandrescu

Jarrett Billingsley wrote:

On Thu, Oct 1, 2009 at 12:25 PM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

[code injection]

What do you think?


I think it sounds interesting enough, but I can't help but wonder if
this is a feature that you've really thought through (especially wrt.
how it interacts with mechanisms such as template mixins and normal
symbol inheritance), or if you just want it to support some pattern
you want to use in Phobos 2.


I've known for a long time this was in store if we want to define decent 
reflection. It's also been a perennial source of trouble with a lot of 
code that needs to inject members.


Let me give another example. When we discussed opCmp around here, people 
said that's the old way of doing things and that the right way is to use 
an interface Comparator!T, akin to Java's ComparatorT:


http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html

That only solves exactly one level of inheritance. It's a more elaborate 
solution that doesn't quite help that much. Consider:


interface Comparator(T)
{
int opCmp(T rhs); // yum, exact type
}

class Widget : Comparator!Widget
{
override opCmp(Widget rhs) { ... } // yum, exact type
}

class Gadget : Widget
{
override opCmp(Gadget rhs) { ... } // ERROR
}

Of course that didn't work. Gadget.opCmp doesn't override anything. 
Gadget needs to remember to inherit Comparator!Gadget:


class Gadget : Widget, Comparator!Gadget
{
override opCmp(Gadget rhs) { ... } // oh ok
}

So any class X in Widget's hierarchy that forgets to inherit 
Comparator!X undergoes the risk of having the wrong opCmp called for it.


With injection, Comparator can be made to work for any interface:

interface Comparator(T)
{
int opCmp(Comparator!T rhs);
mixin(Impl) // for each implementation Impl
{
int opCmp(Impl rhs);
override int opCmp(Comparator!T rhs)
{
return opCmp(cast(Impl) rhs);
}
}
}

class Widget : Comparator!Widget { ... }

Now every derived class of Widget, including Widget itself, commits to 
define a opCmp with the proper signature (failure to do so results in a 
linker error), and also defines the interface function in terms of it.



Andrei


Re: Defining some stuff for each class in turn

2009-10-01 Thread grauzone

Andrei Alexandrescu wrote:

Jarrett Billingsley wrote:

I think it sounds interesting enough, but I can't help but wonder if
this is a feature that you've really thought through (especially wrt.
how it interacts with mechanisms such as template mixins and normal
symbol inheritance), or if you just want it to support some pattern
you want to use in Phobos 2.


I've known for a long time this was in store if we want to define decent 
reflection. It's also been a perennial source of trouble with a lot of 
code that needs to inject members.


I don't see how that would be needed for reflection, and I've written 
some custom reflection/serialization myself. Yay for tupleof being able 
to read even private members.


Re: Defining some stuff for each class in turn

2009-10-01 Thread Leandro Lucarella
Andrei Alexandrescu, el  1 de octubre a las 11:25 me escribiste:
 What do you think?

I think this is close to Python metaclasses[1], but much more specific.
It's amazing how many cool things one can do with Python metaclasses
(there are several articles discussing them[2]) and decorators.  I would
love to see something similar in D but operating at compile-time.  I think
it would be nice to point to a more general solution (like AST macros)
than implementing all sort of small and specific tricks for each problem
instead.

[1] http://docs.python.org/reference/datamodel.html#customizing-class-creation
[2] http://en.wikipedia.org/wiki/Metaclass
http://www.ibm.com/developerworks/linux/library/l-pymeta.html

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Wake from your sleep,
the drying of your tears,
Today we escape, we escape.


Re: Defining some stuff for each class in turn

2009-10-01 Thread Denis Koroskin

On Thu, 01 Oct 2009 20:25:03 +0400, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

I am becoming increasingly aware that we need to provide some means to  
define certain members (data and functions) for each class as if they  
were pasted there.


Right now that right is reserved to the compiler, which generates e.g.  
one static classinfo object for each class. But users would want to also  
define members for each class automatically. This is often the case with  
contravariant-argument functions (that we discussed recently) and other  
important cases such as factories and cloning.


For starters, assume I want to define one static int for each class in a  
hierarchy.


class Counted {
 static uint counter;
 ...
}

Then subclasses of Counted would all share counter, something I don't  
want. I want each subclass to have its own counter, so I need to ask  
derived classes to *also* define counter:


class A : Counted {
 static uint counter;
 ...
}

With the suggested feature, there would be the ability to define counter  
  for each class in turn.


class Counted {
 mixin(Derived)
 {
 // Insert here stuff that must be pasted for each subclass
 // of Counted (including Counted itself).
 // Use Derived as the name of the current subtype of Counter
 static uint counter;
 static if (is(Counted == Derived))
 ref uint getCounter() { return counter; }
 else
 override ref uint getCounter() { return counter; }
 }
 ...
}

The code above does something quite neat - it defines an overridable  
function Counted.getCounter in the base class, and then overrides it in  
*every* class inheriting that base class, to return that class' own  
counter.


The same should go in interface definitions - the feature should allow  
you to


There are quite a few immediate applications of this: opEquals, opCmp,  
clone, various factories and object pools, and most importantly  
reflection. To enable custom reflection with today's D, we'd have to  
require each class to insert some code inside the class body. With the  
mechanism described above, we allow the base class or an interface (e.g.  
Reflectable) to inject the code into the derived class' body.


What do you think?


Andrei


This is cool. I'd also add Serialization task to the application list  
(currently I manually insert mixin Serializable!(); into every class.


There is one thing that I dislike about it, though. I believe mixin(Foo)  
{} syntax is a bit far-fetched, it is not obvious that Foo represents  
derived type inside a mixin scope.


I'd like to remind you that we could just use typeof(this) instead of  
Foo/Derived/etc:


static if (is (typeof(this) == Counted) {
ref uint getCounter() { return counter; }
} else {
override ref uint getCounter() { return counter; }
}

If you remember, we had a similar discussion about a half year ago. It was  
about ICloneable interface that forces all derived class to implement  
proper clone() method. We could define it as:


// forces implementor class and all the derivatives to implement proper  
clone() method

interface ICloneable
{
scope mixin {   // alternative syntax
typeof(this) clone();
}
}

and also be able to declare a method non-recursively (so that derived  
class don't have to implement that method):


interface ICloneableNonRecursive
{
typeof(this) clone();
}

Other possible solution could be to use a special derived keyword. We  
already have a class-level compile-time constant - super. We could also  
introduce its counter-part (derived), which will expand into a concrete  
derived class type. This will simplify the syntax a bit and will allow to  
get rid of mixin and an addition level of indentation:


interface ICloneable
{
derived clone();
}

interface IComparable
{
int opCmp(derived other);
}

As a downside, I don't know how to define a field in every class this way  
(int derived.counter; maybe?).


Re: Defining some stuff for each class in turn

2009-10-01 Thread Andrei Alexandrescu

Denis Koroskin wrote:

On Thu, 01 Oct 2009 20:25:03 +0400, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

[...]

What do you think?


Andrei


This is cool. I'd also add Serialization task to the application list 
(currently I manually insert mixin Serializable!(); into every class.


Yah, serialization is close to reflection so it's definitely part of the 
target applications of the features.


There is one thing that I dislike about it, though. I believe mixin(Foo) 
{} syntax is a bit far-fetched, it is not obvious that Foo represents 
derived type inside a mixin scope.


I'd like to remind you that we could just use typeof(this) instead of 
Foo/Derived/etc:


static if (is (typeof(this) == Counted) {
ref uint getCounter() { return counter; }
} else {
override ref uint getCounter() { return counter; }
}


Yah, I thought a lot along the likes of typeof(this). We need some 
symbolic alias for the struct or class currently being defined and 
typeof(this) is an obvious choice. I just fear that it might be 
confusing that typeof(this) works even outside any method, i.e. when 
there is no this.


If you remember, we had a similar discussion about a half year ago. It 
was about ICloneable interface that forces all derived class to 
implement proper clone() method. We could define it as:


// forces implementor class and all the derivatives to implement proper 
clone() method

interface ICloneable
{
scope mixin {// alternative syntax
typeof(this) clone();
}
}


Yah, I remember.

and also be able to declare a method non-recursively (so that derived 
class don't have to implement that method):


interface ICloneableNonRecursive
{
typeof(this) clone();
}

Other possible solution could be to use a special derived keyword. We 
already have a class-level compile-time constant - super. We could 
also introduce its counter-part (derived), which will expand into a 
concrete derived class type. This will simplify the syntax a bit and 
will allow to get rid of mixin and an addition level of indentation:


interface ICloneable
{
derived clone();
}

interface IComparable
{
int opCmp(derived other);
}

As a downside, I don't know how to define a field in every class this 
way (int derived.counter; maybe?).


I dislike adding yet another keyword. In fact, I want to propose Walter 
to eliminate super as a keyword and make it just an alias for the base 
class as if you defined it by hand.



Andrei


Re: Defining some stuff for each class in turn

2009-10-01 Thread Phil Deets
On Thu, 01 Oct 2009 12:53:46 -0500, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:


interface Comparator(T)
{
 int opCmp(Comparator!T rhs);
 mixin(Impl) // for each implementation Impl
 {
 int opCmp(Impl rhs);
 override int opCmp(Comparator!T rhs)
 {
 return opCmp(cast(Impl) rhs);
 }
 }
}



I like that you can use this in interfaces too. It seems to allow for  
something similar to multiple inheritance, but presumably without the  
implementation difficulty.


Phil Deets


Re: Defining some stuff for each class in turn

2009-10-01 Thread Andrei Alexandrescu

Phil Deets wrote:
On Thu, 01 Oct 2009 12:53:46 -0500, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:


interface Comparator(T)
{
 int opCmp(Comparator!T rhs);
 mixin(Impl) // for each implementation Impl
 {
 int opCmp(Impl rhs);
 override int opCmp(Comparator!T rhs)
 {
 return opCmp(cast(Impl) rhs);
 }
 }
}



I like that you can use this in interfaces too. It seems to allow for 
something similar to multiple inheritance, but presumably without the 
implementation difficulty.


Phil Deets


That's a great point. To compare this feature with Scala's mixins (which 
I studied and now feel are a good feature), my understanding is that 
Scala mixins are an interface plus a default implementation. The feature 
proposed above is an interface with a prescribed implementation. That 
way, Scala mixins seem to be somewhat more flexible.


Andrei


Re: Defining some stuff for each class in turn

2009-10-01 Thread Christopher Wright

Andrei Alexandrescu wrote:
I am becoming increasingly aware that we need to provide some means to 
define certain members (data and functions) for each class as if they 
were pasted there.


Most of the examples given would be well served by decent builtin 
reflection. Walter thinks reflection is too expensive to be active by 
default. Find a cheaper way to provide runtime reflection. It's not as 
sexy as using templates, but it's DRY and easier to use. Slower, but you 
don't pay the cost of reflection multiple times if you have multiple 
libraries requiring reflection.


Re: Defining some stuff for each class in turn

2009-10-01 Thread Andrei Alexandrescu

Christopher Wright wrote:

Andrei Alexandrescu wrote:
I am becoming increasingly aware that we need to provide some means to 
define certain members (data and functions) for each class as if they 
were pasted there.


Most of the examples given would be well served by decent builtin 
reflection. Walter thinks reflection is too expensive to be active by 
default. Find a cheaper way to provide runtime reflection. It's not as 
sexy as using templates, but it's DRY and easier to use. Slower, but you 
don't pay the cost of reflection multiple times if you have multiple 
libraries requiring reflection.


What cheaper way would be than allowing a base class to prescribe 
reflection for its hierarchy? Where do templates even enter the mix? 
What's slower and why? Why do reflection as a language feature 
(increases base language size, buggy, rigid) instead of allowing it as a 
library if we so can? I'm totally against that.


Andrei


Re: Defining some stuff for each class in turn

2009-10-01 Thread Michel Fortin

On 2009-10-01 14:05:10 -0400, Max Samukha spam...@d-coding.com said:


For example, the upcoming reflection mechanism in QtD (which uses its
own metaobjects instead of the limited classinfo) requires manual
insertion of a mixin into derived classes unless the mixin is inserted
implicitly when a signal/property/etc is declared.


I'm using the exact same solution here for the D/Objective-C bridge and 
it's working surprisingly well.


I certainly wouldn't turn down the possibility of inheriting an 
implementation in subclasses, it'd make things a little less hackish.



--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/