What Is a Dynamic Language, and Why Doesn't C# Qualify

What is a dynamic language, and why doesn't C# qualify?

What is a dynamic language?

Whether or not a language is dynamic typically refers to the type of binding the compiler does: static or late binding.

Static binding simply means that the method (or method hierarchy for virtual methods) is bound at compile time. There may be a virtual dispatch involved at runtime but the method token is bound at compile time. If a suitable method does not exist at compile time you will receive an error.

Dynamic languages are the opposite. They do their work at runtime. They do little or no checking for the existence of methods at compile time but instead do it all at runtime.

Why is C# not a dynamic language?

C#, prior to 4.0, is a statically bound language and hence is not a dynamic language.

Why is Ruby the language of the future?

This question is based on a false premise, namely that there does exist one language that is the future of programming. There isn't such a language today because no single language is the best at doing all the different types of programming that need to be done.

For instance Ruby is a great language for a lot of different applications: web development is a popular one. I would not however write an operating system in it.

How can you tell if a language is a dynamic language?

"dynamic" is one of those words that's fashionable, but really means little more than "What I do is cool"... it doesn't have a precise definition.

Having said that, I can answer your question about types, or at least try and explain the difference between typed and untyped (what some people call dynamic, or dynamically typed) languages better.

A typed language checks that you will never end up trying to do something with a variable that you cannot do before you run the program. An untyped language does not do this check - it simply hopes for the best and, if it any point it has a value that is unsuitable for what it needs, gives an error.

Those are two extremes. Like everything in life, in practice languages lie somewhere between the two theoretical extremes. So it's sometimes hard to say that a language is typed or untyped - often all you can say is something like "language X has better type checking at compile time than language Y because these errors are caught in X but not in Y:...."

