equivariant functions

Denis Koroskin 2korden at gmail.com
Tue Oct 14 10:26:54 PDT 2008


On Tue, 14 Oct 2008 21:04:01 +0400, Steven Schveighoffer  
<schveiguy at yahoo.com> 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 think that basic idea is very good! (for some reason I was bound to  
constness issue and didn't think about the latter example).

>>
>> 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
>
>

I have previously proposed the 'same' keyword:

same(Base) foo(same(Base) bar)
{
    bar.callSomeBaseMethod();
    return bar;
}

foo(new Derived());

interface IClonable {
     same(this) clone();
}

It is short and very descriptive.

Frankly speaking, I don't see the difference between inout or some other  
keyword. You either ditch inout and introduce FOO or obsolete inout and  
reuse it. Both have similar effect: some code is broken and needs fixing  
(because inout doesn't work anymore), a new keyword is introduced to  
denote the feature. The only difference is a possible name collision that  
any new keyword might introduce. But it is nothing to worry about, because  
short and meaningful keywords are more important than some potentially  
broken (and easily fixable) code for the language in a long run.



More information about the Digitalmars-d mailing list