Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This claim by Aleks Bromfield states:

Almost every language with a static type system also has a dynamic type system. Aside from C, I can't think of an exception

Is this a valid claim? I understand that with Reflection or Loading classes at runtime Java gets a bit like this - but can this idea of 'gradual typing' be extended to a large number of languages?

share|improve this question
    
I am no language expert, but a few that instantly come to mind that I do not believe have dynamic types (Natively, not saying you couldn't cobble something together in these) - Fortran, Ada, Pascal, Cobol –  mattnz Dec 28 '13 at 22:35
2  
I am a language expert, and I am not sure what this guy is claiming. "static" and "dynamic" are misnomers and usually indicate the time of type check/analysis (whether at compilation time or at runtime). Some languages conciliate both (eg. by disallowing operations on unsupported types during compilation and raising exceptions like ClassCastException during runtime), and that may be what he means. If so, it is true that C usually does not perform type check during runtime. Saying a lang. does not have "dynamic type system" doesn't make sense. –  Thiago Silva Dec 29 '13 at 0:51

5 Answers 5

up vote 18 down vote accepted

Original tweeter here. :)

First of all, I'm somewhat amused/shocked that my tweet is being taken so seriously! If I had known it was going to be this widely disseminated, I would have spent more than 30 seconds writing it!

Thiago Silva is correct to point out that "static" and "dynamic" more accurately describe type checking, rather than type systems. In fact, it isn't really accurate to say that a language is statically or dynamically typed, either. Rather, a language has a type system, and an implementation of that language might enforce the type system using static checking, or dynamic checking, or both, or neither (though that would not be a very appealing language implementation!).

As it happens, there are certain type systems (or features of type systems) which are more amenable to static checking, and there are certain type systems (or features of type systems) which are more amenable to dynamic checking. For example, if your language allows you to specify in the text of a program that a particular value must always be an array of integers, then it's reasonably straightforward to write a static checker to verify that property. Conversely, if your language has subtyping, and if it permits downcasting, then it's reasonably straightforward to check the validity of a downcast at runtime, but extremely difficult to do so at compile time.

What I really meant by my tweet is simply that the vast majority of language implementations perform some amount of dynamic type checking. Or, equivalently, the vast majority of languages have some features that are difficult (if not impossible) to check statically. Downcasting is one example. Other examples include arithmetic overflow, array bounds checking, and null checking. Some of these can be statically checked in some circumstances, but by and large, you'd be hard-pressed to find a language implementation that doesn't do any checking at runtime.

This is not a bad thing. It's just an observation that there are many interesting properties that we would like our languages to enforce, and that we don't really know how to check statically. And it's a reminder that distinctions like "static types" versus "dynamic types" are not nearly as clear-cut as some people would have you believe. :)

One final note: the terms "strong" and "weak" aren't really used in the programming language research community, and they don't really have a consistent meaning. In general, I've found that when someone says that a language has "strong typing" and some other language has "weak typing", they're really saying that their favorite language (the one with "strong typing") prevents them from making some mistake that the other language (the one with "weak typing") doesn't -- or conversely, that their favorite language (the one with "weak typing") allows them to do some cool thing that the other language (the one with "strong typing") does not.

share|improve this answer
4  
"It's just an observation that there are many interesting properties that we would like our languages to enforce, and that we don't really know how to check statically." – Well, it's not just that we don't know how to do it. "Does this program halt for this input" is an interesting property that we not just don't know how to check, but in fact we do know is impossible to check. –  Jörg W Mittag Dec 30 '13 at 4:39

Well yes. You can have property bags in any statically typed language. The syntax will be terrible while at the same time you will gain all the disadvantages of dynamically typed system. So there is not really any advantage unless compiler allows you to use nicer syntax, something like C# with dynamic is doing.

Also, you can do that pretty easily in C too.

In reaction to other answers: I think people are mistaking static/dynamic typing with strong/weak typing. Dynamic typing is about being able to change the structure of data at runtime and code being able to used data that just fits what the code needs. This is called Duck Typing.

Mentioning reflection is not telling the whole story, because reflection does not allow you to change existing structure of data. You cannot add new field to a class or structure in either C, C++, Java or C#. In dynamic languages, adding new fields or attributes to existing classes is not only possible, but actually quite common.

For example, look at Cython, the Python-to-C compiler. It creates static C code, but the type system still retains it's dynamic nature. C is statically typed language, yet it is able to support dynamic typing from Python.

