Just Another Victim of the Ambient Morality wrote: > By "it's a reduction ad extremum of a way of constraining object > behaviour" do you mean that it reduces object behaviour in an extremely > non-constraining way? Yes. In the object-message interpretation of OO, it means an object only needs to respond to the messages absolutely required in a context to be qualified to be of the valid type. > With statically typed languages, the behaviour of an object is defined > by membership. If this variable is a member of this set, then it may have > these properties. So, when a function requires that a parameter be of a > certain type, it must be a member of this certain set. The use of other > types that may also work in this function but are not in this set are > (arbitrarily) excluded. > With dynamically typed langauges, because variables (including > parameters) may be of any type, parameters passed into a method will work > as long as they, literally, satisfy the requirements of the method. This > is much more flexable than defining arbitrary membership. It's "ad > extremum" in the direction of flexability. Unfortunately, it's also > flexable enough to allow you to pass a totally inappropriate parameter into > a method but that's the trade off. Is it worth it? Most of us think so... > <pedant> *flexibility </pedant> As Chad Perrin pointed out, you leverage the benefits of dynamic typing in the special / edge cases rather than the common case. If you poked around Ruby libraries, you'd find out at least several, if not many cases when the libraries perform strong type checks on objects passed into them. And for what it's worth, I personally don't see a problem with this. It makes the libraries easier to document, easier to understand, and behave more predictably. Ruby -allows- you to use (and abuse) dynamic typing, noone's saying you need to code to allow for it. I would personally advocate the opposite, write predictable code most of the time, and then do parts of it that could benefit from the dynamism by design - since they will be inherently more error-prone, they require a lot more effort to be written in a robust maintainable way. > If you want an example you can use in the future, how about a function > or method that takes a vector and a list of vectors and sees if the given > vector can be expressed as a linear combination of the list of vectors. > Because so many things have vector properties (real numbers, complex > numbers, Cartesian vectors, matrices, real valued functions, almost > anything, it seems), you can reuse this function or method with any of > these types! How amazing is that? Interesting example there. Of course, I'd personally formalise the vector properties somehow, at least in documentation. You want these vector properties to manifest themselves in the different types of objects in a consistent way, and this is a constraint on the parameters of the function already. And in good-quality code, you want to check on whether the constraint is satisfied and fail early if it doesn't. Even dynamic / duck typing isn't completely eschewing type checks, even if you can get away with that for spectacularly long. And the problem is that expressing the parameter constraint with "is a Vector" is a little clearer than "has vector properties". It's not -that- apparent in this example, but for more complex ones, where you need a larger set of behaviours from the function parameters, the formal granular constraints on them would be very verbose and hard to understand. Having "ubmrella" concepts that are readily understood is very helpful in that case. And the path between concept and code is sometimes a very short one - having a mixin Vector module with documented methods that you expect from an object "with vector properties" and some helper methods you'd use would probably be my first move after making a vector manipulation library with the dynamism you describe. David Vallner