April 17, 2009
On Fri, 17 Apr 2009 15:08:12 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Nick Sabalausky wrote:
>> "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:op.usjnzajzeav7ka@steves.networkengines.com...
>>> On Fri, 17 Apr 2009 14:32:07 -0400, Nick Sabalausky <a@a.a> wrote:
>>>
>>> My main concern that I've read so far is how if a class has a dynamic method dispatcher that's callable like a method, you can't rely on the compiler to help you typecheck (or spellcheck) the *non-dynamic* methods, because it will just default to sending incorrectly typed data or misspelled methods to the dynamic dispatcher.
>>  That is a *very* good point, that hadn't even occured to me.
>>
>>> I think dynamic methods  have a very limited use, and probably aren't worth polluting the D  language for a few rare cases.
>>>
>>  Agreed.
>>
>>> When you know the API ahead of time,  you're almost always better off to have statically typed objects.  When  you don't know it ahead of time, well, I prefer the uglyness of seeing the  quoted strings to having the compiler just start trusting everything I do  ;)
>>>
>>  Agreed.
>
> I think there's merit in binding via strings. It makes for very flexible code that is future-proof, dynamic-linking-friendly, and hot-swappable without recompiling (e.g. you don't need to recompile because you now implement an interface etc.) Reflection is very useful as well.
>
> If anything, this agreed-fest shows that the rift between static typing and dynamic typing is alive and well. I've seen many discussions in which people were mystified how anyone gets anything done in a statically-typed OO language. (In fairness, static typing and OO have at best a tense marriage.)
>
> But anyway, my point is that it's good to be open-minded. If this conversation does nothing but leave us firmly with our heels in static-land, then we haven't gained anything. If we weren't used to static types we wouldn't be here. I think D can and should allow string lookup for its methods. It's a low-complexity proposition that adds a very interesting tool to D's arsenal. I suggested Walter since a long time ago to support opDot!(string). He implemented the useless version (sigh) which was arguably much simpler and offered a cheap way to experiment. So I'm very happy it's back on the table, and with an implementation to boot. Congratulations David.

I guess I don't mind the dynamic lookup of methods, but I really don't like the proposal to make it look exactly like a statically typed call.  To "hide" the fact that you are doing a dynamic lookup makes me worry about losing the invariants that I come to enjoy with statically typed methods, that is, if I see x.method(a, b, c), it means that the compiler has checked that I called that method correctly with the correctly typed information.

I use C#'s runtime introspection all the time, and it makes for some really awesome code (things I wish D could do), but I still have to do things like

Type[] argTypes = ...;
object[] args = ...;
x.GetType().GetMethod("myMethod", argTypes).Invoke(x, args);

To have that simply cut down to:

x.myMethod(a, b, c);

is a nifty experiment, but now I lost all ability to know how the compiler is interpreting that.  I bet D can do a much better job at runtime type information than C# due to the template system being so powerful, but I still want to know that I'm dynamically doing something versus statically.

Something like:

void foo(object x)
{
   x.invoke("myMethod", a, b, c);
}

where invoke is some method that uses the classinfo of x to look up the method would be freaking awesome ;)

-Steve
April 17, 2009
Nick Sabalausky, el 17 de abril a las 14:45 me escribiste:
> > I'm not yet convinced, but it remains to be seen if there is some killer functionality that cannot be had without it.
> 
> Same here. So far, it just doesn't seem worth the loss of knowing at a glance what is and what might not be verified at compile-time. If I wanted to be throwing compile-time guarantees out the window, I'd go use PHP.

Being able to do it doesn't mean you have to use it always. You don't loose anything if you don't use it =)

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
The diference is simple: hackers build things, crackers break them.
April 17, 2009
Andrei Alexandrescu wrote:
> Nick Sabalausky wrote:
>> "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:op.usjnzajzeav7ka@steves.networkengines.com...
>>> On Fri, 17 Apr 2009 14:32:07 -0400, Nick Sabalausky <a@a.a> wrote:
>>>
>>> My main concern that I've read so far is how if a class has a dynamic method dispatcher that's callable like a method, you can't rely on the compiler to help you typecheck (or spellcheck) the *non-dynamic* methods, because it will just default to sending incorrectly typed data or misspelled methods to the dynamic dispatcher.
>>
>> That is a *very* good point, that hadn't even occured to me.
>>
>>> I think dynamic methods  have a very limited use, and probably aren't worth polluting the D  language for a few rare cases.
>>>
>>
>> Agreed.
>>
>>> When you know the API ahead of time,  you're almost always better off to have statically typed objects.  When  you don't know it ahead of time, well, I prefer the uglyness of seeing the  quoted strings to having the compiler just start trusting everything I do  ;)
>>>
>>
>> Agreed.
> 
> I think there's merit in binding via strings. It makes for very flexible code that is future-proof, dynamic-linking-friendly, and hot-swappable without recompiling (e.g. you don't need to recompile because you now implement an interface etc.) 

