Tuesday, March 04, 2008 4:55 AM
mmaly
Dynamic Sites
I am still working on answering the 2nd question. In the previous post and the one before that I answered most of it, but there is one more thing to address:
Problem Two
What if the language syntax doesn't provide good guidance for the placement of the dynamic operations. There are cases where syntax just doesn't provide enough information, for example when the dynamic operation needs so happen in a library function. What then? there is no way to create ActionExpression and let DLR do the code generation which will create DynamicSite and jump start the whole magic...
This last detail is quite easily answered, luckily. We can, in our library function, do the same magic that DLR does via code generation, except we'll do it by hand. To stay with the same example (formatting for output), we can build our function "Print" in a following way where we have an instance of dynamic site manually created and the Print function simply invokes it...
// The instance of the dynamic site used by the "Print"
// method to format the object for output
private static DynamicSite<object, string> _formatter =
DynamicSite<object, string>.Create(
DoOperationAction.Make(Operators.CodeRepresentation)
);
// The Print built-in function
public static void Print(CodeContext context, object o) {
// Invoke the dynamic site
string formatted = _formatter.Invoke(context, o);
// print
Console.WriteLine(formatted);
}
Same machinery will kick in as in all the cases we explored so far, the only disadvantage here is that the same dynamic site is shared by all calls into the "Print" method instead of just being shared by all calls that happen at the same location in the source code.
DLR uses this trick internally, you can check out the DynamicOperations.cs for many real world examples. And same goes for Python (Converter.cs, Builtin.cs, PythonCalls.cs, PythonSites.Generated.cs and many more).