
Dynamic Languages Are Static Languages (2011) - mlitchard
https://existentialtype.wordpress.com/2011/03/19/dynamic-languages-are-static-languages/
======
Others
While the core theory of this article, that dynamically typed languages are
just statically typed languages with just one type, is correct, its extensions
are questionable at best. It tries to claim that it is somehow restrictive to
have only one type. That is nonsense, anyone has sat down and tried to write
code in both Python and Haskell can tell you it is much harder to get the
Haskell compiler to accept your code. Now having such a strict compiler is
great sometimes, and having a more forgiving compiler like Python's is also
great soemtimes. But that observable forgiveness makes it obvious why it is
silly to claim Python programmers are struggling against "the bondage of
restricting attention to a single type."

~~~
merb
Also Python seems to look like a dynamic language, but it isn't. The type
system is really not as easy as the most other interpreted languages.

~~~
curun1r
Don't confuse static/dynamic with strong/weak. Python is strongly typed, but
it's still dynamic.

~~~
zzalpha
FYI: None of those terms actually mean anything.

Or, more accurately, they mean different things to different people.

There's unfortunately very little in the way of standardized vocabulary for
discussing this topic in a meaningful way. My theory is that this reflects the
religious nature of the discussion.

------
niccaluim
Having gone back and forth between statically and dynamically typed languages
a few times now, I have to say that this comment sums it up for me:
"expressing and enforcing invariants in the program itself is so helpful that
it’s just ludicrous to deprive yourself of them." It's the single biggest
problem I have when I work in a "unityped" language.

~~~
aero142
I've gone through the same transformation but I think you aren't appreciating
the larger picture. Having the ability to specify both compile time and
runtime invariants are both useful features. Java is good at expressing
invariants around datatypes that looks like hardware data storage but it is so
restrictive around interfaces that it is easy to paint yourself in a corner.
Since Java was the mainstream typed language, people saw what could be done in
languages like Python without such enforced rails, that many people decided
the expressiveness was worth the tradeoff. I think Java 8 is much better about
the tradeoff, but ultimately I think we haven't invented the system for
expressing invariants in a language that makes the best tradeoffs between
expressiveness and flexibility.

------
rhaps0dy
This is not exactly the point the article talks about, but it's irked me for
quite some time. When you see the documentation for a library in a dynamic
language, it looks the same as if the language was static: the class of all
the arguments and what the functions return is specified. So in the end you
end up using it just like you would a static language, but with all the type
checks done at runtime instead of before.

This doesn't make much sense if you want to avoid errors.

~~~
svachalek
That's an overly broad generalization, and doesn't line up with my experience.

For example I don't see much about "classes" in MDN:

[https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/parseInt)

[https://developer.mozilla.org/en-
US/docs/Web/API/Window/loca...](https://developer.mozilla.org/en-
US/docs/Web/API/Window/location)

~~~
jameshart
"Window.location returns a _Location_ object" "you can also assign a
_DOMString_ to it" "The parseInt() function parses a _string_ argument and
returns an _integer_ " "If string is not a _string_ , then it is converted to
one"

Seems like this documentation talks about little else than types to me?

~~~
gorena
> "The parseInt() function parses a string argument and returns an integer"

This seems... factually incorrect? Shouldn't it say "a double"? (or a
"number", which just means "double" in JS)

It might ignore any characters after a ".", but it's impossible to return an
integer in JS...

~~~
chc
No, it returns an integer. ECMAScript doesn't officially have a distinct
integer type, but the number returned will still be an integer. Incidentally,
most JavaScript implementations actually do have an internal integer
representation, even though typeof will still just say it's a number.

------
kelvin0
I like the fact that interpreting subjectively what 'Dynamic' and 'Static'
means for a language, the author is able to pull a rabbit out of his
proverbial hat ... except that we see the hole beneath the hat, and the rabbit
is a dead rat. Clearly programming in Python vs C++ is a world apart in terms
of how 'fast' you can get simple things up and running.

~~~
rhaps0dy
The author specifically says C++ is too restricted, and that it makes no
distinction between the "class" and "type" the author is talking about.

C++ has no sum types (afaik, the language is so huge I might very well be
wrong)

~~~
kelvin0
Be that as it may, the tone of the article is clearly written 'looking down'
at the readers, and tries to rack up some points by showing 'how smart I am
(author) to be able to correct most of you...'. If he simply described that
the definition of the terms, with some examples and then lead into his point
to correct the 'popular' assumptions, it would have been a lot better than
feeling like you're being lectured from the pulpit on a Sunday morning.

------
mordocai
The author's stated reasons for why dynamic languages are used may be valid (I
use them because the type of job I like to get usually does) but there are
real advantages to them.

It is much easier to quickly prototype or experiment in a dynamic language.
Note that I am thinking versus a language like Scala or Haskell where types
are a integral part of the language. This applies less to languages like Java.
You don't have to stop and figure out your types for every function and then
go back and change them every time you figure out there is a better way to
represent the data.

That being said, I get their 'Dynamic Languages really just have one type'
argument. I understand what they are saying. Doesn't mean we can't still use
the term dynamic to describe such languages. Words mean whatever we(as a
group) want them to mean.

~~~
mlitchard
"It is much easier to quickly prototype or experiment in a dynamic language."

I disagree. I can say what I mean with types, and if I didn't mean what I
said, refactoring is a breeze.

