Compile-time Interfaces

"Jérôme M. Berger" jeberger at free.fr
Mon Nov 28 02:17:40 PST 2011


Andrei Alexandrescu wrote:
> On 11/27/11 12:36 PM, "Jérôme M. Berger" wrote:
>>> 1. Right now we have "function applies to any type R that is a range".
>>> With the other approach, there'd be "function applies to any type T such
>>> that the given type R is a Range!T". That roundabout approach is likely
>>> to scale poorly to more complex cases. It's arguably inferior because
>>> often the range-ness is of interest, not naming T.
>>>
>>     Debatable, what kind of useful function can be built operating on
>> the above interface without reference to T (at least through auto)?
> 
> It is simpler syntactically and semantically to say "function works for
> any range R" and then optionally use ElementType!R, than to compulsively
> express both in one shot.
> 
>>> 2. Restrictions can be any Boolean expression, whereas interfaces only
>>> apply to types.
>>>
>>     Strawman! Nothing says that adding compile-time interfaces would
>> remove boolean restrictions.
> 
> What I meant to say was that since we need restricted templates anyway
> and compile-time interfaces would be a redundant addition to the
> language, we may as well question their usefulness.
> 
>>> 3. In an interface-based approach, everything must be named; there are
>>> no optional properties such as hasLength or isInfinite. That could, of
>>> course, be added as restricted templates, which means interfaces must
>>> coexist with restricted templates, a more powerful feature. So in the
>>> end interfaces are redundant.
>>>
>>     Strawman again!
> 
> This is not helping the exchange.
> 
>> Everything can be done in straight assembly so in
>> the end so-called higher-level constructs are redundant.
> 
> This reduction of a reasonable argument doesn't, either.
> 
	Maybe because the argument wasn't so reasonable after all...

>>     It should come down to a question of balance between individual
>> feature simplicity, power, and overall language complexity. Adding a
>> feature that is simpler and easier to use despite being less
>> powerful may be a good thing (e.g. "foreach" vs. "while") although
>> it increases the overall language complexity (additional keywords
>> and concepts to understand and remember).
> 
> Of course. But compile-time interfaces would need to stand on their own.
> We can't add such just because foreach makes things easier than while.
> Instead of ridiculing my arguments or engaging in fruitless comparisons,
> you may as well come with valid arguments in favor of compile-time
> interfaces.
> 
	You're missing my point. I don't have any strong opinion one way or
another about compile-time interface, I'm simply pointing out that
your arguments are not valid. The way I see it, your arguments can
be resumed by "there is another way to do it, so there is no point
in adding this functionality". This same argument could be applied
to any high level construct and it weakens your overall argumentation.


=====================================================================

	To get back on topic, your (valid) argument appears to be:
> since we need restricted templates anyway
> and compile-time interfaces would be a redundant addition to the
> language, we may [...] question their usefulness.

	So what would compile-time interfaces bring?

- They're easier to specify and to understand (especially for new
users or people coming from another language);

- They could result in clearer compiler error messages;

- For people using IDEs, the IDE should be able to generate
automatically the required boilerplate to implement the interface,
which it can't do for a template constraint. Even for those who do
not use an IDE, the boilerplate may be gotten easily by copy-pasting
the interface definition.


	On the flip side, what would compile-time interfaces cost?

- Additional overall language complexity in the form of an
additional language construct;

- Development time to implement them.


	So, are the advantages worth the cost?


=====================================================================

	How would they work?

	It might be possible to implement compile-time interfaces with a
simple lowering. Somebody who knows more about the compiler
internals will have to say how feasible this idea is.

Interface definition
====================

The interface could be defined as a "static" template interface:

static interface(T) Range {
    void popFront() const;
    @property bool empty() const;
    @property T front();
}

Class definition
================

There would be nothing special when defining a class:

class IntRange {
    void popFront() const;
    @property bool empty() const;
    @property int front();
}

Function definition
===================

Simple case
-----------

A function which uses a single compile-time interface and does not
need access to the "internal" type(s) could be defined as:

auto DoSomething (Range r) {...}

This would be lowered to:

auto DoSomething(R, T) (R r) if staticImplements!(R, Range!T) {...}


Multiple arguments
------------------

If the function needs to access several compile-time interfaces, or
if it needs access to the "internal" type(s), it could be defined as:

auto DoSomething(T, U) (Range!T r1, Range!U r2) {...}

This would be lowered to:

auto DoSomething(R1, T, R2, U) (R1 r1, R2 r2)
    if (staticImplements!(R1, Range!T) &&
        staticImplements!(R2, Range!U))
{...}


Specific internal data type
---------------------------

If the function requires a specific internal data type, it could be
defined as:

auto DoSomething (Range!int r) {...}

This would be lowered to:

auto DoSomething(R) (R r) if staticImplements!(R, Range!int) {...}


staticImplements
----------------

Note that these lowerings use a "staticImplements" constraint. This
constraint checks that a class (or interface) implements all of the
methods defined in a static interface. It does not require that the
class inherit from the interface (ISTR that somebody already wrote
something similar for regular interfaces).


		Jerome
-- 
mailto:jeberger at free.fr
http://jeberger.free.fr
Jabber: jeberger at jabber.fr

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20111128/b6e8ca1e/attachment.pgp>


More information about the Digitalmars-d mailing list