share|improve this answer
    
Technically, you can do it in C# as of version 4 with ExpandoObject, although it's very much an opt-in process, much unlike JavaScript or Ruby. Still, you've made a very important point, which is that duck typing (what 99% of developers actually mean when they say "dynamically typed") and reflection are not the same things at all. –  Aaronaught Dec 29 '13 at 2:45

The difference between static and dynamic typing is when the type of a value is checked: compile time vs. run time. In languages where values carry their type with them (e.g. Java objects), then you can always resort to dynamic typing even when the language actually prefers static typing. Here is an example in Java, with a dynamically typed method:

void horribleJava(List untypedList) {
  for (Object o : untypedList)
    ((SpecificType) o).frobnicate();
}

Notice how the type of each item is checked at runtime. The equivalent statically typed method is:

void goodJava(List<SpecificType> typedList) {
  for (SpecificType o : typedList) {
    o.forbnicate();
  }
}

In C, values (and specifically pointers) do not retain their type during runtime – every pointer is equivalent to a void *. Instead, variables and expressions have a type. To achieve dynamic typing, you have to carry around the type information yourself (e.g. as a field in a struct).

share|improve this answer
1  
I don't think a cast counts as dynamic typing in any really practical sense. It still requires knowledge of the type at compile-time, it just defers the actual validation until runtime. You can't invoke the frobnicate method here without first knowing about SpecificType. –  Aaronaught Dec 29 '13 at 2:47
1  
@Aaronaught But this is dynamic typing once we've deferred the type check to run time. Note that both of my examples use nominative typing which require a specific type name. You are thinking of structural typing, e.g. duck typing which requires a presence of some method. The axes structural vs. nominative and static vs. dynamic typing are orthogonal to each other (Java is nominative and mostly static; ML and Go are structural and static; Perl, Python, and Ruby are (mostly) structural and dynamic). –  amon Dec 29 '13 at 9:14
    
Like I said in my last comment, it's a theoretical distinction that no programmer I've ever met really cares about. You can abrasively argue that people are using the wrong terminology (and it does in fact appear that the original tweeter was going for precisely that sort of snarkiness) but for people who are actually in the trenches, dynamic typing = duck typing. In fact that definition is so common that langues such as C# have actually codified it (i.e. with the dynamic keyword). Equating static to compile-time and dynamic to runtime mostly just muddies the waters. –  Aaronaught Dec 29 '13 at 19:44
    
@Aaronaught: If one casts to an interface, and if classes that implement a method with the intended meaning consistently implement the same interface to say so, then one would essentially be run-time duck-typing. While some might argue that "duck typing" should just use the method name, I think it would be more helpful to regard the "real" method name as being the interface name plus the method name. Otherwise, should [1,2].Add([3,4]) yield [1,2,3,4], [1,2,[3,4]], or [4,6]? –  supercat Jan 28 at 17:56
    
@supercat: None of the above, it should fail because there is no Add method on array that accepts an array because such a method would be ambiguous. Duck typing doesn't excuse you from writing comprehensible types and functions. –  Aaronaught Jan 28 at 22:15

Static vs. Dynamic typing basically refers on to how types are checked. Static typing means that the verification of the types of various variables or expressions are checked based on the actual code (usually by the compiler) while in a dynamic type system this verification is performed only at runtime, by the runtime environment.

What I believe the text is referring is that even if the types are actually checked statically, they are also checked at runtime, i.e. dynamically. You correctly mentioned Java Reflection; reflection only happens at runtime and the Java Runtime Environment (JVM) actually performs type checking when reflection is used, which basically means dynamic type checking.

share|improve this answer

Dynamic languages are static languages. What is commonly called "dynamic typing" is really a special case of static typing - the case where you've restricted yourself to only having one type. As a thought experiment, imagine writing a program in Java or C# using only Object variables/fields/parameters and down-casting immediately before calling any method. It'd be more accurate to call languages like Python or Javascript "unityped". (This claim will likely confuse/bother many people, considering such a Java or C# program would use many sub-types, but that's because the average OOP language conflates types and classes. Read the blog post for more details.)

Note that even C has "dynamic" typing - you can cast any pointer to a void (and if memory serves me, char) pointer and back again. And note, also, that there is no runtime checking there; if you get it wrong, enjoy your undefined behavior!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.