"You don't have to stop and figure out your types for every function and then
go back and change them every time you figure out there is a better way to
represent the data."

You don't have to do this in languages like Haskell either. Type inference
will help you most of the time when figuring out a function's type, and you
don't have to use the type system as it was intended at first. You can have a
prototype with Strings and Lists, the compiler won't be able to help you much
though.

~~~
falcolas
While Haskel has quite a few tools to help assuage issues like this, I can't
help but think that niche tools do not define the genre. When I hear
"statically typed", I don't think of Haskel, I think of C, C++, Go, Java, and
Rust.

All of these languages offer tools to handle similar duck typing via
interfaces or traits or polymorphism, but they are far from simple to use.

When Haskel gains a mindshare outside of its current niche, or the type
inference becomes more broadly implemented in languages used across our
industry, then let's talk about how it makes statically typed languages better
and easier to use than "unityped" languages.

------
haberman
You can apply this same idea to serialization formats. JSON doesn't have a
schema. On the other hand, you can think of all JSON values as belonging to
this Protocol Buffers schema:

    
    
        message JsonArray {
          repeated JsonValue value = 1;
        }
    
        message JsonObject {
          map<string, JsonValue> properties = 1;
        }
    
        message JsonValue {
          oneof value {
            JsonObject object_value = 1;
            JsonArray array_value = 2;
            bool is_null = 3;
            bool boolean_value = 4;
            string string_value = 5;
    
            // Represented as a string because JSON doesn't restrict the
            // range/precision of numbers.
            string number_value = 6;
          }
        }

~~~
girvo
So, this is something I've been thinking about recently: do you gain much by
using Protocol Buffers (et al) for a client-side web application's
communication with a server? Having JSON/XMLHttpRequest in the browser by
default is such a boon that it'd have to be a lot better as a serialisation
format for it to be worth it, but that might actually be the case?

------
logophobia
This article feels a bit condescending. Like most things, it's a trade-off.
While sophisticated types do have a lot of advantages over dynamically typed
languages (I spend most of my time using languages like that), that doesn't
mean there's no trade-off.

Dynamically typed languages are, in my opinion:

* Simple

* Typically require less design upfront

* Easier to get started with

There's real value in that. Perhaps not for the author. It's easy to scoff at
languages like ruby, python or javascript and claim they're completely
inferior to 'real languages', but there are completely valid reasons to use
them. The real value comes from simplicity.

If you use a language where runtime/dynamic typing is a subset of what's
possible, you lose that simplicity.

~~~
fao_
Exactly, another use is prototyping value. A language in which you can hammer
a prototype out without thinking about or solidifying _all the exact_ details
-- it's more about trying out the concept, after all -- is infinitely easier
to prototype with. After testing if the concept works, move to a more
rigourous type system so you can bulletproof it against possible errors, etc.

~~~
girvo
While I completely agree, the sheer amount of "proto-duction" projects that
are floating around and that I've had to try and maintain over the years makes
an interesting argument for statically typed languages, I think!

------
AnimalMuppet
The last line of the article: "Let a thousand flowers bloom - as long as
they're all static."

More to the point, things that are formally equal to each other do not
necessarily have equal value in certain uses. (For example, think about
Stokes' Theorem. It says that an integral of a function on the boundary of a
manifold is equal to the integral of the derivative of the function on the
whole manifold. That's useful precisely because sometimes the integrals, while
they have equal results, are not equally hard to do.)

A dynamically typed language may be formally equivalent to a static unityping,
interpreting the tag at runtime. That doesn't mean that they're equally easy
to use, though. When I want to do that kind of thing, I want to do it like
it's dynamic, not where I have to do the book-keeping to _make_ it dynamic.

------
unabst
And for those stuck using javascript but with they had static typing there is:
[http://flowtype.org/](http://flowtype.org/)

The arguments for flow seem to resonate nicely with the points raised in the
article.

~~~
mlitchard
I shall stick with fay
[https://github.com/faylang/fay/wiki](https://github.com/faylang/fay/wiki) and
the like.

------
snissn
For me the big difference between dynamic and statically typed languages is
catching bugs like:

    
    
        foo = bar()
        if foo:
          fooo = baz()
    

in a static language, you'd have to write int foo = and the third line where
you have an assignment fooo would be caught by the compiler. Of course there's
advantages to dynamic languages, like being able to write something like

    
    
        mydata = {}
        mydata['foo'] = {}
        mydata['foo']['bar'] = MyObject()
    

without a lot of boilerplate

~~~
SomeCallMeTim
That's what linting is good for, at least in JavaScript where you have
optional "var" declarations: You can set jshint to flag as an error any
assignment that isn't part of a "var" declaration (or any reference that isn't
explicitly defined), which will catch (at compile time) any variable name
typos.

It won't catch this.fooo, though, so it's only a partial solution. My editor
has great completion, though, so as long as the string is IN the file
somewhere, I usually autocomplete it. Way fewer typos that way.

I see there's a PyLint, so MAYBE it has a way of spotting typos like the one
you cite? Not sure how it would work in Python, though, other than on variable
reads.

~~~
dllthomas
Certianly lint handles this. Some lint checks are quite reasonably considered
type constraints, even if they historically have been implemented seperately.
In particular, uninitialized values and unused variables seem very much in the
same theoretical space as linear types.

