Dynamic is the opposite of Static, not of Explicit
I recently read a post where the author said he does not care for Ruby's dynamic typing.
When people start talking about types in programming languages, the terms fly around in a rather fast and loose manner. Here's a rather extensive and balanced discussion: the article on Type Systems
Notice that Ruby is dynamically typed
(it's types are determined at run time and can change at run time), strongly typed
(it does not allow an operation to succeed on arguments which have the wrong type), and type-safe
(it does not allow operations or conversions which lead to erronous conditions).
(There's another school of thought about how to name the properties of type systems. More on that at the bottom.)
Proponents of explicit types
may say that Ruby is not type safe because it is possible to compile programs that contain errors which will not be detected until the program is run and the erroneous condition is detected.
Statically typed languages such as C# can detect a class of such errors at compile time. Some Ruby enthusiasts argue that they do not like the boilerplate associated with explicit typing and feel that the extra error checking does not outweigh the additional overhead.
Both arguments are mistaken. Sorry about that. If Explicit and Implicit were the issues, we could add Type Inference
to Ruby and it would have the low overhead of implicit types as well as some extra error-checking (work on Soft Typing for languages like Scheme and Erlang aims to provide compile-time checking for implicitly typed languages). However, type inference is a feature of statically
The trouble is that Ruby is dynamically
typed. Specifically, Ruby contains extensive dynamic meta-programming
constructs. Type inference works with statically typed languages. The compiler must be able to infer the type or set of types possible for any variable.
Consider a Ruby application that modifies classes and objects at run time. The simplest example is Ruby's built-in accessor methods: attr_accessor :foo
is a class method that actually creates two instance methods at run time, foo
. What happens when attr_accessor is called with a variable
as its argument, like attr_accessor my_attribute
If the type inference engine later looks at a call such as bar.blitz = 'bash'
, how does it know whether attribute_accessor was ever called with 'blitz' or :blitz as an argument? Dynamic meta-programming makes the type inference problem undecidable.
A lucid argument is that Ruby's dynamic typing makes it difficult to detect type errors statically. The correct
counter-argument is that Ruby's style of dynamic typing makes it possible to use dynamic meta-programming, such as Ruby on Rails
' ActiveRecord, not that Ruby's implicit typing is more productive.
Once you've made these arguments, you can decide for yourself whether the benefits of dynamic meta-programming do or do not outweigh the advantages of static type checking.
(Updated to use the expression "dynamic meta-programming" to distinguish features like define_method
from static meta-programming features like macro systems, courtesy of the well-informed Lambda the Ultimate
finp.s. Ward's Wiki seems to use the term static typing to mean the same thing as explicit and strong typing. I prefer that the term static means that it doesn't change. The same wiki seems to use the term dynamic typing to mean the same thing as implicit and strong typing. It includes the possibility that a program is what I would call strongly, statically and implicitly typed: the checking is done at run time but the types of variables never change. The commentary suggests the phrase semantic dynamic typing for the quality of dynamic typing that encompasses dynamic meta-programming. If you like these terms, please substitute "semantic dynamic typing" for "dynamic typing" above.p.p.s. And there's another argument that dynamic meta-programming, like macros, should be considered harmful. I'm saving my reply for a rainy day.
Labels: lispy, ruby