November 30, 2009
On Tue, 01 Dec 2009 00:00:23 +0300, Walter Bright <newshound1@digitalmars.com> wrote:

> Álvaro Castro-Castilla wrote:
>> It does. Shouldn't this work also?
>>  struct foo {
>>     void opDispatch( string name, T... )( T values ) {     }   }
>>                                                                                                                                        void main( ) {     foo f;
>>     f.bar( 3.14 );
>> }
>
> Declare as:
>
>      void opDispatch(string name, T...)(T values...)
>                                                 ^^^

What? I am using code like Álvaro posted all the time, whereas your syntax doesn't even work (according to my test):

void foo(T...)(T values)
{
}

foo(42);

Error: template test.foo(T...) does not match any function template declaration
Error: template test.foo(T...) cannot deduce template function from argument types !()(int)

I wonder why it works for opDispatch (if it does, as you say).
November 30, 2009
Walter Bright:
> So am I. It seems to be incredibly powerful.

Very powerful things can be dangerous too, they can lead to bugs, etc.


> Looks to me you can do things like:

This is stuff that can be written in the D docs to, for example you can add some of those examples in the D2 docs page about operators.

Bye,
bearophile
December 01, 2009
On Mon, Nov 30, 2009 at 3:38 PM, bearophile <bearophileHUGS@lycos.com> wrote:
> Walter Bright:
>> So am I. It seems to be incredibly powerful.
>
> Very powerful things can be dangerous too, they can lead to bugs, etc.

I'm a bit concerned about what this does to introspection.
With a dynamic language like Python, adding runtime methods does not
interfere with your ability to enumerate all the methods supported by
an object.
With this opDispatch it's no longer possible for the compiler to know
what list of methods a class responds to.

So unless we add some way for a class to enumerate such things, opDispatch effectively kills any introspecting that requires knowing everything in a class.

So that would make things like automatic wrapper generation difficult.
 And automatic mock classes.  Anything else that requires enumerating
methods?

Also how does this interact with property syntax?

--bb
December 01, 2009
Walter Bright Wrote:

> Simen kjaeraas wrote:
> > It would seem Walter is right, but only for opDispatch. This compiles fine. If you want compile errors, move the ellipsis around:
> 
> Hmm, looks like there is a problem, but it has nothing to do with opDispatch, as this:
> 
>      void bar(string s, T...)(T args)
> 
> doesn't work either.

I think this doesn't work as should. This code:

struct foo {
    void opDispatch( string name, T... )( T values... ) {
        pragma(msg,values);       // ...shows "tuple()"
        writeln(values);                  // ...shows nothing at runtime
        foreach(v;values) {            // ...idem
            writeln(v);
        }
    }
}

void main( ) {
    foo f;
    f.bar( 3.14, 6.28 );
}

Best regards,

Álvaro Castro-Castilla

December 01, 2009
On Mon, Nov 30, 2009 at 02:02:46PM -0800, Walter Bright wrote:
> 3. add methods to existing classes (monkey patching) that allow such extensions

I think allowing this in general is a bad idea - the opDispatch should only be implemented on a small number of classes.

The reason is simple: a typo in a method name should be a compile time error the vast majority of the time.

If opDispatch was implemented all over the place, allowing random runtime extensions, the error is put off until runtime.

I'm for having the feature - I just don't think it should be used very often.


To add methods to existing classes at compile time, the way I'd love to see it done is:

void newMethod(SomeClass myThis...)  myThis.whatever...{ }

SomeClass a;
a.newMethod(); // rewritten as newMethod(a)


-- 
Adam D. Ruppe
http://arsdnet.net
December 01, 2009
Bill Baxter, el 30 de noviembre a las 16:09 me escribiste:
> On Mon, Nov 30, 2009 at 3:38 PM, bearophile <bearophileHUGS@lycos.com> wrote:
> > Walter Bright:
> >> So am I. It seems to be incredibly powerful.
> >
> > Very powerful things can be dangerous too, they can lead to bugs, etc.
> 
> I'm a bit concerned about what this does to introspection.
> With a dynamic language like Python, adding runtime methods does not
> interfere with your ability to enumerate all the methods supported by
> an object.
> With this opDispatch it's no longer possible for the compiler to know
> what list of methods a class responds to.

That's another reason to have a better support for dynamic types, even when implemented in the library.

Maybe a mixin can be provided to enable some basic functionality, that's common to all objects using opDispatch(), like enumerating the runtime members or checking if a member exist.

Anyway, this problem is present in dynamic languages too, for example if
you use the __setattr__(), __getattr__() and __hasattr__() magic methods
in Python, you can't use introspection to see what's in the object, you
have to know its internals to get that information.

There are two levels of dynamicity (at least in Python), you can add
real members to an object (which can be inspected using the standard
Python facilities) or you can use those magic methods (which kills the
introspection too).

The problem with D (using opDispatch()) is you can't add real members, you
can only use magic method to add members at runtime. And that's why
I think it would be nice to have some standard facilities to do this extra
work, otherwise every D programmer will come up with its own
implementation and interoperability will be a nightmare.

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Ah, se va en 1981? Pero por qué? ... Ah, porque ya había sido determinado,
entonces quiere decir que pronto vamos a elegir presidente nuevo nosot...
Ah, nosotros no? Ah, lo van a elegir en la ... Ah! Quiere que le diga? Muy
bien pensado, porque cada vez que lo elegimos nosotros no duran nada!
	-- Tato vs. Tato (1980, Gobierno de Videla)
December 01, 2009
Alvaro Castro-Castilla wrote:
> I think this doesn't work as should. This code:

Yes, you're right. I'll look into fixing it.
December 01, 2009
Bill Baxter wrote:
> Also how does this interact with property syntax?

Define opDispatch with @property.
December 01, 2009
Adam D. Ruppe wrote:
> On Mon, Nov 30, 2009 at 02:02:46PM -0800, Walter Bright wrote:
>> 3. add methods to existing classes (monkey patching) that allow such extensions
> 
> I think allowing this in general is a bad idea - the opDispatch should
> only be implemented on a small number of classes.
> 
> The reason is simple: a typo in a method name should be a compile time error
> the vast majority of the time.
> 
> If opDispatch was implemented all over the place, allowing random runtime
> extensions, the error is put off until runtime.

Using opDispatch is up to the discretion of the class designer. I doubt it would be used in any but a small minority of classes.
December 01, 2009
On Mon, Nov 30, 2009 at 6:03 PM, Walter Bright <newshound1@digitalmars.com> wrote:
> Bill Baxter wrote:
>>
>> Also how does this interact with property syntax?
>
> Define opDispatch with @property.

So we can overload on @property-ness?  I.e. this works

struct S
{
@property
float x() { return 1.0f; }
float x() { return 2.0f; }
}

void main()
{
    S  s;
    writefln("%s", s.x); // writes 1.0
    writefln("%s", s.x()); // writes 2.0
}

--bb