There's nothing about dynamic typing that prevents declaring types right? Because in Ruby you while you can extend an instance, you can not taketh away Types from it.
IOW, Ruby could use the Scala syntax I wrote, and still be just as Dynamic. You're already constrained by how you use that type within your method. You're just not expressing it concisely since you have to read the method to understand the implicit Type it's operating on.
In practice a lot of this gets naturally conflated though. Which I think you were getting at.
But if we're going to limit ourselves to functions with undeclared types, I guess I'd point to Clojure's partial as something you can't really express with Ruby. Or Pattern Matching in Elixer.
Well, Ruby is duck-typed with dynamic/late dispatch, so method receivers are not known ahead of time. When I call `foo.bar`, it does a dynamic lookup in the class hierarchy at runtime to see which class implements the `bar` method, and the result can be changed at runtime. So although you could theoretically declare types in Ruby, it would just be documentation. You'll still get the type errors at runtime because there's no ahead-of-time typechecking happening.
With Clojure you can actually compile your modules while developing them and discover certain classes of type errors ahead of time, so something like core.typed actually makes sense because you can run the typechecker over your code instead of having to run a separate test suite.
The main type error you always have to worry about in both languages, though, is accidentally calling functions/methods on nil at runtime. Of course that applies to null in Java too...
> You'll still get the type errors at runtime because there's no ahead-of-time typechecking happening.
That doesn't mean it's just documentation though. It could tell you that something is happening you didn't expect. Like passing a Role where you expected a User. (And if you wanted to operate on both interchangeably you shoulda put an interface on it.)
> The main type error you always have to worry about in both languages, though, is accidentally calling functions/methods on nil at runtime.
Agreed. Option/Maybe types FTW. The ?-operators sometimes presented as a solution feel very half-baked in comparison (they don't return a new type so just because you remembered to use it on line 10 doesn't mean anything to lines 20, 37 and 82).
IOW, Ruby could use the Scala syntax I wrote, and still be just as Dynamic. You're already constrained by how you use that type within your method. You're just not expressing it concisely since you have to read the method to understand the implicit Type it's operating on.
In practice a lot of this gets naturally conflated though. Which I think you were getting at.
But if we're going to limit ourselves to functions with undeclared types, I guess I'd point to Clojure's partial as something you can't really express with Ruby. Or Pattern Matching in Elixer.