Fair point, although R's multiple dispatch barely counts as a language feature at all, but is really more of a standard add-on library (read on). All S4 is doing is using a hash table keyed by method signatures to look up which function body to call. You don't even need any syntactic support since "defining a generic function" is just a matter of defining a function that does a hash lookup and then applies that function to its arguments. R doesn't provide any syntactic support for adding methods to generics – you literally have to give it a vector of strings of argument class names. Since you can do all of this in any language – even C – it's arguable that multiple dispatch isn't really part of "the R language" at all, but rather "the R system" happens to ship with a standard implementation of hash-based multiple dispatch and a few of the built-in function like "show" and "plot" are defined using it.
Due to not being a deep language feature, S4 lacks some crucial abilities. It doesn't support any sort of type hierarchy besides the special "ANY" class. Without the ability to define a type hierarchy and program to abstract types, most of the power of multiple dispatch evaporates. Even though it is technically an implementation detail, I've found that performance is a critical feature for multiple dispatch to really come into its own. R's S4 dispatch has been described as "slower than S3" [1] – and S3 dispatch is not exactly fast. Unless really basic things like + and array indexing can be generic and usably fast, you're not really cooking with gas.
[1] http://www.r-project.org/conferences/useR-2004/Keynotes/Leis...