July 03, 2007
Gregor Richards wrote:
> Time for a response without reading the entire message 8-D
> 
> http://www.dsource.org/projects/tango.tools/browser/trunk/tools/rodin
> 
> (FYI: Rodin will work with either Tango or Phobos)
> 
>  - Gregor Richards

Very impressive Gregor. One question: Will it be possible to call a function without knowing it's signature at compile time? In all examples you used a delegate, a function or a base class. What I'd like to do is something like:

object obj = refGetClass(classPath);
object[] arguments = new object[] { 1, "string", new Object() };
refCallMethod(obj, "foo", arguments);

Obviously the object[] doesn't work on D but maybe Box(T)?

Thanks
July 04, 2007
Julio César Carrascal Urquijo wrote:
> Gregor Richards wrote:
>> Time for a response without reading the entire message 8-D
>>
>> http://www.dsource.org/projects/tango.tools/browser/trunk/tools/rodin
>>
>> (FYI: Rodin will work with either Tango or Phobos)
>>
>>  - Gregor Richards
> 
> Very impressive Gregor. 

Can someone post a synopsis for those of us too lazy to go sifting through an svn repository?

--bb
July 04, 2007
Bill Baxter wrote:
> Julio César Carrascal Urquijo wrote:
>> Gregor Richards wrote:
>>> Time for a response without reading the entire message 8-D
>>>
>>> http://www.dsource.org/projects/tango.tools/browser/trunk/tools/rodin
>>>
>>> (FYI: Rodin will work with either Tango or Phobos)
>>>
>>>  - Gregor Richards
>>
>> Very impressive Gregor. 
> 
> Can someone post a synopsis for those of us too lazy to go sifting through an svn repository?
> 
> --bb

It is a project in two parts:

drefgen is a utility, based on the DMD front-end and written in C++, which generates meta-data about whatever code you pass to it.

rodin is a D library which is capable of reading that meta-data, allowing client code (quite possibly the very code you generated the meta-data from) access to it.

While it is an impressive piece of work, the resulting data is not available at compile-time, just run-time. Therefore it is not quite what my post was talking about. It might be able to get there with some work, but I have an aversion to code generation. Actual support in the compiler would be vastly preferable.

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org
July 08, 2007
Kirk McDonald wrote:
> 
> ----
> Member functions
> ----
> 
> Here is where things get really complicated.
> 
> class A {
>     void bar() {}
>     void bar(int i) {}
>     void bar(int i, int j, int k=20) {}
> 
>     void baz(real r) {}
> 
>     static void foobar() {}
>     final void foobaz() {}
> }
> 
> class B : A {
>     void foo() {}
>     override void baz(real r) {}
> }
> 
> D does not really have pointers to member functions. It is possible to fake them with some delegate trickery. In particular, there is no way to directly call an alias of a member function. This is important, as I will get to later.
> 
> The first mechanism needed is a way to get all of the member functions of a class. I suggest the addition of a .methodsof class property, which will derive a tuple of aliases of the class's member functions.
> 
> A.methodsof => Tuple!(A.bar, A.baz, A.foobar, A.foobaz)
> B.methodsof => Tuple!(A.bar, A.foobar, A.foobaz, B.foo, B.baz)
> 
> The order of the members in this tuple is not important. Inherited member functions are included, as well. Note that these are tuples of symbol aliases! Since these are function symbols, all of the mechanisms suggested earlier for regular function symbols should still work!
> 
> tupleof(A.bar) => Tuple!(void function(), void function(int), void function(int, int, int))
> 
> And so forth.
> 
> There are three kinds of member functions: virtual, static, and final. The next important mechanism that is needed is a way to distinguish these from each other. An important rule of function overloading works in our favor, here: A given function symbol can only refer to functions which are all virtual, all static, or all final. Therefore, this should be considered a property of the symbol, as opposed to one of the function itself.
> 

Why would we need to distinguish between virtual, static and final member functions?

> 
> Given these mechanisms, combined with the existing mechanisms to derive the return type and parameter type tuple from a function type, D's compile-time reflection capabilities would be vastly more powerful.
> 

I'm not sure about some of the detail, but in a general wey, yes it would be welcome to have such changes that would allows us to better work with functions. Some of the issues here are not just about compile time reflection, for instance, that you have to create a temporary type, or do a cast, to get a function pointer of a particular overload, seems quite hackish to me.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 08, 2007
"Bruno Medeiros" <brunodomedeiros+spam@com.gmail> wrote in message news:f6qiqg$1bsg$1@digitalmars.com...
>
> Why would we need to distinguish between virtual, static and final member functions?
>

At least from a scripting-language-binding-library point of view, it's useful to know that so that when you write:

Def!(A.foo);
Def!(A.bar);
Def!(A.baz);

If foo is static, bar is virtual, and baz is final, they might all have to be bound in different ways.


July 08, 2007
Bruno Medeiros wrote:
> Kirk McDonald wrote:
>> There are three kinds of member functions: virtual, static, and final. The next important mechanism that is needed is a way to distinguish these from each other. An important rule of function overloading works in our favor, here: A given function symbol can only refer to functions which are all virtual, all static, or all final. Therefore, this should be considered a property of the symbol, as opposed to one of the function itself.
>>
> 
> Why would we need to distinguish between virtual, static and final member functions?
> 

For starters, you can directly call static member functions, but not the others (they require an instance). The difference between virtual and final is more subtle, but is still worth-while to know if you start doing some stupid inheritance tricks.