Given that definition you might worry that (1) a typed language requires a lot more text in the program (because you need to say what type each value is) and (2) that a typed language might restrict what you can do unnecessarily (because the type system isn't smart enough to allow something that you can see would work).

Both of those can be problems. BUT they are both problems that are getting less important as typed languages get better. For example, why have code like:

String s = "hello"

when it's obvious with just

s = "hello"

that "s" must be a String? Languages that are "smart" like this, and where you don't need to say what all the types are, but they are still checked, are often called "Hindley Milner" because those are the people that first worked out how to do that in detail.

So when you look at a program written for a language with a Hindley Milner type system it may look like it doesn't have types. But that's a mistake. It will still, before the program is run, work out what all the types of all the variables must be, and check that you cannot get any errors for trying to do something with the wrong type (I think this is amazing - it's close to a kind of artificial intelligence...)

That means that sometimes the only way to know whether a language is typed or not it to know how it is implemented. It may not be obvious from just looking at the source.

Edit: I just re-read the above, and I could have been a little clearer. The distinction I was trying to make was between languages that have a type system and languages that don't. A type system includes two things: types themselves and logic to check that the types are correct.

The languages I was calling "untyped" (or dynamically typed) do have types. In Python, for example (which is an untyped, dynamic language), there is still a difference between a String and an Integer. But they don't have the extra logic that checks the program before it runs. So it would be more accurate to say that they have types, but don't have a type system.

In contrast "typed" languages, as I said, do check before the program runs, and so must have not just types, but the extra logic to do that work.

Under what circumstances are dynamic languages not appropriate?

Speed is typically the primary answer. Though this is becoming less of an issue these days.

Why C is not a dynamic language?

Because the function in your function pointer is still compiled at compile time.

You cannot add a new function or modify a function "on the fly" at runtime.

Interface in a dynamic language?

I guess there is no single answer for all dynamic languages. In Python, for instance, there are no interfaces, but there is multiple inheritance. Using interface-like classes is still useful:

  • Interface-like classes can provide default implementation of methods;
  • Duck-typing is good, but to an extent; sometimes it is useful to be able to write isinstance(x, SomeType), especially when SomeType contains many methods.

Is there a language that allows both static and dynamic typing?

Sure. It's called "gradual typing", and I would qualify it as trendy.

A cousin of "gradual typing" is "optional typing". In both cases, code with and without static types coexist. However, in "optional typing", the semantics of the language is completely agnostic of static types, while in "gradual typing" the semantics might consider static types, if they are available.

From the page of the course "Integrating Static and Dynamic Typing", I read they study

The design of recent languages that integrate static and dynamic
typing, including Typed Racket (formerly Typed Scheme), C# 4.0,
Diamondback Ruby, Haskell, Sage, and Thorn

You can add Dart to the list, which proposes optional typing as in the position paper Pluggable, Optional Type Systems.

Uses for Dynamic Languages

In theory, there's nothing that dynamic languages can do and static languages can't. Smart people put a lot of work into making very good dynamic languages, leading to a perception at the moment that dynamic languages are ahead while static ones need to catch up.

In time, this will swing the other way. Already various static languages have:

  • Generics, which make static types less stupid by letting it select the right type when objects are passed around, saving the programmer from having to cast it themselves

  • Type inference, which saves having to waste time on writing the stuff that should be obvious

  • Closures, which among many other things help to separate mechanism from intention, letting you pull together complicated algorithms from mostly existing ingredients.

  • Implicit conversions, which lets you simulate "monkey patching" without the risks it usually involves.

  • Code loading and easy programmatic access to the compiler, so users and third parties can script your program. Use with caution!

  • Syntaxes that are more conducive to the creation of Domain Specific Languages within them.

...and no doubt more to come. The dynamic movement has spawned some interesting developments in static language design, and we all benefit from the competition. I only hope more of these features make it to the mainstream.

There's one place where I don't see the dominant dynamic language being replaced, and that's Javascript in the browser. There's just too much of an existing market to replace, so the emphasis seems to be towards making Javascript itself better instead.

What is the difference between statically typed and dynamically typed languages?

Statically typed languages

A language is statically typed if the type of a variable is known at compile time. For some languages this means that you as the programmer must specify what type each variable is; other languages (e.g.: Java, C, C++) offer some form of type inference, the capability of the type system to deduce the type of a variable (e.g.: OCaml, Haskell, Scala, Kotlin).

The main advantage here is that all kinds of checking can be done by the compiler, and therefore a lot of trivial bugs are caught at a very early stage.

Examples: C, C++, Java, Rust, Go, Scala

Dynamically typed languages

A language is dynamically typed if the type is associated with run-time values, and not named variables/fields/etc. This means that you as a programmer can write a little quicker because you do not have to specify types every time (unless using a statically-typed language with type inference).

Examples: Perl, Ruby, Python, PHP, JavaScript, Erlang

Most scripting languages have this feature as there is no compiler to do static type-checking anyway, but you may find yourself searching for a bug that is due to the interpreter misinterpreting the type of a variable. Luckily, scripts tend to be small so bugs have not so many places to hide.

Most dynamically typed languages do allow you to provide type information, but do not require it. One language that is currently being developed, Rascal, takes a hybrid approach allowing dynamic typing within functions but enforcing static typing for the function signature.

Why is the Dynamic part of Dynamic languages so good?

The two fundamentally different approaches to types in programming languages are static types and dynamic types. They enable very different programming paradigms and they each have their own benefits and drawbacks.

I'd highly recommend Chris Smith's excellent article What to Know Before Debating Type Systems for more background on the subject.

From that article:

A static type system is a mechanism by which a compiler examines source code and assigns labels (called "types") to pieces of the syntax, and then uses them to infer something about the program's behavior. A dynamic type system is a mechanism by which a compiler generates code to keep track of the sort of data (coincidentally, also called its "type") used by the program. The use of the same word "type" in each of these two systems is, of course, not really entirely coincidental; yet it is best understood as having a sort of weak historical significance. Great confusion results from trying to find a world view in which "type" really means the same thing in both systems. It doesn't. The better way to approach the issue is to recognize that:

  • Much of the time, programmers are trying to solve the same problem with
    static and dynamic types.
  • Nevertheless, static types are not limited to problems solved by dynamic
    types.
  • Nor are dynamic types limited to problems that can be solved with
    static types.
  • At their core, these two techniques are not the same thing at all.


Related Topics



Leave a reply



Submit