A simple example
Consider the simple factorial function (grabbed from scipinclojure.com) :
The coolest thing about this function is highlighted here in red - we internally define a function inside of the factorial function. This "iter" function could then be a parameter to the factorial function if, for example, we wanted to somehow optimize it. In a structured language (like java, for example), this would require more syntax. But the syntax has an upshot - it prevents us, at compile-time, from replacing "iter" with a function which did not properly support the overall purpose of the factorial function..... And so the circular dynamic vs. static debate goes ....(define (factorial n) (define (iter product counter) (if (> counter n) product (iter (* counter product) (+ counter 1)))) (iter 1 1))
Reconciling the circular debage : the tradeoff
Its pretty simple : lets be honest, in a structured language, we trade off expressiveness for robustness - it is harder to write completely disfunctional code in java than in Clojure , or LISP, or even Python. Thus, a language like java is more robust then the latter, more dynamic languages.
In an ideal world : dynamic languages are probably better.
Why do we care about robustness ? Shouldn't we trust ourselves NOT to write meaningless code ? Shouldn't we trust ourselves take responsibility to UNDERSTAND how our factorial function works before parameterizing and extending it ? If yes, then dynamic languages win . They are easier to comprehend and read once we understand the syntax... Thus, in a perfect world where all programmers were proactive, smart, and actually interested in understanding the consequences of their actions, dynamic languages would probably "win out" over lower level languages.
Thats why the best programmers like languages like Ruby, Clojure, etc.... It gives them the freedom to write truly abstract, reusable, elegant code.
The scary truth : Java programmers "bend" the rules to make the JDK dynamic.
And what about the rest of us ? Those of us who, for example, are not allowed to use dynamic languages at work ? We learn about the java Class API. We learn about metaprogramming on the JVM. We ultimately "turn" java into a dynamic language, by hacking it. Another solution to the "iter" problem might be, for example, defining the iteration function in a string. There are java libraries that do this like beanshell & rhino & meval & ... Meanwhile, with tactics like reflection and dynamic class loading, we have other avenues for introducing dynamic behaviors into our source code.
So, ultimately, even Java is (sort of) a dynamic language, if you know it well enough to take advantage of the hidden "dynamicable" elements . . . And for that matter, the most popular language in the world (the shell) is dynamic to. In fact, its REALLY dynamic when you think about it.
So I'm starting to think that, at the highest levels, all languages are dynamic. And compile-time type safety is but a myth which holds us back less and less as we get older. Im starting to think compilers give us a false sense of security.
Really interesting post. I'm curious to hear what you've been doing recently that led you to write this.
ReplyDeleteDealing with type safety issues , broken parameters that
ReplyDeleteAre simply objects, and looking at the way joining works in hadoop - and also
Been reading more of SCIP.... Of course.
I kind of think the opposite: that in an ideal world, static languages are better. But as practical, real-world programmers we run into lots of issues that are just a pain to solve with static typing, but extremely easy to deal with in a dynamic language. But I agree that static languages make it harder in a lot of ways to write complete garbage.
ReplyDelete