Clay language
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Wed Dec 29 13:14:11 PST 2010
On 12/29/10 2:58 PM, Steven Schveighoffer wrote:
> On Wed, 29 Dec 2010 15:38:27 -0500, Andrei Alexandrescu
> <SeeWebsiteForEmail at erdani.org> wrote:
>
>> On 12/29/10 2:10 PM, Steven Schveighoffer wrote:
>>> On Wed, 29 Dec 2010 14:42:53 -0500, Andrei Alexandrescu
>>> <SeeWebsiteForEmail at erdani.org> wrote:
>>>
>>>> On 12/27/10 6:55 PM, Andrei Alexandrescu wrote:
>>>>> On 12/27/10 12:35 PM, bearophile wrote:
>>>>>> Through Reddit I have found a link to some information about the Clay
>>>>>> language, it wants to be (or it will be) a C++-class language, but
>>>>>> it's not tied to C syntax. It shares several semantic similarities
>>>>>> with D too. It looks like a cute language:
>>>>>> https://github.com/jckarter/clay/wiki/
>>>>> [snip]
>>>>>
>>>>> FWIW I just posted a response to a question asking for a comparison
>>>>> between Clay and D2.
>>>>>
>>>>> http://www.reddit.com/r/programming/comments/es2jx/clay_programming_language_wiki/
>>>>>
>>>>>
>>>>
>>>> That thread is shaping up more and more interesting because it's
>>>> turning into a discussion of generic programming at large.
>>>
>>> I wanted to address your post in the reddit discussion regarding the
>>> issue of operator overloads not being virtual:
>>>
>>> "This non-issue has been discussed in the D newsgroup. You can implement
>>> virtuals on top of non-virtuals efficiently, but not vice versa."
>>>
>>> I've found some very real problems with that, when implementing operator
>>> overloads in dcollections. It's forced me to use the (yet to be
>>> deprecated) opXXX forms. Specifically, you cannot use covariance with
>>> templated functions without repeating the entire implementation in the
>>> derived class.
>>
>> Glad you're bringing that up. Could you please post an example that
>> summarizes the issue?
>
> With D1:
>
> interface List
> {
> List opCat(List other);
> }
>
> class LinkList : List
> {
> LinkList opCat(List other) {...}
> }
>
> With D2:
>
> interface List
> {
> List doCat(List other); // implement this in derived class
> List opBinary(string op)(List other) if (op == "~")
> { return doCat(other); }
> }
>
> class LinkList : List
> {
> LinkList doCat(List other) {...}
> }
>
> // usage;
>
> LinkList ll = new LinkList(1, 2, 3);
> ll = ll ~ ll; // works with D1, fails on D2, "can't assign List to
> LinkList"
>
> Solution is to restate opBinary in all dervied classes with *exact same
> code* but different return type. I find this solution unacceptable.
I understand, thanks for taking the time to share. The solution to this
matter as I see it is integrated with another topic - usually you want
to define groups of operators, which means you'd want to define an
entire translation layer from static operators to overridable ones.
Here's the code I suggest along those lines. I used a named function
instead of a template to avoid 4174:
template translateOperators()
{
auto ohPeeCat(List other) { return doCat(other); }
}
interface List
{
List doCat(List other); // implement this in derived class
}
class LinkList : List
{
LinkList doCat(List other) { return this; }
mixin translateOperators!();
}
void main(string[] args)
{
LinkList ll = new LinkList;
ll = ll.ohPeeCat(ll);
}
The translateOperators template would generally define a battery of
operators depending on e.g. whether appropriate implementations are
found in the host class (in this case LinkList).
Andrei
More information about the Digitalmars-d
mailing list