Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

> In a statically typed language, types are attached to variables.

More precisely, expressions may be typed. Of course, free variables are one particular of expression.

> In a dynamically typed language, types are attached to values.

More precisely, tags are attached to objects. An object is a “physical” entity that exists in space (computer memory) and time (from its construction to its destruction or garbage collection). A value is an abstract and atemporal entity that only exists in the language's semantics.

> Such a language would not allow you to, say, add an integer and a floating point number without explicitly converting one to the other.

But it does allow you to add integers and floating points! The result just happens to be an exception, which is a very well defined operation in the semantics of most high-level languages.

If it weren't allowed, it simply wouldn't happen.



sort by: page size:

>Some dynamic languages will happily convert values from one type to another even when that's not the desired result -- you might not get an error at all, just some bad data you might not find until much later.

This happens with algol style static languages too (And is one of the reasons I find people arguing for Erlang instead of python more persuasive than those instead arguing C++ instead of ruby).

You are confusing strong types with dynamic variables. Most of the algol languages have weak to medium type strength.

For instance, python has much stronger types than C. However, it's variables are all dynamic references.


> Surely dynamic typing is a language feature?

Languages are defined by their grammar. (or you can think about few other ways to define a language, s.a. a set of strings of some shape etc.) There's nothing static or dynamic about languages, just like there's nothing static or dynamic about integers or sausages.

In professional literature these words refer to the fact that some claims (or checks) about types of language expressions can be verified only at run time (when the actual value is known), or either at run time or prior to running the program. First is called "dynamic", second is "static".

Any programs can be checked prior to executing those programs. When there's an argument about "static" vs "dynamic", it is an argument about how useful static analysis can be. For example, in Unix Shell all types can be trivially inferred before executing a program: everything is a string, there aren't any other types. But this kind of analysis is also worthless because it doesn't help to check interesting properties of a program.

Non-professional users of this terminology tend to abuse it to mean something unrelated and inconsistent. You will meet a lot of claims that such and such language is "static" or "dynamic", even though, if you ask the person making that claim to explain what they actually mean by that, you'll discover that they don't really know what that is. Unfortunately, this "classification" is so common that a lot of people take it on faith, without even trying to examine it.

Here are some typical misuses of this terminology:

* If the language doesn't have type annotations, then it is a dynamic language. Of course, this isn't true because there are plenty of languages where type annotations are optional.

* If there isn't a compiler that performs static checks, then the language is "dynamic". Well, nobody so far wrote such a compiler, but that's not a proof it cannot exist. Also, of course, whether or not there is a compiler with w/e properties isn't relevant to the language itself.

* If the language has a mechanism to (automatically) reinterpret a value as belonging to unrelated types, then such language is "dynamic". Unfortunately, this makes virtually every useful language a "dynamic" language, which makes the distinction worthless.

You can probably think about other cases where this attempt at taxonomy fails.

----

To sum it up.

"Dynamic typing" is kind of like "West India" -- a result of confusion, a misunderstanding of the person using the term. The closest thing is "dynamic type checking". In turn, "dynamic type checking" isn't a property of a language, it's a phase of program analysis, specifically, when all values in that program have known types. Every program in any language can be analyzed at run time, which makes claims about some language being more "dynamic" than others nonsense.


Judging by the first paragraph, the author has a very biased, even aggressive preference for static languages and a contempt for anyone that disagrees with him. I don't like that, and I find that the best and most convincing arguments are those that show understanding of the opposite side. People using aggression or logical fallacies in their arguments are usually the people who can't use logic to convince others.

" ... types (static types, of course, there being no other kind) ... "

This is the statement I'm referring to above. It strikes me as completely misguided and wrong. Most languages that I know of, even most statically typed languages, know dynamic types. Java has instanceof. C++ has virtual dispatch (which is based on an objects dynamic type). Even C (untagged) unions usually have some (bit)field that allows the running program distinguish the type of data in the union.

