equivariant functions

Steven Schveighoffer schveiguy at yahoo.com
Tue Oct 14 12:01:59 PDT 2008


"KennyTM~" wrote
> Steven Schveighoffer wrote:
>> "KennyTM~" wrote
>>> Andrei Alexandrescu wrote:
>>>> Steven Schveighoffer wrote:
>>>>> "Andrei Alexandrescu" wrote
>>>>>> I discussed with Walter a variant that implements equivariant 
>>>>>> functions without actually adding an explicit feature to the 
>>>>>> language. Consider:
>>>>>>
>>>>>> typeof(s) stripl(const(char)[] s);
>>>>> As another point on this, I think someone else mentioned it, but I 
>>>>> can't find the post.
>>>>>
>>>>> I don't like the way this looks.  The way it reads is 'stripl returns 
>>>>> the same type as s', but really, the typeof(s) is actually modifying 
>>>>> the type of the argument also.  This seems very unintuitive.
>>>> I agree. We need to look for a better notation.
>>>>
>>>>> I understand the need to not change the language, but I think most 
>>>>> would prefer a syntax where the type modifier is specified on at least 
>>>>> the argument.  People are going to be extremely confused when they 
>>>>> can't treat 's' like a normal const(char)[].
>>>>>
>>>>> If the ultimate result is that no intuitive syntax can be made without 
>>>>> changing the language, then I think it is more important to have this 
>>>>> feature than to not change the language.
>>>>>
>>>>> One other syntax that Janice proposed (and I later put into a 
>>>>> bugzilla), is to use the dead keyword inout.  Meaning, what you send 
>>>>> in is what you get out.  ref already completely replaces inout, so 
>>>>> there is no need to keep it under its current meaning:
>>>>>
>>>>> inout(char)[] stripl(inout(char)[] s);
>>>>>
>>>>> I'm not in love with this completely, but it has the benefit of not 
>>>>> requiring a new keyword.
>>>> Also I guess:
>>>>
>>>> class C
>>>> {
>>>>     Range!(inout(C)) foo() inout;
>>>> }
>>>>
>>>> And also:
>>>>
>>>> class Base {}
>>>> class Derived : Base {}
>>>> inout foo(inout Base b);
>>>>
>>>> I think this could work and doesn't look half bad. Of course, you'll be 
>>>> tasked with addressing protests about yet another D1/D2 
>>>> incompatibility. :o)
>>>>
>>>>
>>>> Andrei
>>> I'm afraid the meaning of inout here is very unclear without 
>>> explanation.
>>
>> You are correct.  It means 'what you send in as input gets returned as 
>> output.'
>>
>> In reality, it's not the best name for this type of thing, but it has the 
>> benefit of using a defunct keyword -- no new keywords necessary.
>>
>> I can't think of a really good keyword that is short and would not 
>> require explanation.  Perhaps you can?  Then we have to weigh the 
>> benefits of having a new keyword vs. having to post an explanation as to 
>> what it means.  My guess is we'll have to post an explanation no matter 
>> what.
>>
>> -Steve
>
> Sorry, I can't think of an existing keyword that can clearly qualify the 
> purpose in this syntax ("stuff(Type) f(stuff(Type) s)") either.

I meant a new keyword.  There aren't many existing keywords that I'd want to 
double the meaning of for this (including typeof).  inout is advantageous 
because its current meaning is exactly covered by another keyword.

>
> By the explanation argument, I actually mean what a programmer first sees 
> this feature think of. Presented with Andrei's "typeof" syntax, I can at 
> least guess what the function looks like (it returns the same type as "s", 
> OK)

Then you failed to see the true meaning of Andrei's syntax ;)  It means that 
the return value is the same as what you used as s to call the function, not 
the type of s (which is whatever the function declares s as).  The return 
type changes depending on what you call it with.

e.g.:

typeof(s) foo(const(char)[] s);

...

char[] x = "hello".dup;

auto x2 = foo(x); // x2 is typed as char[], even though s is declared as 
const(char)[]

> ; but with "inout" I just stopped with "What the heck is going on?!".

At least you are not guessing the wrong thing.  This would probably prompt 
you to look up how inout works in the docs.

I'm not saying that inout is the ideal keyword.  I'm saying that this is a 
novel enough concept that probably people are not going to intuitively see 
what is going on no matter what keyword is used.  They have to learn what 
it's doing by reading docs.  Using typeof as Andrei defined seems 
intuitively to mean something entirely different, and most likely will not 
prompt a lookup of the docs (until it doesn't behave as expected).  Plus it 
doubles the meaning of yet another keyword, which I hate...

e.g. what did you think was happening when you first saw 'mixin'?  Did you 
intuitively think 'oh, this must take what I give it as a compile-time 
generated string and compile it into actual code'.  Probably not, so is 
mixin a bad keyword choice for that feature because you didn't intuitively 
think of it?

-Steve 





More information about the Digitalmars-d mailing list