Does that still apply to the template version you proposed?

>Reflection is very useful as well.
> 
> If anything, this agreed-fest shows that the rift between static typing and dynamic typing is alive and well. I've seen many discussions in which people were mystified how anyone gets anything done in a statically-typed OO language. (In fairness, static typing and OO have at best a tense marriage.)

> But anyway, my point is that it's good to be open-minded. If this conversation does nothing but leave us firmly with our heels in static-land, then we haven't gained anything. If we weren't used to static types we wouldn't be here. I think D can and should allow string lookup for its methods. It's a low-complexity proposition that adds a very interesting tool to D's arsenal. I suggested Walter since a long time ago to support opDot!(string). He implemented the useless version (sigh) which was arguably much simpler and offered a cheap way to experiment. So I'm very happy it's back on the table, and with an implementation to boot. Congratulations David.
> 
> 
> Andrei
April 17, 2009
On Fri, 17 Apr 2009 23:23:52 +0400, Don <nospam@nospam.com> wrote:

> Yeah, The ideal language would detect ALL bugs at compile time. We don't want to move in the wrong direction.
>

I would consider it a "wrong direction". You won't use it *that* frequent, only in those places where it trully fits. For example, a Variant class and scripting languages bindings would greatly benefit for having this functionality.
April 17, 2009
On Fri, 17 Apr 2009 23:36:06 +0400, Denis Koroskin <2korden@gmail.com> wrote:

> On Fri, 17 Apr 2009 23:23:52 +0400, Don <nospam@nospam.com> wrote:
>
>> Yeah, The ideal language would detect ALL bugs at compile time. We don't want to move in the wrong direction.
>>
>
> I would consider it a "wrong direction".

Err.. Should read: I woudn't consider it a "wrong direction".
April 17, 2009
Steven Schveighoffer wrote:
> On Fri, 17 Apr 2009 15:08:12 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> I guess I don't mind the dynamic lookup of methods, but I really don't like the proposal to make it look exactly like a statically typed call.  To "hide" the fact that you are doing a dynamic lookup makes me worry about losing the invariants that I come to enjoy with statically typed methods, that is, if I see x.method(a, b, c), it means that the compiler has checked that I called that method correctly with the correctly typed information.

Yah, but that feeling of losing control often marks a paradigm shift (I hate that term, but incidentally it's exactly what I mean here; I guess there is a legit use for it after all). Some people were completely pissed that ++i does not necessarily mean one machine operation, but instead an arbitrary function call. Then STL came and knocked everybody's socks off.

> I use C#'s runtime introspection all the time, and it makes for some really awesome code (things I wish D could do), but I still have to do things like
> 
> Type[] argTypes = ...;
> object[] args = ...;
> x.GetType().GetMethod("myMethod", argTypes).Invoke(x, args);
> 
> To have that simply cut down to:
> 
> x.myMethod(a, b, c);
> 
> is a nifty experiment, but now I lost all ability to know how the compiler is interpreting that.  I bet D can do a much better job at runtime type information than C# due to the template system being so powerful, but I still want to know that I'm dynamically doing something versus statically.

I don't think you need to worry. Such a style would belong to a handful of types, e.g. Any. It's not a big deal that what you're doing with a value depends on its type.

> Something like:
> 
> void foo(object x)
> {
>    x.invoke("myMethod", a, b, c);
> }
> 
> where invoke is some method that uses the classinfo of x to look up the method would be freaking awesome ;)

But that doesn't quite unify things.


Andrei
April 17, 2009
Don wrote:
> Andrei Alexandrescu wrote:
>> I think there's merit in binding via strings. It makes for very flexible code that is future-proof, dynamic-linking-friendly, and hot-swappable without recompiling (e.g. you don't need to recompile because you now implement an interface etc.) 
> 
> Does that still apply to the template version you proposed?

Of course. The template version includes the version that only does dynamic lookup: you can do static, and you can do dynamic. The static part allows you e.g. to optimize some cases if you so wish. With the runtime string you can only do dynamic.

Again, making it a template in this case is a win-win thing. There's nothing inferior about it.


