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

411 views Asked by At

I'm trying to get a better handle on what it really means for a language to be "dynamic". I have quite a bit of experience with Lingo, which is the scripting language for the Adobe (formerly Macromedia) Director product line, and I'm just wondering if it would be considered a "dynamic language".

The way variables and lists are handled seems very "dynamic language"-ish to me.

With variables, you would just write foo = 3 or bar = "Hello World". You don't declare a variable as an int or string--it figures that out as is goes.

With lists, you can just write something like miscCollection = [3, "Hello World", #helloWorld, ["Embedded List", "Goes Here", 3], [#phrase: "Property List goes here", #value: 3]]. Would this not be similar to a tuple?

Are these features enough to qualify for "dynamic language" status?

Interestingly, I've been using C# a lot more and Director/Lingo a lot less, but with all the excitement over dynamic languages these days, I wonder if I'm actually going against the grain.

EDIT

Regarding Mark Rushakoff answer, below, here's an attempt to analyze whether Lingo qualifies as "dynamic" using this Wikipedia article:

  1. Eval - Lingo has do and value keywords. do will execute an entire command, e.g., do "foo = 23" or do "foo = sum(20, 3)". value attempts to convert a string into a numeric, but it is more than just a parsing operator--it can actually convert a string representation of a variable into its number, e.g., assuming foo = 23, the statement value("foo") will evaluate to 23.

  2. Higher-Order Functions - If I'm understanding this right, this is basically what I would be called a "delegate" in C#. Lingo doesn't support this directly as far as I know, although you could create a type (called a "parent script") that has a function and pass an instance of the type.

  3. Closures - No support for this as far as I know.

  4. Continuation - No support for this as far as I know.

  5. Reflection - In a sense at least, yes. You actually create new instances of types using a string, e.g., fooInstance = script("Foo").new(bar). It is also possible to convert an instance of a type into a string that contains the name of the type (so you can sort of mimic c#'s GetType() functionality). You can also query the properties of a type without knowing the names of the properties (e.g., look up a property by index) and find out the names of the properties by index.

  6. Macros - The way the Wikipedia article describes a macro, I don't believe so. It is possible to edit scripts at runtime, however, so maybe that counts.

So, it seems that Lingo scores a 2 to 3 out of 6 on dynamic features, but I'm not clear enough on closures and continuations to know for sure that Lingo doesn't support them. I guess I'm not sure what to conclude. Comments welcome.

4

There are 4 answers

1
andrew cooke On BEST ANSWER

"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.

0
Mark Rushakoff On

Type inferencing (such as your examples of foo = 3 and bar = "Hello World") does not imply a dynamic language. The var keyword in C# infers the variable type at compile-time, and Haskell also can use implicit typing for all variables, even in compiled programs.

"Dynamic programming language" is a pretty loosely defined term, but I think if you had to restrict it to one qualifier, it would be runtime reflection. If you can do reflection, you can probably do the other qualifiers listed in the Wikipedia article (eval, object runtime alteration, closures, macros...).

I don't know anything about the Lingo language, but I'd say it's generally easier to disqualify a language as being dynamic than it is to qualify a language. Can Lingo do any/all of the qualifiers in the Wikipedia article? If not, then it's probably just not dynamic. If it can do any, then it's probably at least "dynamic enough".

2
Daniel Pryden On

When people talk about a programming language being "dynamic", they are usually referring to a dynamic type system. The best definition of what a dynamic type system is (and what it isn't) that I've ever read is Chris Smith's excellent article What to Know Before Debating Type Systems.

Once you've read that article, I think you should have your answer as to whether any given language qualifies as being statically or dynamically typed.

0
Gus On

I would like to show that Lingo is a dynamic language.

I've did LingoF a Functional Programming Framework for Lingo. This Framework is entirely written in Lingo, no xtra, no low level components used, so it wouldn't be possible to develop such framework if the language was not dynamic.

Considering that framework, here is my evaluation for Lingo as Dynamic language:

1 - Eval - Lingo has do and value keywords. Plus you can compile a script in execution time. See LingoF's Feature "Lingo Expressions".

2 - Higher-Order Functions - LingoF shows how possible is to do extensive use of Higher order functions in Lingo.

3 - Closures - Again LingoF shows how is possible to work with Closures in Lingo.

4 - Continuation - LingoF syntax helpers are defined with continuation techniques. It is possible to write functions in Continuation Passing Style. Check this (taken from LingoF module):

on public_factorialCPS_2
on fac me, n,k
  x = LingoF().var()
  if ( n = 0 ) then return k [1] 
  else return me.factorialCPS[$(#-,n,1) ] [ LingoF().fun(x) [ k [ $(#*,n,x) ]  ] ]
end

5 - Reflection - Already answered yes and I agree. For example LingoF module manager is implemented using Lingo's Reflection features mentioned by DanM.

6 - Macros - I will have to do more research in this field. Since Director supports Linked Scripts (scripts stored in external text files) it is possible to implement some kind of macros. Maybe the macro manager can intercept some events like startMovie (to expand them) and stopMovie (to compress them again). Another possibility is to use fields as scripts and expand them in script members, I'm sure it will work fine.

So my score is 5 to 6 out of 6 on dynamic features.