August 02, 2004
"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in news:cebr2j$1qic$1@digitaldaemon.com:

>> > But what I can say is that having a template such as the following is
>> totally
>> > f**cked:
>> >
>> >     template TransformedRange(R, F, T) { class TransformedRange
>> >      : public NotionalRange!(T)
>> >     {
>> >       . . .
>> >         this(R r, F f)
>> >         {
>> >             m_r = r.dup;
>> >             m_f = f;
>> >         }
>> >         this(R r)
>> >         {
>> >             m_r = r.dup;
// template cannot be instantiated if F doesn't have a default constructor
>> >             m_f = new F();
>> >         }
>> >     }

It seems to me that this 'all or nothing' approach of D templates is a bit too restrictive. So here's my suggestion to rectify this.


I suggest the attribute 'optional'. The optional attribute can be applied to any member (variables, functions, aliases, classes, members within classes etc.) of a template body. It means that a template instance *may* but *need not* 'support' the template member. Effectively, a template declaration consists of a set of guaranteed members and optional members.

<example>

template TFoo(T) {
   uint length(T v) {
      return v.length;
   }

   // Removes an element from an array.
   // Note: Function is only allowed for dynamic arrays and AAs.
   optional void remove(inout T array, int index) {
      delete array[index];
   }

   optional alias T.bar SomeAlias;
}
...

int[4] fixed;
int[] dynamic=new int[4];

TFoo!(int[4]).length(fixed); TFoo!(int[]).length(dynamic); TFoo!(int[]).remove(dynamic, 1); // works

TFoo!(int[4]).remove(fixed); // Error: optional function remove(inout int[4], int) not supported by instance TFoo!(int[4]). Reason: cannot have out or inout parameter of type int[4]

TFoo!(int).length(5);  // Error: no property 'length' for type 'int'

</example>



Explanation:

When the template is instantiated the compiler looks for semantic errors of all template members. The instantiation fails, if a semantic error is caused by a garanteed template member (AFAIK, this is the current way that D templates work). Any semantic errors that are caused by an optional template member,  merely means that the specific template instance does not support the 'erroneous' optional template member.

It is an error if a garanteed template member depends on an optional template
member, even if the specific template instance does support the optional
template member.
Therefore an optional member of template declaration can only be accessed if
a) the specific template instance supports the optional member.
or b) the optional template member is accessed within the context of an
optional template member of a template body.



Why is lazy template-evalution sometimes acceptable?

The problem in the given (contrived) example could be easily solved using
template specialization. But for big generic libraries, tons of
specializations, interfaces and template meta programming tricks might be
necessary. This is a burden for designers of the generic libraries and its
users.
When writting proof-of-concept code, the designers are pestered by an endless
stream of errors from the pedantic compiler. And when the library is finally
ready (late, of course) its users have to figure out the peculiarities of a
dozens of specializations, which results in a steep-learning curve.
Preferably, the use of optional elements in templates would be avoided by
library designers, but for some cases the added simplicity of the library is
well worth the costs of an occasional obscure error message for the user.
Disclaimer: I made everything out of thin air. Therefore none of my
statements could refer to the DTL or any simliar work.


Any, thoughts?




Farmer.





1 2 3 4 5 6 7 8 9
Next ›   Last »