I believe that in general, types are properties of data, which rarely exists at compile time. Thus, almost all types are dynamic. Statically typed languages simply restrict the data that can be stored in variables to a particular type and subtypes thereof.


This was very interesting -

>> Types are a tool of thought. They exist in the mind first, and in the machine second.

>> A statically typed language, therefore, guides your thinking. This is useful. >> A dynamically typed language lets you think freely. This too is useful.

As is this -

>> Not everything is an object. Nor is everything a function, a string, a process, an actor, a value, a thunk, a message, a list, a file, or an expression. Not everything is data, nor is everything code. Not everything is lazy, immutable, pure, copyable, serializable, sortable, or transmissible over the network. goto is not the only control operator, and neither is call/cc.


> A dynamically typed language is a statically typed language with precisely one type.

While technically true, saying this is about as useful as saying "You can do anything in any Turing-complete programming language."


> On the other hand, in a statically typed language there is necessarily a distinction between code that is executed at runtime and (although we often don't talk about it this way) code that is executed at compile time.

Is the distinction or separation necessarily obvious? Statically typed languages which have a unified term- and type-level seem to get a bit subtle in this regard, since a type can be used as a value. And Idris passes proofs around, and has to use proof erasure in order to not let it infect the runtime: proofs can remain until run-time if you're not careful.

I am asking this as a question since I don't have enough experience with such languages to really know myself.


> The issue I have with dynamic languages with types is that the type is usually inferred based on the operation.

That's about as wrong as can be.

In fact, it's the exact opposite (type inference can only be a property of statically typed languages)


> Statically typed languages create a lot of complexity from being entirely dependent on types being correct in a static sense rather than at runtime.

Nonsense. It's very easy to use a runtime cast if and when you want to, even in Haskell. You're in control of exactly where typechecking doesn't happen.

In contrast, in a dynamic language with optional typechecking you have basically no guarantees. Even if 99% of your codebase is typechecked, you have no idea what errors might be lurking in the other 1% or how far they might propagate, since a type error can show up essentially arbitrarily far away from its actual cause. It's the worst of both worlds - you pay all the costs of a static type system but get hardly any of the benefits.


> The code is exactly the same except that you don't have type annotations with dynamically typed languages.

No they are not the same.

Here's some key differences:

- If at runtime an execution doesn't even reach the code, then it doesn't matter at all for that particular execution whether the types were "correct". With static typing you need to get it right for all possible executions before you can even compile, regardless of how unlikely or unimportant those executions are. In practice, having to get it all right for all executions before you can even run one is a massive productivity loss in a lot of scenarios.

- Not only might a "type" of something in a dynamic language not be expressible statically (at least in majority of static languages) in the first place, dynamic code is never dependent on any particular type. You might get an unintended "type" in and the code can still work. There is a dependency on infinite amount of unexpressible "types".

You are completely ignoring the point of dynamic typing and you are using it as if it were static typing without annotations, by your own admission. But that's your problem. Similarly I could also use statically typed language as if it were dynamic and then claim that static typing is exactly the same as dynamic except more verbose.


> how using it is different from using a dynamically typed language

It's not different for that type. The point of using a statically typed language is you can give static types to other entities in your program!


> (C and Java aren't really statically typed; they rely on run-time typing for polymorphism.)

Um, what? Having type information available at runtime is orthogonal to whether or not a language is statically typed.


"You don't litter up a program in a dynamic language with manually written type checks. If you're reinventing a static type system, you're doing something wrong"

Yes: using a dynamic language


> Why write in a statically-typed language when dynamically-typed languages have adapted the best bits and pieces from statically-typed languages?

Unfortunately, dynamically-typed languages haven't adapted the best bit from statically-typed languages: that all types are enforced at compile-time!


> This is true for static and dynamic typing as well: they exist in degrees. Rust can verify type proofs that other languages can't regarding memory safety. Some languages can verify that integer indexes into an array won't go out of bounds. Thus it's not the case that a given language is either statically typed or dynamically typed

Memory safety and static/dynamic typing are orthogonal. C is statically typed but memory unsafe. Rust is statically typed but memory safe (except in unsafe blocks). Lua is dynamically-typed but memory safe.

I agree that it's possible to mix elements of static and dynamic typing in a single language. C++ is generally statically typed, but also supports dynamic_cast<>.

But generally speaking, static and dynamic typing have a very precise definition. Something that carries around type information at runtime is dynamically typed. Something that does type analysis at compile time so that the runtime doesn't need to carry type information is statically typed.


> should the language catch us making a type error here?

With a statically typed language, the choice is up to you. Every statically typed language is just a "dynamically typed" language with the ability to statically assign types. For example, you can type the variable as an "Int" or for more runtime flexibility, a "Variant" (if using C++).


> Formerly dynamically typed languages that pull in static types, like Racket or TypeScript, become statically typed languages with embedded dynamic types.

These languages are not "formerly dynamically typed." These languages are fully dynamically typed. Dynamic typing does not mean the absence of static types! That's the main point of the article.

I use and love statically typed languages. Dynamic types are a "yes and", enabling new things. ObjC and TypeScript are examples of languages with static and dynamic types.

> C# is a language that is considerably different from its first release, and yet v1.0 C# still compiles on the latest compiler. The converse is not true, for either JS or C#. Dynamic types don't help with this problem.

Actually dynamic types help enormously with this problem. They enable testing for the presence of features at runtime, and conditionally invoking code that otherwise could not type check.

Consider for example preventing event propagation in JS. This varies by browser so you might write:

    if (event.preventDefault) event.preventDefault();
dynamically checking for the presence of a field, and then invoking it as a function. This is where dynamic types shine.

You can write this in C# or Java using reflection, because these languages have dynamic types. You can't write this in languages without dynamic types.

> How do all the arbitrary programs on your computer coexist? The programs that interact do so via protocols or standard interfaces

Every program on my computer is a conversation between the application code, the system libraries, and plugins. The browser I am using to type this dynamically interrogates the classes that it uses to discover their features, and conditionally invoke code. Example [1] - notice how this statically typed code is making a dynamic type query, illustrating that these concepts are completely compatible.

My computer's programs rely on dynamic types. That's how they retain compatibility across different versions, and it's how the OS vendor keeps the programs working across system updates.

1: https://chromium.googlesource.com/chromium/src.git/+/62.0.31...


> The way that the value floats through the system is checked statically, and the program can (and should) be designed so that the value with the appropriate type cannot be constructed unsafely.

Except that in the first example from the first link you sent me, there is no static guarantee that the inputs to the constructor are valid, thus the error branch (it would be unnecessary if static guarantees could be made regarding the use of the constructor). And that was my point, that you still end up with dynamic checks on the values which is where pre/post conditions step in to cover what static typing cannot (or, again, cannot easily in mainstream languages, which would not be Haskell).


Dynamic 'types' are not types, they're tags [1]. Their function, to determine what to do with a piece of data passed to a function at runtime, is common to both so-called statically and dynamically typed languages. The actual function of types, on the other hand, is to prove simple propositions about a program without running it. This feature is unique to statically typed languages.

This is the problem with this entire debate. People act like there are two sides arguing from positions of equal merit. That is not the case. One (static) is a strict superset of the other (dynamic).

[1] https://en.m.wikipedia.org/wiki/Tag_(programming)


> However, static languages cannot change the size of the values dynamically at runtime without additional memory allocations.

That is false; a static language could have bignum integers. E.g. you can easily have a bignum class in C++, which is static.

You can't have a variable-length bignum as an unboxed value type.

"Language with unboxed value types" and "statically typed language" are separate, somewhat related concepts.

next

Legal | privacy