The problem is that for .NET wrapper objects, we’d face the same problem: We don’t know which script the call comes from. These objects would be passed around, and I don’t believe we’d get a chance to switch wrappers between script boundaries.
Just imagine this (admittedly extreme) example:
Script 1 (referencing assembly A):
obj.bar() // should invoke bar() as defined in assembly A
foo (lambda x: x.bar())
Script 2 (referencing assembly B):
def foo (method):
obj.bar() // should invoke bar() as defined in assembly B
method (obj) // should invoke bar() as defined in assembly A, since the lambda expression was created in Script 1.
I don’t see a way to solve this problem without support from the DLR or the script language.
On the other hand, being dependent on a script context does not sound all that scary to me. At least no scarier than watching your carefully tested scripts break in production, and getting error reports from users for unforeseeable situations.
This could be a feature that’s fine to use even without mixins, so I’ll restrict the discussion to explicit interface implementations. In fact, similar mechanisms could even be used for other ambiguity cases.
Consider a script developer who’s writing a script on their own PC, where any number of assemblies is installed. The script developer therefore knows only the types defined in those assemblies. Now we can follow two schools of thought:
a) This is a dynamic language, so whatever the script developer saw while they were developing doesn’t matter.
b) The script developer was scripting for e known environment, and what executed once should execute too in environments that have other assemblies too.
(We could even argue that the script developer should be able to restrict access to a certain set of assemblies that are of interest to them, very much like “add assembly reference” in C#. A call to a method defined in another assembly should then always fail,
even if it could unambiguously be resolved on the script developer’s machine.)
Considering any environment that uses DLR languages for application scripting, we have a potential problem of breaking code when 3rd party add-ins are loaded at run time. Option b) would free the script developer from worrying about that, and it would free
the admin of the deployed system from manually resolving ambiguities in script source code. This would give us the option to take the best of dynamic languages without the horror of PHP applications, where you end up modifying scripts at deployment time (effectively
branching the code).
Now I see that this might seem like a very un-dynamic approach, but it would be of real value to any dynamically extensible system that uses the DLR for scripting in the context of deliverable modules (e.g. workflow activities).
I’m not sure if this is important enough to make it into the DLR or any DLR language (although scripting in large applications with plugin-models seems to be a sweet spot for both), but any mechanisms that would allow us to create this behavior ourselves
would be very welcome!
I’ve seen some classes in the DLR source that look like they could provide the necessary context (ScriptDomainManager, LanguageContext, Scope), but they don’t seem to get passed around enough. Or is there a way? Then any hints would be welcome, of course.
What do you think?