April 17, 2009
davidl, el 17 de abril a las 14:31 me escribiste:
> After tweaking dmd a bit litte, i get the dotexp overloading work.
> 
> The following is the test code:
> import std.stdio;
> class c
> {
> 
>     B opDotExp(char[] methodname,...)
>     {
>     	writefln("god it works ", methodname);
>       return new B();
>     }
>     void opAdd(int j)
>     {
> 
>     }
>     void test()
>     {
>     }
> }
> 
> class a:c
> {
> 
> }
> 
> class B
> {
>   int i;
>   B opAssign(int k){
>     i=k;
>     return this;
>   }
> }
> 
> char[] v1;
> 
> void func(char[] v, ...){}
> 
> void main()
> {
>    a v=new a;
>    v.test();
>    v.dynamicmethod(3,4);
>    //v.qq = 5;
>    writefln((v.qq = 5).i);
> }
> 
> it generates the output:
> god it works dynamicmethod
> god it works qq
> 5
> 
> Any comments? Do you like this feature?

This is awsome indeed. I'd love to see it in the specs. The suggestion of making opDotExp a template it's good one too. I guess that now that opDot is replaced by alias this, opDot can be used for this instead of opDotExp.

I don't fully understand the example though. In writefln((v.qq = 5).i),
how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't propagate
the 5 to the new B()?

Thanks for the great job.

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
Que barbaridad, este país se va cada ves más pa' tras, más pa' tras...
	-- Sidharta Kiwi
April 17, 2009
On Fri, 17 Apr 2009 09:44:09 -0400, Leandro Lucarella <llucax@gmail.com> wrote:

> I don't fully understand the example though. In writefln((v.qq = 5).i),
> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't propagate
> the 5 to the new B()?

I think it translates to

opDotExp("qq") = 5

Without knowing the signature of qq, how is the compiler supposed to infer that it is a property?  In fact, I think this might be a limitation of this syntax, you can't define dynamic properties.

I for one, can't really see a huge benefit, but then again, I don't normally work with dynamic-type langauges.  It looks to me like a huge hole that the compiler will ignore bugs that would have been caught if the methods were strongly typed:

class c
{
  void opDotExp(char[] methodname,...)
  {
     if(methodname == "mymethod")
        callMyMethod();
     else
        throw new Exception("bad method name: " ~ methodname);
  }
}

void foo(c myc, bool rarelySetToTrue)
{
  if(rarelySetToTrue)
    myc.mymethud(); // compiles, will throw runtime exception
}

Also, how do you overload the return value?  Using this proposal, you can't have different dynamic methods that return different types.

-Steve
April 17, 2009
On Fri, 17 Apr 2009 18:24:04 +0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> On Fri, 17 Apr 2009 09:44:09 -0400, Leandro Lucarella <llucax@gmail.com> wrote:
>
>> I don't fully understand the example though. In writefln((v.qq = 5).i),
>> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't
>> propagate
>> the 5 to the new B()?
>
> I think it translates to
>
> opDotExp("qq") = 5
>
> Without knowing the signature of qq, how is the compiler supposed to infer that it is a property?  In fact, I think this might be a limitation of this syntax, you can't define dynamic properties.
>
> I for one, can't really see a huge benefit, but then again, I don't normally work with dynamic-type langauges.  It looks to me like a huge hole that the compiler will ignore bugs that would have been caught if the methods were strongly typed:
>
> class c
> {
>    void opDotExp(char[] methodname,...)
>    {
>       if(methodname == "mymethod")
>          callMyMethod();
>       else
>          throw new Exception("bad method name: " ~ methodname);
>    }
> }
>
> void foo(c myc, bool rarelySetToTrue)
> {
>    if(rarelySetToTrue)
>      myc.mymethud(); // compiles, will throw runtime exception
> }
>
> Also, how do you overload the return value?  Using this proposal, you can't have different dynamic methods that return different types.
>
> -Steve

Here is how it could be done:

class C
{
    auto opDot(string methodName, T... args)(T args) // opDotExp renamed to opDot
    {
        static if (methodName == "length") {
            return _length; // return type is size_t
        } else static if (methodName == "resize") {
            _resize(args); // return type is void
        }
    }
}