Andrei
April 17, 2009
Leandro Lucarella wrote:
> Nick Sabalausky, el 17 de abril a las 14:45 me escribiste:
>>> I'm not yet convinced, but it remains to be seen if there is some killer functionality that cannot be had without it.
>> Same here. So far, it just doesn't seem worth the loss of knowing at a glance what is and what might not be verified at compile-time. If I wanted to be throwing compile-time guarantees out the window, I'd go use PHP.
> 
> Being able to do it doesn't mean you have to use it always. You don't
> loose anything if you don't use it =)

Correction: You don't lose anything if *nobody you interact with* uses it. A feature that is wide open to abuse is dangerous, even if you'll never abuse it yourself.
The feature has to be worth using.

April 17, 2009
Nick Sabalausky:
> I'd rather have my compiler automatically guarantee correctness (when possible) than have to manually create even more tests than I'm already creating and *hope* that they catch all the problems.

This is a very old discussion about the pro/cons of dynamic/static typing :-)
(Also note that in such discussions what is often missing is a really powerful and flexible static type system, like Haskell one :-) )

Anyway, regarding what you say here, note that writing tests in python can be very fast, for example if you use doctests :-)
http://docs.python.org/library/doctest.html

In Haskell you have other good solutions as QuickCheck that invent tests for you: http://www.cs.chalmers.se/~rjmh/QuickCheck/

In my D code I write almost as many tests as I write in Python (about 0.8-1.5 lines of tests for 1 line of D code, while in Python I write about 1-2.5 lines of tests for each line of code). The D compiler is able to catch some bugs the PythoVM isn't able to, but such errors are usually easy to find and fix in Python code, and such tests are quick to write.
But then you have to write tests for the logic of method/functions/classes, and they require some time to be written in both languages.
The end result is that writing tests in Python is usually not as bad as you think.

Bye,
bearophile
April 17, 2009
On 17/04/2009 21:58, Steven Schveighoffer wrote:
> On Fri, 17 Apr 2009 14:49:37 -0400, Yigal Chripun <yigal100@gmail.com>
> wrote:
>
>> On 17/04/2009 21:34, bearophile wrote:
>>> Nick Sabalausky:
>>>>> There are people who swear by the ability of adding methods at
>>>>> runtime and changing the inheritance hierarchy dynamically. It
>>>>> makes for a very fluid environment.
>>>> Personally, I've always seen that as extremely sloppy and
>>>> haphazard.
>>>
>>> Adding methods at runtime is named "monkey patching", and it is
>>> considered a bad practice even in Python. In Ruby it is more common.
>>> Usually in such languages such things are less dangerous because the
>>> code contains lot of tests anyway. Some people say that a way to
>>> remove most of the downsides of monkey patching is to make it scoped,
>>> that is the changes (like a method added or replaced) to a class
>>> aren't seen globally in the whole program (like from other modules),
>>> but only in the scope where such change is done (and its subscopes).
>>> I think I have not seen languages where this is doable yet.
>>>
>>> Bye, bearophile
>>
>> just like anything in life this can be overused. This is a very useful
>> tool in a programmer's toolbox for when you need, for example, to
>> quickly experiment with something or do an urgent fix.
>>
>> It's like when you build a house you have it properly designed and
>> have solid foundations but after the house is built you can still
>> redesign internally without rebuilding the entire house.
>
> It's more like adding another outside door. Try doing that ;) (BTW,
> removing one is easy, but that kind of doesn't apply here...)
>
> changing internals in code is easy, that's why we use OOP. Changing APIs
> is not.
>
> -Steve

I completely disagree. here's a use case from my work:
we have executables that take 20+ min to compile and link, written with C, C++, and fortran, and we also have code in JavaScript.
when I work on the Javascript code it's very easy and quick to debug and test changes while the program is still running while doing the same with the C++ code is very annoying, every change I want to test requires me to wait 20+ minutes for the re-link. a *HUGE* waste of time and also it's easy to forget what you were doing while you wait. no APIs involved in this case.

OOP has nothing to do with this since there are both dynamically typed and statically typed OOP languages (Smalltalk vs. D/JAVA) as well as non-OOP languages (ML vs. LISP).

btw, I'm not trying to convince you that dynamic typing is necessary always a better solution. What I'm saying is that I agree with Andrei - we need to be open minded and have as many useful tools as possible in our programmer toolbox. The important thing is to choose the right tool for the job.

Having only a hammer makes a person think that "when all you got is a hammer everything looks like a nail" kind of way.