April 17, 2009
"Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:op.usjevzhseav7ka@steves.networkengines.com...
> On Fri, 17 Apr 2009 11:27:57 -0400, davidl <davidl@nospam.org> wrote:
>>
>> DDBI can also benefit from it.
>>
>> Consider the use case:
>> myRow.Col1 = "abc";
>
> Yes, this case does make sense, but I would still probably rather write a statically-typed wrapper.
>
> Plus it's not terribly hard to write:
>
> myRow.set("Col1", "abc");
>

I think some sort of paramaterized property would be far better (I *think* we can do these, right?):

myRow.col("Col1") = "abc";
myRow.col["Col1"] = "abc";

> 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.


April 17, 2009
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.
April 17, 2009
On Fri, 17 Apr 2009 14:32:07 -0400, Nick Sabalausky <a@a.a> wrote:

> "davidl" <davidl@nospam.org> wrote in message
> news:op.usje9ia3j5j59l@my-tomato...
>>
>> The benefit is you don't need to write the call function,
>
> ...But you do have to write the opDotExp() function. How is that less work
> than just writing a dispatch function?
>
>> you don't need to write the string quote.
>
> I think I'd prefer that. If I put something in quotes, that tells me that
> typos might not get detected until runtime. But if I don't use quotes, and
> it compiles, then I know it's ok. With opDotExp, that certainty goes right
> out the window. All of a sudden I never know if an identifier following a
> dot compiled because it's ok, or because the error detection has been
> deferred. I'd feel like I was working in a dynamic language and I *HATE*
> working with dynamic languages. It's like trying to construct a building on
> a patch of ground that you know at any moment could change into a lake,
> sand, cliffside, or simply cease to exist without any warning.
>
> Additionally, here's an example from Haxe's xml.Fast:
>
> page.node.html.node.head.node.title.x.addChild(Xml.createPCData("Hello"));
>
> Think fast without any close inspection: What's the path being used? Umm...
>
> Ok, without opDotExp, that would be:
>
> page.node("html").node("head").node("title").x.addChild(Xml.createPCData("Hello"));
>
> That's a hell of a lot easier to read. Very easy now to see, at a mere
> glance, the path is "html/head/title".
>
> Of course, you could adjust the API for the Haxe/opDotExp version to be more
> like:
>
> page.html.head.title.x.addChild(Xml.createPCData("Hello"));
>
> But now (in addition to still not having the certainty of "if an unquoted
> identifier compiles, it must be ok"), you've opened yourself up to a world
> of naming collision issues.

This is what I was talking about, but didn't thoroughly explain when I said "ease of tracing where a method call goes."

Thanks for explaining this better.

I do see usefulness in cases like setting a field in a database row (which should be relatively painless, path-wise).  However, my preference is to create a wrapper class around the row to have the compiler to type check my calls.  In that case, the typechecked version would just call a dispatch routine anyways (which can be ugly because it's hidden).  I think dynamic methods are just asking for trouble in the form of latent bugs.

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.  I think dynamic methods have a very limited use, and probably aren't worth polluting the D language for a few rare cases.  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 ;)

-Steve
April 17, 2009
"davidl" <davidl@nospam.org> wrote in message news:op.usjfexkpj5j59l@my-tomato...
>ÔÚ Fri, 17 Apr 2009 23:34:37 +0800£¬Steven Schveighoffer <schveiguy@yahoo.com> дµÀ:
>
> Actually in a lot cases, you don't have the time to write the static
> wrapper.
> Also for a COM object, you don't want to call it in such ways:
>
> comobj.callfunc("ComObjFunc", 3,4,5);
>
> You probably want to call it only by comobj.ComObjFunc(3,4,5);
>
> Yes static wrapper can solve these all. Problem is not in all cases you want to make a static binding for it.
>

Solution: Create a dispatch function like callfunc above, then use a mixin to generate static callfunc wrappers for any functions that you already know you want.

That way, you can have your trivial-to-create static bindings and sidestep them too. ;)


April 17, 2009
"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.


April 17, 2009
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
April 17, 2009
"bearophile" <bearophileHUGS@lycos.com> wrote in message news:gsai34$1p9k$1@digitalmars.com...
> 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.

Interesting, I didn't know that.

> Usually in such languages such things are less dangerous because the code contains lot of tests anyway.

See, that just sounds to me like the dynamic-ness is just creating extra work for less payoff. 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.

> 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.
>

That would certainly be better. It sounds very much like extension methods, which I'm a big fan of (but I have yet to see polymorphic extension methods, that would be nice to have). Although I think I would still prefer extension methods (polymorphic or otherwise) be defined/declared statically.


April 17, 2009
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.


Andrei
April 17, 2009
Steven Schveighoffer, el 17 de abril a las 11:27 me escribiste:
> >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.

RPC is an example that comes into mind

There is plenty of magic you can do with dynamic methods. Just try a dynamic language and see =)

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
Corrí muchas carreras, tratando de alcanzarte a vos.
Pero corría sólo y siempre salí último.
April 17, 2009
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.

That's the VB/PHP nightmare -- allow any garbage to compile.
Yet, if the function name is in a template (which I believe it has to be), the problem isn't as bad: you can detect it in many cases.

The only use case I can really see for this is when an extremely large number of functions need to be created. Swizzling an array was one example that was mentioned previously:

float4 f, g;
g = f.wzyx * f.zzxy;

If you were to create all possibilities, it's 4^4 = 256 function overloads. Which is too many to document, but is still feasible to create with a mixin. If it was instead 8^8 functions, it'd really be a lot easier on the poor compiler's symbol table to have the functions generated only on demand.

Still,
g = f.swizzle!("wzyx");
(or Andrei-style g = f.swizzle!"wzyx"; )
isn't so terrible.

D is already incredibly more flexible and powerful than (say) C++, so there's not going to be any use cases which go from terrible to perfect.

> 
>> I think dynamic methods  have a very limited use, and probably aren't worth polluting the D  language for a few rare cases.
> 
> Agreed.

If there were a few use cases which were sufficiently important, it might be possible to create a solution for them which didn't allow so much undesirable behaviour.

> 
>> 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.
> 
Yeah, The ideal language would detect ALL bugs at compile time. We don't want to move in the wrong direction.