I don't have much experience with statically typed languages (currently learning Scala and loving it!) but one thing I've noticed is that they don't ever seem to have anything like Ruby's method_missing or ColdFusion's onMissingMethod. Is there some inherent limitation in statically typed languages that prevent or make this difficult?
views:
288answers:
4Certainly a mechanism for handling them could be added, but it is at odds with what static typing is: Compile-time determination that your program is free of type errors.
In statically typed languages, member functions are invoked directly. If the compiler cannot figure out which member function to invoke, the program will not compile. Method invocation is, in this sense, static.
In dynamically typed languages, member functions are not invoked directly. Rather, calling code sends a message to an object, and then the language runtime figures out what to do with that message. For example, the runtime will scan the object for a method with the same name, and then will scan the object for a method with the name method_missing
. Method invocation is, in this sense, dynamic.
C# 4 combines static typing with dynamic typing. An variable may have a compile-time type of dynamic
. Any method invocations on this variable will be handled as in dynamically typed languages. Any method invocations on variables with static types will be handled as in statically typed languages.
# static invocation, bound at compile time by the compiler
var s = 6;
s.ToString();
# dynamic invocation, handled at runtime by the CLR
dynamic d = 6;
d.ToString();
Just to further Randall's post, it is possible, but the reason it goes against the static paradigm is that it's beyond "dynamic dispatch". Dynamic dispatch happily lets you dispatch to a function that is dynamically bound to a known static piece of code. i.e. the compiler sets up the dispatch that is deterministically executed at runtime, from its perspective.
What the method_missing
call does, is essentially make a "catch all" where you decide what to do based on the method name using a switch statement, or something equivalent (which I'm sure you know). Thus, the compiler has no idea what's going to happen here. Let's say the compiler did something like:
if (function is known at compile time)
{
provide static call or dynamic call to "some" derivation
}
else
{
bind the function call to obj.method_missing(...) and pass in the "details"
}
Then you have to provide method_missing
like this:
def method_missing(intendedFunctionName, arguments)
{
if (intendedFunctionName is "X")
{
X may not need arguments, so just do something
}
else if (intendedFunctionName is "Y")
{
Y expects 5 arguments of varying types
Throw exception if there isn't the right number or types
}
... etc ...
}
Asking the compiler to send you "arbitrary" (i.e. not known at compile time) arguments of arbitrary types, with an intendedFunctionName
that you may not be accounting for... well, it's not very safe, and Scala is intended to be a statically safe language.
Yes, it's doable but not in the spirit of a static language. If you really want that type of flexibility, polyglot programming is probably your friend.
Note: Objective-C is not strictly statically typed. There is a runtime engine on which the code executes and the dynamic typing system does not allow code to be stripped or inlined like C/C++.
Objective-C has "method_missing" (specifically, forwardInvocation and methodSignatureForSelector) and it is arguably statically typed. This works because it will treat static type errors as warnings rather than errors at compile time, since method dispatch occurs at runtime to a much greater extent than something like virtual methods in C++ (and this is why you can have "method_missing").