November 29, 2009
On 2009-11-29 06:14:21 -0500, "Simen kjaeraas" <simen.kjaras@gmail.com> said:

> That is because your opDispatch is instantiated no matter what the name
> is, but only does something sensible if it's foo. Try this:
> 
> string opDispatch( string name )( ) {
>    static if ( name == "foo" ) {
>      return "foo";
>    } else {
>      static assert( false, "Invalid member name." );
>    }
> }

Wouldn't this be even better?

	string opDispatch(string name)() if (name == "foo") {
		return "foo";
	}

I haven't tested that it works though.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

November 29, 2009
Le 29/11/09 13:16, Michel Fortin a écrit :
> On 2009-11-29 06:14:21 -0500, "Simen kjaeraas" <simen.kjaras@gmail.com>
> said:
>
>> That is because your opDispatch is instantiated no matter what the name
>> is, but only does something sensible if it's foo. Try this:
>>
>> string opDispatch( string name )( ) {
>> static if ( name == "foo" ) {
>> return "foo";
>> } else {
>> static assert( false, "Invalid member name." );
>> }
>> }
>
> Wouldn't this be even better?
>
> string opDispatch(string name)() if (name == "foo") {
> return "foo";
> }
>
> I haven't tested that it works though.
>

It doesn't improve the error message, but it works. It's been a long time since I used D: I didn't know this syntax!
November 29, 2009
Walter Bright wrote:

> And here it is (called opDispatch, Michel Fortin's suggestion):
> 
> 
http://www.dsource.org/projects/dmd/changeset?new=trunk%2Fsrc@268&old=trunk%2Fsrc@267

holy duck, that is quick!
November 29, 2009
biozic wrote:

> Le 29/11/09 13:16, Michel Fortin a écrit :
>> On 2009-11-29 06:14:21 -0500, "Simen kjaeraas" <simen.kjaras@gmail.com> said:
>>
>>> That is because your opDispatch is instantiated no matter what the name is, but only does something sensible if it's foo. Try this:
>>>
>>> string opDispatch( string name )( ) {
>>> static if ( name == "foo" ) {
>>> return "foo";
>>> } else {
>>> static assert( false, "Invalid member name." );
>>> }
>>> }
>>
>> Wouldn't this be even better?
>>
>> string opDispatch(string name)() if (name == "foo") {
>> return "foo";
>> }
>>
>> I haven't tested that it works though.
>>
> 
> It doesn't improve the error message, but it works. It's been a long time since I used D: I didn't know this syntax!

Don has made a patch to improve these kind of error messages in templates, but that will probably come after D2 is finalized (doesn't affect the language).

If you want to resolve the symbol at runtime I think you can get a better error message for throwing an exception or assertion. I don't have the svn dmd, so this isn't tested:

void opDispatch(string name)(string file = __FILE__, int line = __LINE__)
{
  if ( !dynamicDispatch(name) )
  {
    // line and file are default initialized from the call site:
    throw new MethodMissingException(name, file, line);
  }
}





November 29, 2009
On Sun, 29 Nov 2009 16:02:24 +0300, Lutger <lutger.blijdestijn@gmail.com> wrote:

> biozic wrote:
>
>> Le 29/11/09 13:16, Michel Fortin a écrit :
>>> On 2009-11-29 06:14:21 -0500, "Simen kjaeraas" <simen.kjaras@gmail.com>
>>> said:
>>>
>>>> That is because your opDispatch is instantiated no matter what the name
>>>> is, but only does something sensible if it's foo. Try this:
>>>>
>>>> string opDispatch( string name )( ) {
>>>> static if ( name == "foo" ) {
>>>> return "foo";
>>>> } else {
>>>> static assert( false, "Invalid member name." );
>>>> }
>>>> }
>>>
>>> Wouldn't this be even better?
>>>
>>> string opDispatch(string name)() if (name == "foo") {
>>> return "foo";
>>> }
>>>
>>> I haven't tested that it works though.
>>>
>>
>> It doesn't improve the error message, but it works. It's been a long
>> time since I used D: I didn't know this syntax!
>
> Don has made a patch to improve these kind of error messages in templates,
> but that will probably come after D2 is finalized (doesn't affect the
> language).
>
> If you want to resolve the symbol at runtime I think you can get a better
> error message for throwing an exception or assertion. I don't have the svn
> dmd, so this isn't tested:
>
> void opDispatch(string name)(string file = __FILE__, int line = __LINE__)
> {
>   if ( !dynamicDispatch(name) )
>   {
>     // line and file are default initialized from the call site:
>     throw new MethodMissingException(name, file, line);
>   }
> }
>
>

IIRC, this trick only works when __FILE__ and __LINE__ are both template arguments.
November 29, 2009
Denis Koroskin wrote:

> On Sun, 29 Nov 2009 16:02:24 +0300, Lutger <lutger.blijdestijn@gmail.com>
*snip*
>> If you want to resolve the symbol at runtime I think you can get a better
>> error message for throwing an exception or assertion. I don't have the
>> svn
>> dmd, so this isn't tested:
>>
>> void opDispatch(string name)(string file = __FILE__, int line = __LINE__)
>> {
>>   if ( !dynamicDispatch(name) )
>>   {
>>     // line and file are default initialized from the call site:
>>     throw new MethodMissingException(name, file, line);
>>   }
>> }
>>
>>
> 
> IIRC, this trick only works when __FILE__ and __LINE__ are both template arguments.

hey that's right. That means when Walter fixes the current bug with template parameters, good compile time error messages are possible after all.


November 29, 2009
biozic:
> Ok but what still looks confusing is that the error is reported on the template code, as for any template instantiation error,

Using the template constraint has to avoid that problem, improving the error message. And Don will probably improve the error messages in the other templates in future.

Bye,
bearophile
November 29, 2009
Le 29/11/09 14:23, Lutger a écrit :
> Denis Koroskin wrote:
>
>> On Sun, 29 Nov 2009 16:02:24 +0300, Lutger<lutger.blijdestijn@gmail.com>
> *snip*
>>> If you want to resolve the symbol at runtime I think you can get a better
>>> error message for throwing an exception or assertion. I don't have the
>>> svn
>>> dmd, so this isn't tested:
>>>
>>> void opDispatch(string name)(string file = __FILE__, int line = __LINE__)
>>> {
>>>    if ( !dynamicDispatch(name) )
>>>    {
>>>      // line and file are default initialized from the call site:
>>>      throw new MethodMissingException(name, file, line);
>>>    }
>>> }
>>>
>>>
>>
>> IIRC, this trick only works when __FILE__ and __LINE__ are both template
>> arguments.
>
> hey that's right. That means when Walter fixes the current bug with template
> parameters, good compile time error messages are possible after all.
>
>

I tried:

==============================================
module main;
import std.stdio;
import std.string;

class Test
{
    string foo(string name)(string file = __FILE__, int line = __LINE__)
    {
        return format("Call of Test.foo at %s(%d).", file, line);
    }

    string bar(string name, string file = __FILE__, int line = __LINE__)()
    {
        return format("Call of Test.bar at %s(%d).", file, line);
    }
}

void main()
{
    auto test = new Test;
    writeln(test.foo!"something");
    writeln(test.bar!"something");
}
==============================================

and the output is:

Call of Test.foo at test.d(21).
Call of Test.bar at test.d(12).
November 29, 2009
Walter Bright, el 27 de noviembre a las 15:30 me escribiste:
> One thing Java and Python, Ruby, etc., still hold over D is dynamic classes, i.e. classes that are only known at runtime, not compile time. In D, this:

I like the feature, but I don't understand where is the duck-typing in all this. I think you're confusing duck-typing with dynamic-typing or I'm missing something?

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Ambition makes you look pretty ugly
November 29, 2009
Sun, 29 Nov 2009 14:59:27 -0300, Leandro Lucarella wrote:

> Walter Bright, el 27 de noviembre a las 15:30 me escribiste:
>> One thing Java and Python, Ruby, etc., still hold over D is dynamic classes, i.e. classes that are only known at runtime, not compile time. In D, this:
> 
> I like the feature, but I don't understand where is the duck-typing in all this. I think you're confusing duck-typing with dynamic-typing or I'm missing something?

Well it seems like the duck typing happens all on compile time with the new feature. You get some of the features of true dynamic languages, but not all. You can't really write python/ruby style dynamic code with it, e.g.

class foo {
  void sayHello() { print("hello"); }
}

auto bar = new foo();

try {
  bar.sayBye();
}
catch(MethodNotFoundException e) {
  ...
}

auto bye_routine(Object o) {
  return o.sayBye();
}

bar.sayBye = { bar.sayHello(); return "and bye"; }

println(bye_routine(bar));

Of course this is inefficient and error prone but that's what's it all about in dynamic languages. You get tons of flexibility.