Hacker News new | ask | show | jobs
by tomp 5567 days ago
This article is full of FUD and completely misses the point of static/dynamic distinction (flame-war, if you want). It's a perfect example of someone arguing to make a point without even trying to understand the opposite position.

No one has ever argued that dynamic languages are more expressive than static languages. This is impossible, as long as we're considering Turing-complete languages. The fact that Harmony/EcmaScript 5 reference compiler was implemented on OCaml. However, it is equally futile to argue that they are less expressive[1].

"you are imposing a serious bit of runtime overhead to represent the class itself [...] and to check [...] the class [...] on the value each time it is used."

Users of dynamic languages simple trade runtime efficiency for compile-time efficiency. What's wrong with that?

The point of having multiple languages is that different languages make different things simple and easily expressible. Sure, you can do dynamic programming in Haskell or OCaml, but the language is going to work against you in some way, requiring you to specify your intension in a particularly lengthy and awkward way (think Java, except Java makes you do that for any kind of programming).

[1] Ironically, the author fails to point out the one way in which static languages are more "expressive" than dynamic languages: overloading on function's return type. I have yet to see that in a dynamically typed language.

tl;dr: All Turing-complete languages are equally expressive, but different languages make different things simple.

2 comments

I have not used dynamic languages enough to know what I say before for sure, but this is my current understanding:

>> No one has ever argued that dynamic languages are more expressive than static languages. This is impossible, as long as we're considering Turing-complete languages.

As I think you note in your last sentence, "expressive" here is not meant to imply whether something can be expressed in the language or not. It's rather about being able to express the concept in the language in a way that is no more or less complex than the concept itself, and expresses no more or less than the concept itself. So the Turing-complete argument does not really apply. (John McCarthy in fact had to say the same thing about Tuning-machines themselves -- that while they help to understand limits of any machine, for AI programs they are at too low a level to help real humans build new insights into AI beyond understanding those limits.)

>> Users of dynamic languages simple trade runtime efficiency for compile-time efficiency. What's wrong with that?

1. A program is run more times than it is compiled (hopefully). So the goal is really to make the effective combination of the two more efficient in a given usage scenario. On the other hand, with a dynamic typed language, if N seconds are shoved away from compilation, at least N seconds will be added to run-time.

2. The bigger issue I have is that dynamic languages often turn compile-time "errors" into run-time errors. Run-time errors take longer to detect and correct and the process of doing so is bound to see less automation. This is not to say of course that dynamic typing is always an issue.

> 1. A program is run more times than it is compiled (hopefully). So the goal is really to make the effective combination of the two more efficient in a given usage scenario.

You're not counting development time, or rather, cost.

Even if I eventually need the efficiency of a statically typed language, dynamic languages let me save the time that I would have spent satisfying the type checker on code that didn't make it into that version.

> On the other hand, with a dynamic typed language, if N seconds are shoved away from compilation, at least N seconds will be added to run-time.

It's unclear that that's true. In fact, the cost of compile-time type checking is typically more than the cost of run-time type checking during much of development.

> Run-time errors take longer to detect and correct and the process of doing so is bound to see less automation.

Run-time errors aren't detected until run-time but since folks with dynamic languages get to run-time faster, they're often detected earlier.

As to "less automation", I don't see it. Do you have an automated system that corrects type errors?

I partly agree to what you said, but just for sake of completeness:

>> Even if I eventually need the efficiency of a statically typed language, dynamic languages let me save the time that I would have spent satisfying the type checker on code that didn't make it into that version.

This conversion does not sound so trivial to me generally. At times converting from a dynamic language to a statically typed language requires either a change of code architecture or a massive refactoring operation.

>> Do you have an automated system that corrects type errors?

Not corrects, just detects. I have at times faced issues when code runs for half-an-hour and then crashes just because a the given object could not be converted to the needed new type at run-time. My reaction: "Sigh! I wish the compiler told me earlier during compile-time!"

> This conversion does not sound so trivial to me generally. At times converting from a dynamic language to a statically typed language requires either a change of code architecture or a massive refactoring operation.

I didn't claim that it was necessarily trivial. However, I'm happy to claim that it is very rarely required. What is it that they say about premature optimization?

That said, I think that you're overstating the amount of work. As our python friends keep demonstrating, the amount of code that is actually performance-critical is usually fairly small and can be handled by special means once you get things relatively stable.

And, when it is required, it may be an indication of massive success. If you wrote the first version, said massive success may make the conversion someone else's problem. :-)

> Not corrects, just detects. I have at times faced issues when code runs for half-an-hour and then crashes just because a the given object could not be converted to the needed new type at run-time. My reaction: "Sigh! I wish the compiler told me earlier during compile-time!"

No optimization produces speedups in every situation.

As to that particular problem, I develop in dynamic languages so I "never" have that problem after a significant amount of run-time.

To me, it's important to remember that dynamically and statically typed languages give you different rope with which to hang yourself, so it's best to program with that in mind.

To put it another way, it is generally agreed that it's a bad idea to write fortran in other languages even though it is possible. Why would you think that it would be a good idea to write static in a dynamic language or the reverse?

About your [1] ... dynamic languages can support multimethods (i.e. method overloading on steroids) so I don't get how a dynamic language can't do overloading based on return type.

The difference between a static and a dynamic language would be when this dispatch is made (compile-time versus runtime).

Overloading on return type is fundamentally impossible in dynamic languages, since they dispatch on values, and the return value can not be known before the function is called.
Oh come on, all you need to do is to (OPTIONALLY) tag the function with the return type.

And it's still a dynamic type system ;)

Well it's not impossible. You could run them all and then decide which result to use. :)
That doesn't work either, since then you will have more than one result. Which one will you dispatch on?
Presumably, you'll have some rules that determine which is the best match and then error if it's ambiguous - just like the static case