equivariant functions

Steven Schveighoffer schveiguy at yahoo.com
Tue Oct 14 07:36:55 PDT 2008


"Andrei Alexandrescu" wrote
> Steven Schveighoffer wrote:
>> "Andrei Alexandrescu" wrote
>> I'm glad you are looking into this.  This is along the same vein as what 
>> I called 'scoped const' (see 
>> http://d.puremagic.com/issues/show_bug.cgi?id=1961), but I only addressed 
>> const variance.
>>
>> Just in terms of const, I have a case where your solution doesn't 
>> help/work.
>>
>> Easiest case is min/max:
>>
>> typeof(v1) min(T)(const(T) v1, const(T) v2) { if(v1 < v2) return v1; 
>> return v2;}
>>
>> Now, imagine you call it like this:
>>
>> char[] best = "bb".dup;
>> best = min(aa, "aa");
>>
>> If the function and usage are allowed to compile, then this results in 
>> best, being a char[], to be pointing to an invariant(char)[].
>
> The function doesn't compile per the typechecking I discussed in a 
> different post.

I read that, but I didn't understand it, I'll go read it again ;)

>
>> There are two problems that need to be solved here.  First, you need 
>> another const type.  One that is treated as const, but is implicitly 
>> castable back to the argument type, and can't be implicitly casted to. 
>> That type modifier needs to be perpetuated throughout the function, 
>> because you shouldn't be able to return things that didn't originate from 
>> the input.  If I create a temporary variable, I should have to use this 
>> modifier to declare the variable (in my proposal, at the suggestion of 
>> Janice, I used 'inout', a dead keyword).  This guarantees that your 
>> output is a subset of the input.
>
> I think the typedef-based approach could work (and be that type you 
> mention).

So in your scheme, the following is true?

void foo2(const(char)[] arg);

typeof(arg) foo3(const(char)[] arg);

typeof(arg1)  foo(const(char)[] arg1)
{
   arg1 = "foo"; // fails
   typeof(arg1) arg1copy = arg1; // ok
   const(char)[] arg2 = arg1; // ok
   foo2(arg1); // ok
   arg1copy = foo3(arg1); // ok
   return arg1copy; // ok
}

If that's the case, then the scheme is similar to what I had in mind.

I don't really like the typeof(arg1) to use as the type name for temporary 
variables inside the function, it seems innocuous.  Perhaps a special type 
name can be implicitly declared inside the function?

>
>> An example of how min looks in my proposal (with the proposed 'inout' 
>> keyword):
>>
>> inout(T) min(T)(inout(T) v1, inout(T) v2)
>>
>> The second problem is, you want the return type to be dependent on both 
>> v1 and v2.  In my proposal, the return type could depend on multiple 
>> arguments, and if they varied by constancy, the return type was defaulted 
>> to const, as this is the only possible type that anything can be casted 
>> to.
>>
>> You might be tempted to do something like this:
>>
>> typeof(v1) min(T)(const(T) v1, typeof(v1) v2)
>>
>> But then if you pass in the mutable version as the first, the function 
>> fails to compile in the usage I have above.
>
> My solution does theoretically support multiple types by including them in 
> the typeof expression. Walter, however, mentioned potential difficulties 
> with implementing them.

OK, so how does min look in your scheme?

-Steve 





More information about the Digitalmars-d mailing list