December 30, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jérôme M. Berger | > ?? The only type in this list without a division operator is vector > all the others have it. Matrix matrix, matrix vector, vector matrix division also not defined, there is one syntactic similarity but it is not division. Didn't give much of a thought to others since vector, matrix and scalar operations takes already quite a bit space. > I'm sorry? What do you call the "generic case" here? All this list > shows is that each operator needs to be implemented individually > anyway. Andrei's point was exactly the reverse: he claims that most > operators can be implemented in groups which clearly isn't the case I don't agree, majority of the cases you duplicate almost all of the code and just change the operator. That was the thing i meant with "generic case". If i wasn't clear, say: vector opBinary(string op)(scalar s) if(op == "+" || op == "-" ....) { static if(op == "/") return general("*")(1/s); // particular case else return general(op)(s); // general case, just a one-liner mixin } vector opBinary(string op)(vector v) if(op == "+" || op == "-" ....) { return general(op)(v); // again, just a one-liner mixin } Same goes for matrix, particular case being the multiplication. -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
December 30, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to so | On Thu, 30 Dec 2010 17:03:05 -0500, so <so@so.do> wrote:
>> ?? The only type in this list without a division operator is vector
>> all the others have it.
>
> Matrix matrix, matrix vector, vector matrix division also not defined, there is one syntactic similarity but it is not division.
> Didn't give much of a thought to others since vector, matrix and scalar operations takes already quite a bit space.
>
>> I'm sorry? What do you call the "generic case" here? All this list
>> shows is that each operator needs to be implemented individually
>> anyway. Andrei's point was exactly the reverse: he claims that most
>> operators can be implemented in groups which clearly isn't the case
>
> I don't agree, majority of the cases you duplicate almost all of the code and just change the operator. That was the thing i meant with "generic case".
> If i wasn't clear, say:
>
> vector opBinary(string op)(scalar s) if(op == "+" || op == "-" ....) {
> static if(op == "/")
> return general("*")(1/s); // particular case
> else
> return general(op)(s); // general case, just a one-liner mixin
> }
>
> vector opBinary(string op)(vector v) if(op == "+" || op == "-" ....) {
> return general(op)(v); // again, just a one-liner mixin
> }
>
> Same goes for matrix, particular case being the multiplication.
Actually, that doesn't work currently. But I think this is a situation that can be fixed.
Essentially, you can't overload templates. You have to do something like this instead:
vector opBinary(string op, T)(T s) if(is(T == scalar) && (op == "+" || op == "-" ....)) {
static if(op == "/")
return general("*")(1/s); // particular case
else
return general(op)(s); // general case, just a one-liner mixin
}
vector opBinary(string op, T)(T v) if(is(T == vector) && (op == "+" || op == "-" ....)) {
return general(op)(v); // again, just a one-liner mixin
}
So, it makes things difficult in this regard too, but I really hope this can be solved. It's already been stated in TDPL that templates will be able to overload with non-templates. I think this means they should overload with templates also.
Note that these solutions may look simple and easy to you, but they look convoluted and messy to me ;)
-Steve
|
December 31, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | Michel Fortin <michel.fortin@michelf.com> wrote: > I stubbled upon this yesterday: > > Template This Parameters > > TemplateThisParameters are used in member function templates to pick up the type of the this reference. > import std.stdio; > > struct S > { > const void foo(this T)(int i) > { > writeln(typeid(T)); > } > } > > <http://www.digitalmars.com/d/2.0/template.html> > > Looks like you could return the type of this this way... The problem of template this parameters is that it doesn't work as one might expect: class A { void bar( this T )( ) { writeln( typeid( T ) ); } } class B : A { } void main( ) { A a = new B; a.bar(); } Surely this will print modulename.B, right? Wrong. It prints modulename.A, as A is the type of the reference from which the function is called. It looks like a way to automagically override a function for each subclass, but no. -- Simen |
December 31, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samukha | On Thu, 30 Dec 2010 19:17:09 +0100, Max Samukha <spambox@d-coding.com> wrote: > On 12/30/2010 07:08 PM, Steven Schveighoffer wrote: > >> >> auto opAdd(Foo other) >> >> vs. >> >> auto opBinary(string op)(Foo other) if (op == "+") > > For the latter not to look so intimidating, it can be shortened to: > > auto opBinary(string op : "+")(Foo other) Sadly, that shortcut does not allow for grouping. :( Perhaps we could get a specialization for that, though: auto opBinary( string op : "+" | "-" )( Foo other ) for instance. -- Simen |
December 31, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer <schveiguy@yahoo.com> wrote: > Where the new scheme wins in brevity (for written code at least, and certainly not simpler to understand) is cases where: > > 1. inheritance is not used > 2. you can consolidate many overloads into one function. As others have pointed out, this likely accounts for 99% of uses. The one exception is opCat. -- Simen |
December 31, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | On 12/31/10, Simen kjaeraas <simen.kjaras@gmail.com> wrote:
>
This will give you both:
class A
{
void bar(this T) ( )
{
writeln(typeid(T));
writeln(typeid(this));
}
}
class B : A
{
}
void main( )
{
A a = new B;
a.bar();
}
|
December 31, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote: > On 12/31/10, Simen kjaeraas <simen.kjaras@gmail.com> wrote: >> > > This will give you both: > > class A > { > void bar(this T) ( ) > { > writeln(typeid(T)); > writeln(typeid(this)); > } > } > > class B : A > { > } > > void main( ) > { > A a = new B; > a.bar(); > } Indeed it will. Now, if you look closely, you will see that typeid(T) is A, while typeid(this) is B. Testing further: class A { void baz() { writeln(typeid(this)); } } class B : A { } void main() { A a = new B; a.baz(); // prints B. } We thus see that the template this parameter has absolutely no value. -- Simen |
December 31, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | On 12/31/10, Simen kjaeraas <simen.kjaras@gmail.com> wrote:
> We thus see that the template this parameter has absolutely no value.
Oh, you thought the D documentation is describing features *that work*? Ha! Classic mistake.
You see, the D documentation is about showcasing features which don't work, while TDPL is about showcasing features which don't even exist yet.
|
December 31, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu Attachments:
| Andrei Alexandrescu wrote: > And I stand by that claim. One aspect that seems to have been forgotten is that types usually implement either op= in terms of op or vice versa. That savings alone is large. > This could have been done with a couple of stdlib mixins "generateOpsFromOpAssign" and "generateOpAssignsFromOp". Jerome -- mailto:jeberger@free.fr http://jeberger.free.fr Jabber: jeberger@jabber.fr |
December 31, 2010 Re: Clay language | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen kjaeraas | On Thu, 30 Dec 2010 21:14:28 -0500, Simen kjaeraas <simen.kjaras@gmail.com> wrote:
> Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
>
>> On 12/31/10, Simen kjaeraas <simen.kjaras@gmail.com> wrote:
>>>
>>
>> This will give you both:
>>
>> class A
>> {
>> void bar(this T) ( )
>> {
>> writeln(typeid(T));
>> writeln(typeid(this));
>> }
>> }
>>
>> class B : A
>> {
>> }
>>
>> void main( )
>> {
>> A a = new B;
>> a.bar();
>> }
>
> Indeed it will. Now, if you look closely, you will see that typeid(T) is A, while typeid(this) is B. Testing further:
>
> class A {
> void baz() {
> writeln(typeid(this));
> }
> }
> class B : A {
> }
>
> void main() {
> A a = new B;
> a.baz(); // prints B.
> }
>
> We thus see that the template this parameter has absolutely no value.
No, it does have value:
class A
{
string x;
T setX(this T, U)(U newx)
{
this.x = to!string(newx);
return cast(T)this;
}
}
class B : A
{
int y;
void setY(int newy)
{
this.y = newy;
}
}
void main()
{
auto b = new B;
b.setX(5).setY(6);
}
Hey, look! covariance with templates :)
Now if only templates worked in interfaces...
I also have to write a helper function to eliminate that cast (which does a runtime lookup).
-Steve
|
Copyright © 1999-2021 by the D Language Foundation