This is specially useful for options that are not used near the entry point, but instead are passed down. If the later implementation changes, you'd have to change the middle implementation as well to accept the new/different types.
Or, getting back to C++, we have polymorphic lambdas there now (which are implemented in terms of templates, but with syntactic sugar that makes it all much cleaner):
auto f = [&](auto x, auto y) {
return x + y;
};
cout << f(1, 2); // 3
cout << f("a"s, "b"s); // "ab"
cout << f("abcd", 2); // "cd"
cout << f(main, true); // compile-time error
Again, all statically typed, although the type checking basically consists of substituting the types in the body and checking if the result makes sense. Which is to say, the error messages from such code are very similar to the ones you get in e.g. Python if you have the types wrong, except here the errors are compile-time, not runtime.- type of Agg object passed into object
- type of "algorithm" used (or similar)
I read matplotlib's Agg C++ backend. Guessing which Class A could be passed into various template parameters in Class B was miserable because of duck typing. And it also broke "jump to definition".
``` Class B<A> { A a; } this->a.foo(), but you don't know what type a is. ```
Is that really true? whether the original declaration is strongly typed or not, its likely that changes to the type will result in code changes needed wherever the value is being used.
The only thing that no typings does is make it impossible for the compiler to help you find where it is being used.