As Jarrett points out, this information is particularly valuable when binding the language to another language.

>>
>> Given these mechanisms, combined with the existing mechanisms to derive the return type and parameter type tuple from a function type, D's compile-time reflection capabilities would be vastly more powerful.
>>
> 
> I'm not sure about some of the detail, but in a general wey, yes it would be welcome to have such changes that would allows us to better work with functions. Some of the issues here are not just about compile time reflection, for instance, that you have to create a temporary type, or do a cast, to get a function pointer of a particular overload, seems quite hackish to me.
> 

This would not change that. In fact, I honestly see nothing wrong with that. Casting seems like simplest way of specifying the overload, without introducing new syntax. (Although I'm aware some folks want to introduce new syntax for this express purpose.)

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org
July 08, 2007
Kirk McDonald wrote:
> Given these mechanisms, combined with the existing mechanisms to derive the return type and parameter type tuple from a function type, D's compile-time reflection capabilities would be vastly more powerful.

Thanks for taking the time to put together an especially valuable post.
July 11, 2007
Bruno Medeiros wrote:
> Kirk McDonald wrote:
>>
>> ----
>> Member functions
>> ----
>>
>> Here is where things get really complicated.
>>
>> class A {
>>     void bar() {}
>>     void bar(int i) {}
>>     void bar(int i, int j, int k=20) {}
>>
>>     void baz(real r) {}
>>
>>     static void foobar() {}
>>     final void foobaz() {}
>> }
>>
>> class B : A {
>>     void foo() {}
>>     override void baz(real r) {}
>> }
>>
>> D does not really have pointers to member functions. It is possible to fake them with some delegate trickery. In particular, there is no way to directly call an alias of a member function. This is important, as I will get to later.
>>
>> The first mechanism needed is a way to get all of the member functions of a class. I suggest the addition of a .methodsof class property, which will derive a tuple of aliases of the class's member functions.
>>
>> A.methodsof => Tuple!(A.bar, A.baz, A.foobar, A.foobaz)
>> B.methodsof => Tuple!(A.bar, A.foobar, A.foobaz, B.foo, B.baz)
>>
>> The order of the members in this tuple is not important. Inherited member functions are included, as well. Note that these are tuples of symbol aliases! Since these are function symbols, all of the mechanisms suggested earlier for regular function symbols should still work!
>>
>> tupleof(A.bar) => Tuple!(void function(), void function(int), void function(int, int, int))
>>
>> And so forth.
>>
>> There are three kinds of member functions: virtual, static, and final. The next important mechanism that is needed is a way to distinguish these from each other. An important rule of function overloading works in our favor, here: A given function symbol can only refer to functions which are all virtual, all static, or all final. Therefore, this should be considered a property of the symbol, as opposed to one of the function itself.
>>
> 
> Why would we need to distinguish between virtual, static and final member functions?
> 

Ok, I don't think I made my point correctly. Yes, it's useful to distinguish between virtual, static and final member functions[*], but that's something that could be done (if not already) with is-expressions. What I mean is more about this:
"An important rule of function overloading works in our favor, here: A given function symbol can only refer to functions which are all virtual, all static, or all final."
Why would we want this change?


[*] Although, I'm not so sure about virtual vs. final distinctions.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 11, 2007
Kirk McDonald wrote:
>>
>> I'm not sure about some of the detail, but in a general wey, yes it would be welcome to have such changes that would allows us to better work with functions. Some of the issues here are not just about compile time reflection, for instance, that you have to create a temporary type, or do a cast, to get a function pointer of a particular overload, seems quite hackish to me.
>>
> 
> This would not change that. In fact, I honestly see nothing wrong with that. Casting seems like simplest way of specifying the overload, without introducing new syntax. (Although I'm aware some folks want to introduce new syntax for this express purpose.)
> 

Casting is a kludge, and should not be used for something that is perfectly normal, valid (and possibly common). Fortunately we can hide it with some cleaner templates:
  auto fn2 = overload!(fn, int, char) // select fn(int, char) overload
I don't think new syntax should be added. But that doesn't mean that some things could not be improved with the current design. For instance, taking the address of an overloaded function without a cast (or another overload selection mechanism) should result in a error, instead of simply returning the address of the lexically first overload.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 11, 2007
Bruno Medeiros wrote:
> Kirk McDonald wrote:
> 
>>>
>>> I'm not sure about some of the detail, but in a general wey, yes it would be welcome to have such changes that would allows us to better work with functions. Some of the issues here are not just about compile time reflection, for instance, that you have to create a temporary type, or do a cast, to get a function pointer of a particular overload, seems quite hackish to me.
>>>
>>
>> This would not change that. In fact, I honestly see nothing wrong with that. Casting seems like simplest way of specifying the overload, without introducing new syntax. (Although I'm aware some folks want to introduce new syntax for this express purpose.)
>>
> 
> Casting is a kludge, and should not be used for something that is perfectly normal, valid (and possibly common). Fortunately we can hide it with some cleaner templates:
>   auto fn2 = overload!(fn, int, char) // select fn(int, char) overload
> I don't think new syntax should be added. But that doesn't mean that some things could not be improved with the current design. For instance, taking the address of an overloaded function without a cast (or another overload selection mechanism) should result in a error, instead of simply returning the address of the lexically first overload.
> 

I agree with making that an error, so long as we get a way to automatically derive the types of all of the overloads.

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org