This is a great use-case for compile-time "static switch". Can we haz one, please?
April 17, 2009
Denis Koroskin wrote:
> On Fri, 17 Apr 2009 18:24:04 +0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> 
>> On Fri, 17 Apr 2009 09:44:09 -0400, Leandro Lucarella <llucax@gmail.com>  wrote:
>>
>>> I don't fully understand the example though. In writefln((v.qq = 5).i),
>>> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't  propagate
>>> the 5 to the new B()?
>> I think it translates to
>>
>> opDotExp("qq") = 5
>>
>> Without knowing the signature of qq, how is the compiler supposed to  infer that it is a property?  In fact, I think this might be a  limitation of this syntax, you can't define dynamic properties.
>>
>> I for one, can't really see a huge benefit, but then again, I don't  normally work with dynamic-type langauges.  It looks to me like a huge  hole that the compiler will ignore bugs that would have been caught if  the methods were strongly typed:
>>
>> class c
>> {
>>    void opDotExp(char[] methodname,...)
>>    {
>>       if(methodname == "mymethod")
>>          callMyMethod();
>>       else
>>          throw new Exception("bad method name: " ~ methodname);
>>    }
>> }
>>
>> void foo(c myc, bool rarelySetToTrue)
>> {
>>    if(rarelySetToTrue)
>>      myc.mymethud(); // compiles, will throw runtime exception
>> }
>>
>> Also, how do you overload the return value?  Using this proposal, you  can't have different dynamic methods that return different types.
>>
>> -Steve
> 
> Here is how it could be done:
> 
> class C
> {
>     auto opDot(string methodName, T... args)(T args) // opDotExp renamed to opDot
>     {
>         static if (methodName == "length") {
>             return _length; // return type is size_t
>         } else static if (methodName == "resize") {
>             _resize(args); // return type is void
>         }
>     }
> }
> 
> This is a great use-case for compile-time "static switch". Can we haz one, please?

I think the more urgent need is for static loops. At least we have a simple workaround for static switch.

Andrei
April 17, 2009
On Fri, 17 Apr 2009 10:32:04 -0400, Denis Koroskin <2korden@gmail.com> wrote:

> On Fri, 17 Apr 2009 18:24:04 +0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
>> On Fri, 17 Apr 2009 09:44:09 -0400, Leandro Lucarella <llucax@gmail.com>
>> wrote:
>>
>>> I don't fully understand the example though. In writefln((v.qq = 5).i),
>>> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't
>>> propagate
>>> the 5 to the new B()?
>>
>> I think it translates to
>>
>> opDotExp("qq") = 5
>>
>> Without knowing the signature of qq, how is the compiler supposed to
>> infer that it is a property?  In fact, I think this might be a
>> limitation of this syntax, you can't define dynamic properties.
>>
>> I for one, can't really see a huge benefit, but then again, I don't
>> normally work with dynamic-type langauges.  It looks to me like a huge
>> hole that the compiler will ignore bugs that would have been caught if
>> the methods were strongly typed:
>>
>> class c
>> {
>>    void opDotExp(char[] methodname,...)
>>    {
>>       if(methodname == "mymethod")
>>          callMyMethod();
>>       else
>>          throw new Exception("bad method name: " ~ methodname);
>>    }
>> }
>>
>> void foo(c myc, bool rarelySetToTrue)
>> {
>>    if(rarelySetToTrue)
>>      myc.mymethud(); // compiles, will throw runtime exception
>> }
>>
>> Also, how do you overload the return value?  Using this proposal, you
>> can't have different dynamic methods that return different types.
>>
>> -Steve
>
> Here is how it could be done:
>
> class C
> {
>     auto opDot(string methodName, T... args)(T args) // opDotExp renamed to opDot
>     {
>         static if (methodName == "length") {
>             return _length; // return type is size_t
>         } else static if (methodName == "resize") {
>             _resize(args); // return type is void
>         }
>     }
> }
>

Look! I found a way to implement this *in the current compiler*!:

class C
{
   size_t length()
   {
      return _length;
   }

   void resize(T...)(T args)
   {
      _resize(args);
   }
}

sorry, couldn't help myself :P

-Steve
April 17, 2009
在 Fri, 17 Apr 2009 21:44:09 +0800,Leandro Lucarella <llucax@gmail.com> 写道:

> davidl, el 17 de abril a las 14:31 me escribiste:
>> After tweaking dmd a bit litte, i get the dotexp overloading work.
>>
>> The following is the test code:
>> import std.stdio;
>> class c
>> {
>>
>>     B opDotExp(char[] methodname,...)
>>     {
>>     	writefln("god it works ", methodname);
>>       return new B();
>>     }
>>     void opAdd(int j)
>>     {
>>
>>     }
>>     void test()
>>     {
>>     }
>> }
>>
>> class a:c
>> {
>>
>> }
>>
>> class B
>> {
>>   int i;
>>   B opAssign(int k){
>>     i=k;
>>     return this;
>>   }
>> }
>>
>> char[] v1;
>>
>> void func(char[] v, ...){}
>>
>> void main()
>> {
>>    a v=new a;
>>    v.test();
>>    v.dynamicmethod(3,4);
>>    //v.qq = 5;
>>    writefln((v.qq = 5).i);
>> }
>>
>> it generates the output:
>> god it works dynamicmethod
>> god it works qq
>> 5
>>
>> Any comments? Do you like this feature?
>
> This is awsome indeed. I'd love to see it in the specs. The suggestion of
> making opDotExp a template it's good one too. I guess that now that opDot
> is replaced by alias this, opDot can be used for this instead of opDotExp.
>
> I don't fully understand the example though. In writefln((v.qq = 5).i),
> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't propagate
> the 5 to the new B()?
>
> Thanks for the great job.
>

Thanks, the example here v.qq returns a B object, and then the assignment kicks in, therefore it calls B.opAssign(5), thus the i member of that B instance is 5.


-- 
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
April 17, 2009
在 Fri, 17 Apr 2009 22:24:04 +0800,Steven Schveighoffer <schveiguy@yahoo.com> 写道:

> On Fri, 17 Apr 2009 09:44:09 -0400, Leandro Lucarella <llucax@gmail.com> wrote:
>
>> I don't fully understand the example though. In writefln((v.qq = 5).i),
>> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't propagate
>> the 5 to the new B()?
>
> I think it translates to
>
> opDotExp("qq") = 5
>
> Without knowing the signature of qq, how is the compiler supposed to infer that it is a property?  In fact, I think this might be a limitation of this syntax, you can't define dynamic properties.
>

The opDotExp overload func is supposed to deal with that, because it's in your hand to deal with the dynamic properties. The example here is illustrating the dynamic properties.

> I for one, can't really see a huge benefit, but then again, I don't normally work with dynamic-type langauges.  It looks to me like a huge hole that the compiler will ignore bugs that would have been caught if the methods were strongly typed:
>
> class c
> {
>    void opDotExp(char[] methodname,...)
>    {
>       if(methodname == "mymethod")
>          callMyMethod();
>       else
>          throw new Exception("bad method name: " ~ methodname);
>    }
> }
>
> void foo(c myc, bool rarelySetToTrue)
> {
>    if(rarelySetToTrue)
>      myc.mymethud(); // compiles, will throw runtime exception
> }
>

The problem is you're dealing with the class which is overloaded its opDot. You know the risk before hand, you are not going to overload for every classes. Here, you seem to little bit overrate this feature. :)
If you want things checked, then you probabely need to go back to static. This dynamic stuff is used for dynamic things only, and as long as you have to do it in the dynamic way that means you have no easy way or even impossible to check it at compiletime and you accept the potential risk like the example you posted.

> Also, how do you overload the return value?  Using this proposal, you can't have different dynamic methods that return different types.
>

Umm, maybe make the compiler to pass the return type into the opDot would allow the opDot func to decide which overload func to call.

-- 
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
April 17, 2009
在 Fri, 17 Apr 2009 22:24:04 +0800,Steven Schveighoffer <schveiguy@yahoo.com> 写道:

> On Fri, 17 Apr 2009 09:44:09 -0400, Leandro Lucarella <llucax@gmail.com> wrote:
>
>> I don't fully understand the example though. In writefln((v.qq = 5).i),
>> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't propagate
>> the 5 to the new B()?
>
> I think it translates to
>
> opDotExp("qq") = 5
>
> Without knowing the signature of qq, how is the compiler supposed to infer that it is a property?  In fact, I think this might be a limitation of this syntax, you can't define dynamic properties.
>
> I for one, can't really see a huge benefit, but then again, I don't normally work with dynamic-type langauges.  It looks to me like a huge hole that the compiler will ignore bugs that would have been caught if the methods were strongly typed:
>

Actually this can help ddl project to work more nicely. Consider you can call plugin code directly without static bindings. And I believe delphi COM variant use some similar trick. It allows you call COM object without static bindings. Sometimes it's troublesome to get the static bindings, and you only need one piece of little function(you won't need the whole interface).


