The cheating comes from the run-time compilation features being leveraged to inspect "already compiled" code and dodge around the dispatch. However this causes problems in larger systems (Julia has some serious shortcomings when it comes to large projects, and they ban people who talk about it too much) because if you add a method to the multiple dispatch already compiled functions won't make use of it without recompiling them too, this is basically the expression problem being displayed in a dynamic language (because they choose speed over true dynamicism; they leverage the dynamic features for a different purpose and loose the feature typically gained). This is a very bad form of cheating because multi-methods are often seen as a solution to the expression problem, but Julia still has the problem even though they use multi-methods.
Try the following:
# Library
abstract bar
ex(x) = println("dynamic")
ex(x::bar) = println("bar")
test(x::bar) = ex(x)
type foo <: bar
x :: Int
end
test(foo(5))
# Now our code
ex(x::foo) = println("foo")
test(foo(5))
It should print `bar\nfoo` it doesn't.