equivariant functions

Steven Schveighoffer schveiguy at yahoo.com
Wed Oct 15 12:02:01 PDT 2008


"Andrei Alexandrescu" wrote
> Steven Schveighoffer wrote:
>>>  const?(X) f(const?(Y) y, const?(Z) z);
>>
>> All these sound like valid alternatives, I'd be fine with any of them.
>
> The const? has been on the table. It is a fave of mine because it offers a 
> consistent solution for a related issue - detecting lvalueness:
>
> void foo(ref? Widget w);
>
> This means foo should bind to a ref Widget if you pass it an lvalue, and 
> to a Widget if offered an rvalue. There is precedent on using "x?" to mean 
> an optional x in regexes, so I wouldn't be surprised if many figured what 
> const? does when first seeing it.
>
> One issue  have with const? is that it binds the behavior to const, 
> thereby eliminating the chance of making things more general. Also the 
> const? will have to do something NOT suggested by the notation, namely 
> pass the invariant, if present, along.

I've convinced myself at this point that the const piece has to be separate 
from the 'derived type' piece.  Both can be required separately, i.e. I want 
to allow variations to the constancy of a specific type, but not to 
derivative types.

Therefore, it makes the most sense to me to make each feature use a distinct 
syntax.  So I have no problem with this notation for the const variant.

As far as invariant, I think it is well established that people don't gripe 
or sing the praises of the const-invariant system, they generally refer to 
it as the const system.  I think it's already a defacto standard that const 
in D includes invariant.  They are clearly related.

> Anyhow, I wanted to share one more thought. On the face of it, as someone 
> already said, we DO have a solution to avoid code duplication: templates. 
> Maybe a fertile direction to take would be to use regular template syntax 
> and just let the compiler figure out that it can actually define only one 
> function instead of three.
>
> What I'm saying is that we're really trying to beat the compiler in the 
> head until it understands that:
>
> S stripl(S s) if (is(S : const(char)[]) { stmts }
>
> really means to us:
>
> char[] stripl(char[] s) { stmts }
> const(char)[] stripl(const(char)[] s) { stmts }
> invariant(char)[] stripl(invariant(char) s) if (is(S : const(char)[]) { 
> stmts }
>
> What if, instead of finding yet another notation for that simple fact, we 
> actually used the "right" notation (it is right because it's already 
> there!) and figure out whether the compiler can understand it?
>
> I was about to post when I realized that that idea won't work prettily at 
> all with member functions... sigh :o/

Yeah, that would be tough for functions you want to make virtual.  I think 
it needs to be required to be a single function implementation, not left up 
to the compiler.

-Steve 





More information about the Digitalmars-d mailing list