-- 
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
April 17, 2009
On Fri, 17 Apr 2009 11:11:55 -0400, davidl <davidl@nospam.org> wrote:

> 在 Fri, 17 Apr 2009 22:24:04 +0800,Steven Schveighoffer <schveiguy@yahoo.com> 写道:
>
>> On Fri, 17 Apr 2009 09:44:09 -0400, Leandro Lucarella <llucax@gmail.com> wrote:
>>
>>> I don't fully understand the example though. In writefln((v.qq = 5).i),
>>> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't propagate
>>> the 5 to the new B()?
>>
>> I think it translates to
>>
>> opDotExp("qq") = 5
>>
>> Without knowing the signature of qq, how is the compiler supposed to infer that it is a property?  In fact, I think this might be a limitation of this syntax, you can't define dynamic properties.
>>
>
> The opDotExp overload func is supposed to deal with that, because it's in your hand to deal with the dynamic properties. The example here is illustrating the dynamic properties.

except, you can't define a property like:

void prop(int x)
{
   _prop = x ^ ~0;
}

Using a dynamic method.

>
>> I for one, can't really see a huge benefit, but then again, I don't normally work with dynamic-type langauges.  It looks to me like a huge hole that the compiler will ignore bugs that would have been caught if the methods were strongly typed:
>>
>> class c
>> {
>>    void opDotExp(char[] methodname,...)
>>    {
>>       if(methodname == "mymethod")
>>          callMyMethod();
>>       else
>>          throw new Exception("bad method name: " ~ methodname);
>>    }
>> }
>>
>> void foo(c myc, bool rarelySetToTrue)
>> {
>>    if(rarelySetToTrue)
>>      myc.mymethud(); // compiles, will throw runtime exception
>> }
>>
>
> The problem is you're dealing with the class which is overloaded its opDot. You know the risk before hand, you are not going to overload for every classes. Here, you seem to little bit overrate this feature. :)
> If you want things checked, then you probabely need to go back to static. This dynamic stuff is used for dynamic things only, and as long as you have to do it in the dynamic way that means you have no easy way or even impossible to check it at compiletime and you accept the potential risk like the example you posted.

Sure, but what is the reason to need dynamic methods?  I'm just trying to understand the usefulness of it.  If a method is dynamic, we lose the following things:

- compile-time type/signature checking
- IDE assistance in determining which methods are available
- ease of tracing where a method call goes.
- not future proof -- for example, if a method name gets changed or moved, the code using the method still compiles.

If we lose all these things, there must be *something* we gain by doing this, right?

Also, what is the benefit of doing something like this versus specifically calling the dispatcher instead of having the compiler translate it?

>
>> Also, how do you overload the return value?  Using this proposal, you can't have different dynamic methods that return different types.
>>
>
> Umm, maybe make the compiler to pass the return type into the opDot would allow the opDot func to decide which overload func to call.

Walter already has issues overloading on return type, I'm not sure this is any different.

-Steve
April 17, 2009
在 Fri, 17 Apr 2009 23:20:53 +0800,davidl <davidl@nospam.org> 写道:

> 在 Fri, 17 Apr 2009 22:24:04 +0800,Steven Schveighoffer <schveiguy@yahoo.com> 写道:
>
>> On Fri, 17 Apr 2009 09:44:09 -0400, Leandro Lucarella <llucax@gmail.com> wrote:
>>
>>> I don't fully understand the example though. In writefln((v.qq = 5).i),
>>> how is that B.i is assigned to 5 if the opDotExp("qq", 5) don't propagate
>>> the 5 to the new B()?
>>
>> I think it translates to
>>
>> opDotExp("qq") = 5
>>
>> Without knowing the signature of qq, how is the compiler supposed to infer that it is a property?  In fact, I think this might be a limitation of this syntax, you can't define dynamic properties.
>>
>> I for one, can't really see a huge benefit, but then again, I don't normally work with dynamic-type langauges.  It looks to me like a huge hole that the compiler will ignore bugs that would have been caught if the methods were strongly typed:
>>
>
> Actually this can help ddl project to work more nicely. Consider you can call plugin code directly without static bindings. And I believe delphi COM variant use some similar trick. It allows you call COM object without static bindings. Sometimes it's troublesome to get the static bindings, and you only need one piece of little function(you won't need the whole interface).
>
>

DDBI can also benefit from it.

Consider the use case:
myRow.Col1 = "abc";

-- 
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/