- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
[scala-language] Naming of Dynamic#invokeDynamic Method
Wed, 2011-01-26, 23:16
After some discussion, it seems to me that the (newly renamed) invokeDynamic method on the Dynamic trait should actually be named a bit more in line with what it's doing. As Charles Nutter points out, it's not really true dynamic dispatch, it's really just an intercept for method failure. In fact, it's exactly what method_missing does in Ruby and doesNotUnderstand in Smalltalk. So in other words, there are a few languages out there that already have a feature very much like this one. And while there is no standard for the naming, the convention is to imply the catching of an unhandled message. This is not at all what "invokeDynamic" implies (particularly in light of JSR-292 and the potential confusion there).
I propose that we rename invokeDynamic (again) to something slightly more indicative of what it is doing. I'm a Ruby guy, so methodMissing strongly appeals to me, but I would be ok with almost anything which hints at what is really going on (rather than implying something that it is not).
Daniel
I propose that we rename invokeDynamic (again) to something slightly more indicative of what it is doing. I'm a Ruby guy, so methodMissing strongly appeals to me, but I would be ok with almost anything which hints at what is really going on (rather than implying something that it is not).
Daniel
Wed, 2011-01-26, 23:47
#2
Re: [scala-language] Naming of Dynamic#invokeDynamic Method
method_missing? missingMethod sounds so much better to my ears...
Groovy uses methodMissing and propertyMissing (oh, just read Nutter's reply! they use missingMethod now!), the latter being unneeded in Scala. It's camel case, in line with the more popular Ruby use, so I'm all for it, if it truly does the same thing. If it does something _similar_, however, I'm very much against using that name.
Here's a couple of relevant posts about similar functionalities in various languages:
http://langexplr.blogspot.com/2008/02/handling-call-to-missing-method-in.html http://langexplr.blogspot.com/2008/02/handling-call-to-missing-method-in_06.html
On Wed, Jan 26, 2011 at 20:16, Daniel Spiewak <djspiewak@gmail.com> wrote:
--
Daniel C. Sobral
I travel to the future all the time.
Groovy uses methodMissing and propertyMissing (oh, just read Nutter's reply! they use missingMethod now!), the latter being unneeded in Scala. It's camel case, in line with the more popular Ruby use, so I'm all for it, if it truly does the same thing. If it does something _similar_, however, I'm very much against using that name.
Here's a couple of relevant posts about similar functionalities in various languages:
http://langexplr.blogspot.com/2008/02/handling-call-to-missing-method-in.html http://langexplr.blogspot.com/2008/02/handling-call-to-missing-method-in_06.html
On Wed, Jan 26, 2011 at 20:16, Daniel Spiewak <djspiewak@gmail.com> wrote:
After some discussion, it seems to me that the (newly renamed) invokeDynamic method on the Dynamic trait should actually be named a bit more in line with what it's doing. As Charles Nutter points out, it's not really true dynamic dispatch, it's really just an intercept for method failure. In fact, it's exactly what method_missing does in Ruby and doesNotUnderstand in Smalltalk. So in other words, there are a few languages out there that already have a feature very much like this one. And while there is no standard for the naming, the convention is to imply the catching of an unhandled message. This is not at all what "invokeDynamic" implies (particularly in light of JSR-292 and the potential confusion there).
I propose that we rename invokeDynamic (again) to something slightly more indicative of what it is doing. I'm a Ruby guy, so methodMissing strongly appeals to me, but I would be ok with almost anything which hints at what is really going on (rather than implying something that it is not).
Daniel
--
Daniel C. Sobral
I travel to the future all the time.
Thu, 2011-01-27, 09:17
#3
Re: [scala-language] Naming of Dynamic#invokeDynamic Method
On Wed, Jan 26, 2011 at 11:16 PM, Daniel Spiewak <djspiewak@gmail.com> wrote:
After some discussion, it seems to me that the (newly renamed) invokeDynamic method on the Dynamic trait should actually be named a bit more in line with what it's doing. As Charles Nutter points out, it's not really true dynamic dispatch, it's really just an intercept for method failure. In fact, it's exactly what method_missing does in Ruby and doesNotUnderstand in Smalltalk. So in other words, there are a few languages out there that already have a feature very much like this one. And while there is no standard for the naming, the convention is to imply the catching of an unhandled message. This is not at all what "invokeDynamic" implies (particularly in light of JSR-292 and the potential confusion there).It's an interesting proposal. It seems the terminology depends very much on your setup/viewpoint. Using type Dynamic it's possible to write a DynamicProxy that can call every Java object dynamically. On JDK7, the invokeDynamic method would be implemented with a invokeDynamic instruction, so in that sense the method name is right on spot. On the other hand, a DSL would implement invokeDynamic with something different.
But really, my primary focus for that feature is integration of dynamic languages, not so much DSLs. These dynamic languages usually have their own implementation of missingMethod that gets invoked when the first-line dynamic dispatch fails. So calling first-line dynamic dispatch also missingMethod would be very confusing.
I agree that calling the method invokeDynamic might suggest too strongly that this is always the same as the instruction. On the other hand, I want to keep dynamic in the name, also because the method lives in the Dynamic trait. So I think we could rename to `applyDynamic'. What do you think about that?
Cheers
-- Martin
----------------------------------------------
Martin Odersky
Prof., EPFL and CEO, Scala Solutions
PSED, 1015 Lausanne, Switzerland
Thu, 2011-01-27, 16:47
#4
Re: [scala-language] Naming of Dynamic#invokeDynamic Method
Given that the method lives in the Dynamic trait, why do we need Dynamic in the name? That sounds really redundant. Sort of like using "mapIterator" instead of "map" in the Iterator trait.
In any case, I question whether invokedynamic (the instruction) would actually be a useful implementation given the semantics of Dynamic with respect to Scala. I'm assuming you would be generating CallSite(s), well, at the call site. Thus, invokedynamic would transparently replace invocations of Dynamic#invokeDynamic. This strategy would not only rule out DSLs, but it would also be completely useless in the face of languages like JRuby (which doesn't have methods which peer directly to JVM methods). I'm hoping that I misunderstood what you meant by "implemented with an invokedynamic instruction".
All that aside, I'm not sure I agree with the analogy of invokeDynamic as the "first line" dispatch for any given dynamic language. For starters, we're not *in* any given dynamic language; we're in Scala. As such, we can't be working with the "first line" anything for any language accept Scala. In general, I think it might be more productive to think of Dynamic in terms of a fallback dispatch for Scala, one which makes it possible to write compatibility layers for dynamic languages. And there will need to be compatibility layers, since dynamic languages like JRuby have complicated dispatch semantics.
If we look at Dynamic from a Scala perspective, then the "fallback" concept seems substantially more natural from a naming perspective. Basically, it comes down to a question of precedence: if type A <: Dynamic and defines identifier foo, then some code accesses foo on type A, does that code use Dynamic to get at foo, or is it a conventional statically-determined dispatch? If the former (ie Dynamic has precedence), then invoke makes some sense as a name. However, if the latter, then the semantics are precisely the same as method_missing and should be named accordingly.
I guess my perspective boils down to the fact that we're designing a language feature for *Scala*, so that feature should be named in a way which reflects what that feature does from *Scala's* point of view. Other languages are secondary. And, by following this design guideline (Scala first for Scala features), the interop layers for other languages will be easier and more natural to design.
Daniel
On Jan 27, 2011, at 2:11 AM, "martin odersky" <martin.odersky@epfl.ch> wrote:
In any case, I question whether invokedynamic (the instruction) would actually be a useful implementation given the semantics of Dynamic with respect to Scala. I'm assuming you would be generating CallSite(s), well, at the call site. Thus, invokedynamic would transparently replace invocations of Dynamic#invokeDynamic. This strategy would not only rule out DSLs, but it would also be completely useless in the face of languages like JRuby (which doesn't have methods which peer directly to JVM methods). I'm hoping that I misunderstood what you meant by "implemented with an invokedynamic instruction".
All that aside, I'm not sure I agree with the analogy of invokeDynamic as the "first line" dispatch for any given dynamic language. For starters, we're not *in* any given dynamic language; we're in Scala. As such, we can't be working with the "first line" anything for any language accept Scala. In general, I think it might be more productive to think of Dynamic in terms of a fallback dispatch for Scala, one which makes it possible to write compatibility layers for dynamic languages. And there will need to be compatibility layers, since dynamic languages like JRuby have complicated dispatch semantics.
If we look at Dynamic from a Scala perspective, then the "fallback" concept seems substantially more natural from a naming perspective. Basically, it comes down to a question of precedence: if type A <: Dynamic and defines identifier foo, then some code accesses foo on type A, does that code use Dynamic to get at foo, or is it a conventional statically-determined dispatch? If the former (ie Dynamic has precedence), then invoke makes some sense as a name. However, if the latter, then the semantics are precisely the same as method_missing and should be named accordingly.
I guess my perspective boils down to the fact that we're designing a language feature for *Scala*, so that feature should be named in a way which reflects what that feature does from *Scala's* point of view. Other languages are secondary. And, by following this design guideline (Scala first for Scala features), the interop layers for other languages will be easier and more natural to design.
Daniel
On Jan 27, 2011, at 2:11 AM, "martin odersky" <martin.odersky@epfl.ch> wrote:
On Wed, Jan 26, 2011 at 11:16 PM, Daniel Spiewak < (djspiewak [at] gmail [dot] com> wrote:After some discussion, it seems to me that the (newly renamed) invokeDynamic method on the Dynamic trait should actually be named a bit more in line with what it's doing. As Charles Nutter points out, it's not really true dynamic dispatch, it's really just an intercept for method failure. In fact, it's exactly what method_missing does in Ruby and doesNotUnderstand in Smalltalk. So in other words, there are a few languages out there that already have a feature very much like this one. And while there is no standard for the naming, the convention is to imply the catching of an unhandled message. This is not at all what "invokeDynamic" implies (particularly in light of JSR-292 and the potential confusion there).It's an interesting proposal. It seems the terminology depends very much on your setup/viewpoint. Using type Dynamic it's possible to write a DynamicProxy that can call every Java object dynamically. On JDK7, the invokeDynamic method would be implemented with a invokeDynamic instruction, so in that sense the method name is right on spot. On the other hand, a DSL would implement invokeDynamic with something different.
But really, my primary focus for that feature is integration of dynamic languages, not so much DSLs. These dynamic languages usually have their own implementation of missingMethod that gets invoked when the first-line dynamic dispatch fails. So calling first-line dynamic dispatch also missingMethod would be very confusing.
I agree that calling the method invokeDynamic might suggest too strongly that this is always the same as the instruction. On the other hand, I want to keep dynamic in the name, also because the method lives in the Dynamic trait. So I think we could rename to `applyDynamic'. What do you think about that?
Cheers
-- Martin
----------------------------------------------
Martin Odersky
Prof., EPFL and CEO, Scala Solutions
PSED, 1015 Lausanne, Switzerland
Fri, 2011-01-28, 22:47
#5
[scala-language] Re: Naming of Dynamic#invokeDynamic Method
On Jan 27, 2:10 am, martin odersky wrote:
> your setup/viewpoint. Using type Dynamic it's possible to write a
> DynamicProxy that can call every Java object dynamically. On JDK7, the
> invokeDynamic method would be implemented with a invokeDynamic instruction,
> so in that sense the method name is right on spot. On the other hand, a DSL
> would implement invokeDynamic with something different.
You're still not doing a dynamic invocation at the call site, you're
doing a static invocation of a specific method name with a symbol and
a set of arguments. Whether the resulting target object/proxy
eventually does its own "real" dynamic invocation or not is beside the
point. Because of that I find the invokeDynamic name misleading. It's
invokeByName at best.
There's also the optimization aspect of this; since this isn't really
doing a dynamic invocation, it has to bounce through someone else's
implementation of invokeDynamic. If the same invokeDynamic is used by
multiple consumers, as in your DynamicProxy example, only the body of
DynamicProxy will inline on current JVMs (and not the eventual dynamic
call, however it's implemented). If instead invoking against your
dynamic type were actually a dynamic invocation, the resulting target
could be inlined all the way back.
Yes, this is a limitation of current JVMs. But it's a big one. See
Cliff Click's presentation from JVMLS a few years ago where he pointed
out this bouncing through a general piece of code was a primary reason
JRuby did not optimize as well as it could on their JVM. If Azul's VM
couldn't optimize it, it's probably going to be a while before any
generally-available JVM can optimize it.
> But really, my primary focus for that feature is integration of dynamic
> languages, not so much DSLs. These dynamic languages usually have their own
> implementation of missingMethod that gets invoked when the first-line
> dynamic dispatch fails. So calling first-line dynamic dispatch also
> missingMethod would be very confusing.
If you really want to get a tight integration of dynamic languages,
then a simple "by name" invocation is insufficient. You either want to
actually invokedynamic at the bytecode level, letting the target
language figure out how to wire up the dispatch, or you need to ask
the target language for some sort of method handle you then implement
in-place, which will allow it to inline properly.
I appreciate making dynlang integration better, but calling the target
method invokeDynamic is very misleading, since it isn't "invoke
dynamic".
> I agree that calling the method invokeDynamic might suggest too strongly
> that this is always the same as the instruction. On the other hand, I want
> to keep dynamic in the name, also because the method lives in the Dynamic
> trait. So I think we could rename to `applyDynamic'. What do you think about
> that?
How about invokeSymbolic? Then it's clear this isn't doing a dynamic
invocation but a symbolic one. It's also far less likely to conflict
with any existing libraries/languages that might have "invokeDynamic"
as a method already (as JRuby does in some places).
- Charlie
Fri, 2011-01-28, 23:07
#6
Re: [scala-language] Re: Naming of Dynamic#invokeDynamic Method
Hi Charles,
For me, invokeDynamic/applyDynamic is an invocation of a method where I do not know the precise method signature (or: on the implementation level: vtable entry), nor do I know whether that specific method is actually implemented on the receiver.
Cheers
-- Martin
You're still not doing a dynamic invocation at the call site, you'reEssentially it boils down to question whether I can do a direct call or need a proxy. For me, that's an implementation detail.
doing a static invocation of a specific method name with a symbol and
a set of arguments. Whether the resulting target object/proxy
eventually does its own "real" dynamic invocation or not is beside the
point. Because of that I find the invokeDynamic name misleading. It's
invokeByName at best.
There's also the optimization aspect of this; since this isn't reallyOr wrap in proxies, yes. Ideally, the dynamic language we interact with implements Scala's Dynamic type. As long as that does not happen we need to go though proxies.
doing a dynamic invocation, it has to bounce through someone else's
implementation of invokeDynamic. If the same invokeDynamic is used by
multiple consumers, as in your DynamicProxy example, only the body of
DynamicProxy will inline on current JVMs (and not the eventual dynamic
call, however it's implemented). If instead invoking against your
dynamic type were actually a dynamic invocation, the resulting target
could be inlined all the way back.
Yes, this is a limitation of current JVMs. But it's a big one. See
Cliff Click's presentation from JVMLS a few years ago where he pointed
out this bouncing through a general piece of code was a primary reason
JRuby did not optimize as well as it could on their JVM. If Azul's VM
couldn't optimize it, it's probably going to be a while before any
generally-available JVM can optimize it.
> But really, my primary focus for that feature is integration of dynamic
> languages, not so much DSLs. These dynamic languages usually have their own
> implementation of missingMethod that gets invoked when the first-line
> dynamic dispatch fails. So calling first-line dynamic dispatch also
> missingMethod would be very confusing.
If you really want to get a tight integration of dynamic languages,
then a simple "by name" invocation is insufficient. You either want to
actually invokedynamic at the bytecode level, letting the target
language figure out how to wire up the dispatch, or you need to ask
the target language for some sort of method handle you then implement
in-place, which will allow it to inline properly.
I appreciate making dynlang integration better, but calling the targetPardon me for coming from a hopelessly static corner of the world, but I don't understand most of the terminology. What's the difference between invokeDynamic and invokeSymbolic and invokeByName?
method invokeDynamic is very misleading, since it isn't "invoke
dynamic".
> I agree that calling the method invokeDynamic might suggest too strongly
> that this is always the same as the instruction. On the other hand, I want
> to keep dynamic in the name, also because the method lives in the Dynamic
> trait. So I think we could rename to `applyDynamic'. What do you think about
> that?
How about invokeSymbolic? Then it's clear this isn't doing a dynamic
invocation but a symbolic one. It's also far less likely to conflict
with any existing libraries/languages that might have "invokeDynamic"
as a method already (as JRuby does in some places).
For me, invokeDynamic/applyDynamic is an invocation of a method where I do not know the precise method signature (or: on the implementation level: vtable entry), nor do I know whether that specific method is actually implemented on the receiver.
Cheers
-- Martin
Fri, 2011-01-28, 23:17
#7
Re: [scala-language] Re: Naming of Dynamic#invokeDynamic Method
How about invokeSymbolic? Then it's clear this isn't doing a dynamic
invocation but a symbolic one. It's also far less likely to conflict
with any existing libraries/languages that might have "invokeDynamic"
as a method already (as JRuby does in some places).
I could get behind invokeSymbolic. It's certainly more accurate than invokeDynamic. However, I keep getting stuck on the fact that this is a fallback dispatch mechanism from Scala's perspective. Even if the primary purpose is dynlang integration, the feature design needs to be focused on Scala. Again, while it may be the first-line dispatch when calling into the dynlang, it's still the second-line dispatch when making a Scala call.
For me, invokeDynamic/applyDynamic is an invocation of a method where I do not know the precise method signature (or: on the implementation level: vtable entry), nor do I know whether that specific method is actually implemented on the receiver.
If we were calling that method directly, then yes, I could sort of see your point. However, the Dynamic API is not directly exposed to the call site. It's only an artifact of the receiver, which can then choose to handle it in whatever way is required (a way which may in fact be static, not dynamic). So, thinking from an API consumer's perspective (and remember, the API consumer here is the one implementing the method in Dynamic), the "Dynamic" part of the method name doesn't really make any sense.
Daniel
Fri, 2011-01-28, 23:27
#8
[scala-language] Re: Naming of Dynamic#invokeDynamic Method
On Jan 28, 4:00 pm, martin odersky wrote:
> need a proxy. For me, that's an implementation detail.
For you it is :) For any target object that wants to enlist in the
protocol, it's definitely an important detail that can't just be
brushed under the covers.
> Or wrap in proxies, yes. Ideally, the dynamic language we interact with
>
> implements Scala's Dynamic type. As long as that does not happen we need to
> go though proxies.
It will be almost impossible for most languages to do this without
yanking in a Scala dependency for all users all the time. Perhaps this
should be spun off into a common library without any language-specific
dependencies?
> Pardon me for coming from a hopelessly static corner of the world, but I
> don't understand most of the terminology. What's the difference between
> invokeDynamic and invokeSymbolic and invokeByName?
>
> For me, invokeDynamic/applyDynamic is an invocation of a method where I do
> not know the precise method signature (or: on the implementation level:
> vtable entry), nor do I know whether that specific method is actually
> implemented on the receiver.
And I'm coming from a dynamic-language-implementer's corner of the
world. :) I'll try to explain my thoughts better.
I'm primarily concerned about calling it invokeDynamic since that will
be confusing to anyone familiar with the invokedynamic bytecode and
JSR-292 work. So there's that.
My somewhat weak secondary justification is the fact that it's not
actually doing a dynamic invocation, since it requires additional
plumbing to do that invocation. In Ruby, dynamic invocation is just
how invocation is always done, so it's not necessary that anyone
implement a specific method or implicit DynamicProxy. It's handled by
the language runtime...and so we say Ruby dispatches dynamically. With
Scala's "invokeDynamic", you can't simply start using it today on any
existing object or type. Someone has to make a proxy that knows how to
do the dispatch for you, or the target object needs to implement a new
interface. The dynamic part of the dispatch is not intrinsic to the
language, not handled for you by the runtime (or compiler). You have
to do extra. All you get is dynamic-looking sugar over the static
part.
Does that make sense?
- Charlie
Fri, 2011-01-28, 23:37
#9
Re: [scala-language] Re: Naming of Dynamic#invokeDynamic Method
On Fri, Jan 28, 2011 at 11:00 PM, martin odersky wrote:
> For me, invokeDynamic/applyDynamic is an invocation of a method where I do
> not know the precise method signature (or: on the implementation level:
> vtable entry), nor do I know whether that specific method is actually
> implemented on the receiver.
I think invokeDynamic would be a reasonable name for this, were it not
already associated with the existing JSR. If you make a conscious
decision to move away from that, applyDynamic seems reasonable to me,
given the existing use of 'apply'.
I would also like folks to consider what other features of regular
Scala function application might be brought to dynamic invocations.
These seem useful, perhaps on a opt-in basis:
- argument names
- by-name evaluation
- return type other than Dynamic
Marginally useful:
- type arguments (converted to manifests?)
- sequence arguments
-jason
Sat, 2011-01-29, 11:17
#10
Re: [scala-language] Re: Naming of Dynamic#invokeDynamic Method
On Fri, Jan 28, 2011 at 11:05 PM, Daniel Spiewak <djspiewak@gmail.com> wrote:
How about invokeSymbolic? Then it's clear this isn't doing a dynamic
invocation but a symbolic one. It's also far less likely to conflict
with any existing libraries/languages that might have "invokeDynamic"
as a method already (as JRuby does in some places).
I could get behind invokeSymbolic. It's certainly more accurate than invokeDynamic. However, I keep getting stuck on the fact that this is a fallback dispatch mechanism from Scala's perspective. Even if the primary purpose is dynlang integration, the feature design needs to be focused on Scala. Again, while it may be the first-line dispatch when calling into the dynlang, it's still the second-line dispatch when making a Scala call.
But you need to see both the dynamic and static perspective. It's perfectly possible that an object that has a certain method, say, "foo", has static type "Dynamic". So statically, "foo" is invisible, but it is still present. That's why I believe that "missingMethod" is confusing. The method is not missing at all, it's just invisible for the static typechecker. If you want a painfully long name you could pick "methodStaticallyInvisibleNowTryAppliyDynamic", but I believe we all prefer "applyDynamic" over that.
Cheers
-- Martin
For me, invokeDynamic/applyDynamic is an invocation of a method where I do not know the precise method signature (or: on the implementation level: vtable entry), nor do I know whether that specific method is actually implemented on the receiver.
If we were calling that method directly, then yes, I could sort of see your point. However, the Dynamic API is not directly exposed to the call site. It's only an artifact of the receiver, which can then choose to handle it in whatever way is required (a way which may in fact be static, not dynamic). So, thinking from an API consumer's perspective (and remember, the API consumer here is the one implementing the method in Dynamic), the "Dynamic" part of the method name doesn't really make any sense.
Daniel
--
----------------------------------------------
Martin Odersky
Prof., EPFL and CEO, Scala Solutions
PSED, 1015 Lausanne, Switzerland
Sat, 2011-01-29, 13:57
#11
Re: [scala-language] Re: Naming of Dynamic#invokeDynamic Method
On Fri, Jan 28, 2011 at 5:22 PM, Charles Oliver Nutter <headius@headius.com> wrote:
On Jan 28, 4:00 pm, martin odersky <martin.oder...@epfl.ch> wrote:<snip/>
<snip/>
> Or wrap in proxies, yes. Ideally, the dynamic language we interact with
>
> implements Scala's Dynamic type. As long as that does not happen we need to
> go though proxies.
It will be almost impossible for most languages to do this without
yanking in a Scala dependency for all users all the time. Perhaps this
should be spun off into a common library without any language-specific
dependencies?
I think this is a huge point that we shouldn't miss. If we want to interop with dyn languages on the JVM, the 'core' library should consist of a single/set of standalone interface(s) that dyn languages can pull in as a separate JAR dependency. This dependency could be small and simple and gives us a decent migration strategy where the dyn-lang interface wouldn't be easily broken by new scala-libraries.
On Jan 26, 4:16 pm, Daniel Spiewak wrote:
> I propose that we rename invokeDynamic (again) to something slightly more
> indicative of what it is doing. I'm a Ruby guy, so methodMissing strongly
> appeals to me, but I would be ok with almost anything which hints at what is
> really going on (rather than implying something that it is not).
There's another precedent in Groovy, which calls the same feature
missingMethod (I suggested they add methodMissing some years
ago...they did, but I'm unsure why they reversed the word order).
The confusion with "real" dynamic invocation and JSR-292 concerns me
as well. To me, dynamic invocation does not require that the target
object implement specific behavior in order to participate.
methodMissing does, specifically to support callee-driven symbolic
invocation.
Another example why this isn't "real" dynamic invocation is from C#.
In C#, the "dynamic" type is used not for callee-driven symbolic
invocation, but as a hook into the Dynamic Language Runtime, which can
handle any arbitrary object/type. In some cases, the objects
themselves do implement basic lookup and optimization mechanisms to
aid dynamic invocation, as with IronPython and IronRuby. But that's
not a prerequisite for "dynamic" invocation, and the DLR will happily
route dynamic calls from one static type to another static type
without either of them implementing any special logic.
- Charlie