home Static vs. Dynamic

Remember to check the "with heading" box in the lower right corner. Surround code listings with <pre> and </pre>, and if you use < and > symbols you must say & lt ; and & gt ;

Very interesting article, I do want to mention that type inferrence as used in ML and it's derivitives does allow latent typing. If the type cannot be inferred it is assumed to be of a generic type, and any value can be passed in. Objects are typed in very interesting way in OCaml? in that the type of an object is the public methods that can be called on it. A class in OCaml? is nothing but an alias for its full listing of methods. So you could say that in ML-family languages latent typing is the default. (though things may work a little differently in other dialects than OCaml?). Max Polun

One of my fears with a compiler/runtime that tries to be "too smart" is whether or not the user can find out what it's thinking. With a compiler you have to inspect the resulting assembly/bytecode if it does something unexpected, and with a runtime you have to step through with a debugger to see what's going on. In OCaml?, what do you do? Do the implementations give you a way of finding out whether or not the language could infer a type, or does the type just silently become generic?


2004/11/17 09:38 EST (via web):
You can test the type signature of any type in OCaml? by checking it in the toplevel. Anything you define at the toplevel it will tell you the type signature of. The extra strong type checking means you generally find out the type of every function anyway. for example:

# List.map  ( # is the toplevel prompt )
val map : val map : ('a -> 'b) > 'a list -> 'b list
where 'a and 'b are type placeholders.


2004/11/17 15:08 EST (via web):
This is a topic that comes up on the Ruby mailing list on occasion. Having started with C and then quickly switching to Perl, and ultimately to Ruby, I've known for a long time that the whole typing-is-safer argument was a lot of fluff. Dave Thomas of "Pragmatic Programmer" fame, once a typing bigot himself, long ago realized this as well. Dan Sugalski (of Parrot fame) once said something along the lines of, "Typing saves you from mistakes you just don't make". So true.

I should also add that there is a strongtyping package available for Ruby that lets you do both typing and overloaded methods. So you can do something like:

def foo(a, b) expect(a, String, b, Numeric) ... end

See http://mephle.org/StrongTyping/ for more details.


2004/11/17 21:24 EST (via web):
A link to the "Seven plus or minus two" reference.

http://www.well.com/user/smalin/miller.html


2004/11/20 20:12 EST (via web):
I'm unconvinced. The strong-static-typing-is-fluff crowd hasn't yet produced a scrap of evidence to back up their claims, except anecdotal. Let me propose an alternate theory on why some people like dynamic typing: it lowers the bar for programmers. From the author's own articles, I've realized that he has an unprincipled design methodology, or at least lacks the years of practical experience required to make good design decisions up front. This is actually common with seasoned veterans as well, and is not a cheap-shot taken at someone who has honestly revealed his thoughts on programming. There are definitely some people who can groove on software design, and others who struggle to find the right path for their classes to fit together. Some people just never make it to that zen, or never find a complete design methodology that makes the decisions clear and obvious for them.

What dynamic typing gives you is the ability to be uncertain, and the chance to change your mind quickly because of that uncertainty. This is the same direction that XP points--rapid iterative tests and prototypes that evolves into a final product. The issue that both XP and the above article on static typing being unnecessary both are addressing failings in programmer-space, not in code-space. I grant entirely that some languages make a mess of their own syntax (templates in C++), and have more rules than even the most complex German board games, but once you find a working system for defining your code layouts, you can begin to ignore vast sections of "no-man's land" in those rules. For instance, multiple inheritance in C++. There's a lot that can go wrong there. So I don't use it, except occasionally with pure virtual interfaces. I also don't tend to nest my inheritance more than 1 level off an interface class, because the IS-A relationship begins to break down after that, particularly when an intermediary class needs to change its implementation, but its derived children classes do not. What I'm saying is, you can trap yourself in a language with too many constructs because you try to apply them without the foreknowledge to avoid the pitfalls inherent in those constructs. This is true of any language. What the author has (fairly successfully, I might add) argued is that dynamic typing languages have fewer syntactic constructs that inhibit code design by inexperienced programmers.

This is not the same as arguing that static type checking is not useful. In fact, I offer a quick contradiction: Static type checking can remove a certain class of bugs. Dynamic type checking cannot remove any bugs that static checking cannot also detect. If you accept these two statements, you must conclude that static type checking has benefits that dynamic does not.

My personal feelings, however, are more inclined to disagree with dynamic checking because it removes restrictions that you can place on code that can be checked before runtime. In my opinion, if you have a branch in code that exercises once in a million runs, and it triggers a runtime type exception, you will have a harder time finding that bug than with a statically typed program that is written the same way. Worse, with weakly typed languages you are moving more information about how the code should perform OUT of the source files and INTO the developer's head (or comments, if you're really lucky). This is a significant loss on large projects where static type bindings at least will tell you the obvious errors like, you forgot to supply enough parameters to this function, or your class needs to implement these methods to fulfill this interface, or what have you (C++'s syntax fails in this regard with pure virtual methods, because there's no way to force a derived grandchild to implement a function, nor is there a way to finalize classes or functions as in Java). At any rate, the loss of information means the compiler can never use that to do more automated tests. The argument that the programmer can do a faster job of it than typing in the statically type safe code and its invariants is contrary to the author's own arguments that programmer time is costly.

Either way, it's nice to see this discussed, if only to dispel the argument.


2004/11/22 05:49 EST (via web):
Having lived in Germany for nearly three decades now (and being born there), I never encountered any German board game that is more complex than Tic Tac Toe, so ... what are you talking about?


2004/11/22 13:27 EST (via web):
"In a language that leans towards static type checking, the compiler will ensure that certain things will not slip through the cracks, and this is helpful, although the resulting language will typically make you work harder for a desired result, and the reader must also work harder to understand what you've done." This is something I'll never understand in Bruce's writings: how can explicit type specifiaction as part of the language syntax make it harder to understand the code? This claim is all the more mysterious as it has been challenged numerous times during the past year and Bruce never responded. I regard code readability one of the main advantages of Java-style typing, and I have yet to see a shred of evidence to the contrary.


2004/11/22 13:27 EST (via web):
"In a language that leans towards static type checking, the compiler will ensure that certain things will not slip through the cracks, and this is helpful, although the resulting language will typically make you work harder for a desired result, and the reader must also work harder to understand what you've done." This is something I'll never understand in Bruce's writings: how can explicit type specifiaction as part of the language syntax make it harder to understand the code? This claim is all the more mysterious as it has been challenged numerous times during the past year and Bruce never responded. I regard code readability one of the main advantages of Java-style typing, and I have yet to see a shred of evidence to the contrary.

-- piglet


2004/11/23 13:17 EST (via web):
Type inference Note that the Nice language does type inference only locally; the coder doesn't have to specify the type in some obvious cases. This is nowhere near type inference properly speaking. The type inference algorithm as used by OCaml? and other ML languages actually infers and checks types throughout the program. This seems to work reasonably, but there are two problems:

  1. The algorithm depends on the code body. It infers the type of an object by examining how it is used. This seems to be exactly what Bruce has been asking for all the time. But it should be clear that the separation between interface and implementation, usually regarded as an essential feature of the OO paradigm, is negated by that approach. A change in the code body can break all the respective client code. Likewise, the client programmer cannot rely on the method signature; he must examine the code or hope that the documentation is accurate. The fact that the compiler can tell him when there's an incompatibility surely helps, but I wonder how this scales to large projects and external libraries. And if OCaml? really offers the "best of both worlds", flexibility plus safety, may I ask the question why it isn't much more popular?
  2. The shoot problem has already been discused at length. If Gun and Camera both have a shoot method, type inference may be unable to distinguish between them, resulting in mysterious errors. Java's nominal type system doesn't only prevent this, it actually allows us to associate a meaning to the type and method names we use. Well-designed Java code is humanly readable. I wouldn't want to miss that.

-- piglet

fd

"This is something I'll never understand in Bruce's writings: how can explicit type specifiaction as part of the language syntax make it harder to understand the code?"

Consider these two functions:

def spouse(person): if person.is_male: return person.wife else: return person.husband

vs

public static Person spouse(Person person) { if (person.is_male) { Man man = (Man) person; return man.wife; } else { Woman woman = (Woman) woman; return woman.husband; } }

The second (Java) is, IMO, considerably harder to read than the first (Python).


2004/11/25 11:37 EST (via web):
This is an example of silly design, not a proof that Java is harder to read. The intuitive solution would be an gender attribute and a spouse reference. By the way, your design would miss same-sex couples ;-) Even if for some reason your design would make sense, I would write in Java
 public static spouse (Person person){
          return ( person.isMale()? ((Man) person).wife : ((Woman) person).husband);
      }


2004/11/25 12:51 EST (via web):
I can confirm Max Polun's comments on OCaml? supporting both latent typing and type inference (which counterexamples Bruce's intuition that the two can't be combined). To illustrate, this is the infamous dog/robot/mute example done in OCaml?.

class dog =
    object
        method talk () = print_endline "Arf!"
        method wagTail () = ()
    end;;

class robot = object method talk () = print_endline "Click!" method oilChange () = () end;;

class mute = object method dance () = print_endline "Boogie!" end;;

let speak x = x#talk ();;

let d = new dog;; let r = new robot;; let m = new mute;;

begin speak d; speak r; ( speak m; ) end

Note that the last instruction is commented out (see below). This code compiles and runs:

$ ocaml latent.ml
Arf!
Click!

Yet, OCaml? is still able to statically detect typing errors. For example, if the last instruction is left uncommented, this will not compile:

$ ocaml latent.ml
File "latent.ml", line 27, characters 10-11:
This expression has type mute but is here used with type
  < talk : unit -> 'a; .. >
Only the second object type has a method talk

Note how the inferred type for the argument of "talk", as shown in the third line of the error message from the compiler, is a latent type. The type can be read as "anything having a method talk which takes an argument of type unit (i.e. which takes no arguments) and returns some other type".


2004/11/25 13:26 EST (via web):
As a follow-up to 2004/11/25 11:37 EST, note how the Java code exposes the design and its weakness: it is immediately clear from reading the code that the Person class has been split into Man and Woman classes. This cannot be understood from reading the Python code, you will have to look up the class definitions. If Java code looks cumbersome, consider the possibility that it merely reflects a cumbersome design.

Once again, explicit type specification in Java isn't just more toc-toc-toc to satisfy the compiler. It makes design decisions explicit and prohibits ambiguity. Now, ambiguity is in fact flexibility. I accept that in some cases, the programmer wants to be ambiguous in order to gain flexibility. But, like in a natural language, ambiguity makes code more difficult to understand. This tradeoff should at least be clear.

-- piglet

Just some comments on the write-up. First, I didn't see anything in the link to the NICE language about type inference. I'll have to check other reference on NICE to see exactly what it is doing.

In ML and it's derivatives, one of the key features is that it tells you the type of every expression that you give it, as was mentioned by one of the replies above. So the type that it creates is never "silent", but always seen by the coder assuming the coder bothers to look.

I discussed Bruce's reply with the students in my class and one of them made a very interesting comment. This was in regards to the statement "compilers protect programmers from errors they don't make." My student replied, "When was the last time you got into an argument with a compiler and you were right?" The answer to his question is, quite simply, never. Compilers only flag errors that are true violations of the language. Granted, the reply here could be that the language design was too restrictive and in some cases that is true. In my opinion, that is somewhat rare, but it is possible. An example is trying to put templated class methods in a source code file in most C++ implementations. Or, also in C++, trying to mix templates and inheritance in certain ways. Not everything works because templates are statically typed and virtual method invocations are dynamically typed. The two don't always get along. I describe this as a case of a language allowing me to think a thought, but not allowing me to actually express it. That frustrates me to no end.

This doesn't make the statement that compilers only find errors that programmers don't commit true. In fact, ML is a perfect example of the opposite. However, the reason ML is a counter example is because it, and most functional languages, are fundamentally more expressive than imperative or object-oriented languages. Simple things that a programmer can easily forget drastically change an expression and typically this shows up in the type of the expression. A common example of this in ML is leaving out a cons (::) in one place where it should go, especially in patterns. This is a type error. It's not a case of the compiler being too restrictive, nor is it something the programmer never really does. It is a real error that happens very easily to anyone. If you do this in Scheme, you better hope you have good test cases that exercise most of the paths through your code because otherwise you won't find this until someone else is using your program. In ML, this error is caught immediately.

So I guess one could make the argument that the less expressive a language is, the less you need static type checking. Similarly, it can probably be argued that programmers who don't try to fully utilize the expressivity of the language they use also don't need static type checking. If you are pushing the boundaries of what is capable in a language though, it is quite likely that minor mistakes that any human makes will only turn up as type errors and for that reason, static type checking will benefit the programmer in the end.

As a last comment, it was mentioned above that in O'Caml the type of an object is determined by the visible methods of that object. This form of typing is refered to as structural typing and differs from the name typing that most of us are using to in C/C++/Java where a type is defined by some point of declaration. This is also true in ML but with records and structures (not like C structures) instead of objects since objects aren't a part of ML. ML gives the programmer the ability to match subsets of the complete set of elements in a record, but somewhere in a declaration, it must be able to determine the complete type. This is one case where the static nature of the checking can seem a bit oppressive. I do not know if O'Caml, Haskell, F#, or other derivatives of ML have improved on this at all by allowing partial matching which could enable something similar to subtyping by an incomplete structural type.

Wow, I should have refreshed the page before writing my reply. It appears that O'Caml does indeed provide that ability to do some limited structural typing so that it only has to have required elements and the type isn't bound to all public parts of an object.

As to the question of why O'Caml isn't more popular if it is so good, I think this is a good question that can't be answered simply. In fact, can you state simply why any language is or isn't popular? Why did Pascal die? However, I'll take a stab at it. First and foremost, O'Caml, like ML, is fundamentally a functional language. The majority of programmers are not trained in functional languages. Those who are are often taught Scheme and LISP which many programmers dislike the syntax of and reject on that basis. As a result, few programmers feel comfortable writing functional code and functional languages haven't been picked up as a result. In addition, functional languages have historically been slow because they have been interpreted. This is not a big factor for O'Caml or ML, which both have optimizing compilers available, and because of their strong static typing, the optimizations can be quite strong. For evidence of this see the Computer Language Shootout (http://shootout.alioth.debian.org/) where O'Caml and MLton? do quite well and stomp on languages like Nice, Perl, Python, and Ruby. O'Caml also is able to do the problems with few lines of code.

So, will the popularity of O'Caml or some other ML derivative grow in the future? That is impossible to predict, but I can make a stab at why they might. One simple reason is that Microsoft has added F# to the .NET framework. They aren't pushing it very hard right now so that might not really go anywhere, but it has more potential than most other ML derivatives at this point simply because it will be part of .NET. More significant is the fact that functional languages have always been fundamentally parallelizable and anyone who has been paying attention to the CPU market knows the importance of that will be growing in coming years. In the second half of 2005 both AMD and Intel will come out with dual core chips. Their single thread performance will be slower than the fastest single core chips, but their dual thread performance will be significantly faster. Intel and AMD don't want to see their benchmark scores go down and for that reason they (especially Intel since they have money) will be pushing programmers to put out parallel programs. Most programmers don't know how to do this properly, so they can either learn how to do it in a language they know now, or they can learn a new language that does it naturally. At the very least, this is an opening for some functional language if someone puts out a good optimizing compiler. For example, if O'Caml or F# were to have a compiler that keeps 2-4 threads busy for nearly all programs without too much overhead and no direct work by the coder other than programming in a functional manner, it would give that language a huge boost


2004/11/26 15:47 EST (via web):
Do you think type inference and OO are compatible? (see the comment 2004/11/23 13:17 EST)


2004/11/28 08:32 EST (via web):
I'll try to illustrate how OCaml? offers the combination of type inference, OO and latent typing. This is done by developping an OCaml?-version of the bank account example of even greater fame.

Starting with a single class:

class person name_init =
        object (self)
                val mutable name = name_init
                method get_name = name
                method set_name x = name <- x
                method to_str = ("Person named " ^ self#get_name)
        end;;

The compiler can infer this class type:

class person :
  string ->
  object
    val mutable name : string
    method get_name : string
    method set_name : string -> unit
    method to_str : string
  end

And I can use it like this:

# let b = new person "Bruce" ;;
val b : person = <obj>
# b # to_str ;;
- : string = "Person named Bruce"

Suppose I try to add a class account like this:

class account holder_init =
        object (self)
                val holder = holder_init
                val mutable balance = 0.
                method get_holder = holder
                method get_balance = balance
        end;;

From this definition the compiler can only infer that the holder can be simply anything. As such, Ocaml will not accept this:

Some type variables are unbound in this type:
  class account :
    'a ->
    object
      val mutable balance : float
      val holder : 'a
      method get_balance : float
      method get_holder : 'a
    end
The method get_holder has type 'a where 'a is unbound

One way to resolve this, is to specify that we meant holder to be a person. Explicitly typing this once is enough to hint the inference:

class account holder_init =
        object (self)
                val holder:person = holder_init
                val mutable balance = 0.
                method get_holder = holder
                method get_balance = balance
        end;;

Then again, you might have intended to have other type of account holders than persons. In this example it would be semantically strange, but you can say that "simply anything" can be the holder of an account by making account a parameterized class using a type variable like this:

class ['a] account holder_init =
        object (self)
                val holder:'a = holder_init
                val mutable balance = 0.
                method get_holder = holder
                method get_balance = balance
        end;;

This allows for accounts to be used like this:

# let a1 = new account b ;;
val a1 : person account = <obj>
# let a2 = new account "foo" ;;
val a2 : string account = <obj>
# let a2 = new account a1 ;;
val a2 : person account account = <obj>

But like I said, the last two examples make little semantic sense here (better cases where this kind of generics is useful of course exist). Interestingly, OCaml? however also offers you latent typing on type parameters, as we can see in an example where we actually use the holder for something:

class ['a] account holder_init =
        object (self)
                val holder:'a = holder_init
                val mutable balance = 0.
                method get_holder = holder
                method get_balance = balance
                method to_str = (
                        "Account with holder named " ^ self#get_holder#get_name ^
                        " and balance " ^ string_of_float self#get_balance
                )
        end;;

The inferred type will now specify a holder to be "simply anything offering a get_name method returning string".

class ['a] account :
  'a ->
  object
    constraint 'a = < get_name : string; .. >
    val mutable balance : float
    val holder : 'a
    method get_balance : float
    method get_holder : 'a
    method to_str : string
  end

As can be expected, the "constraint" in the above type is used for static type checking:

# let a1 = new account b ;;
val a1 : person account = <obj>
# a1 # to_str ;;
- : string = "Account with holder named Bruce and balance 0."
# let a2 = new account "foo" ;;
This expression has type string but is here used with type
  < get_name : string; .. >


2004/11/29 16:00 EST (via web):
If all, say, Groovy added to Java was the ability to not specify types, I doubt it would be anywhere near so popular. I'd wager that most of the win with all these dynamic languages is the fact that things are specified so neatly.

For example, this morning, I wanted to store two ints against an entry in a hashmap. So in order to implement this, I would have (in Java) had to build a class with two ints in it, a hashCode() and an equals method.

In, say, Objective Caml - I could have written (a,b) for two ints. And int comparisons would work properly. I would wager that that is the big win that you get from Python over Java, and not so much the lack of type checking.

(Also), one thing that I think is a win in type checking is, for example, the ability to specify the types as a stronger constraint. For example, in Ocaml there are no null pointers. If you want the equivalent you can use option types, but you can write your functions without testing to see whether nulls occur at all.


2004/11/30 10:15 EST (via web):
You could put your ints into a Set or a List in Java. You don't have to invent a new class for such a simple task. If you only want to store your two ints, not use them as key, you could simply put them in an array, like new int[]{a, b}.


2004/12/03 06:39 EST (via web):
Ahh, but I wanted them as a key (basically, I wanted type, size), and I wanted to look things up in it (otherwise, what is the point of a HashMap??). And yes, I could slap them into an int array, and I could have iterated through all of the values in the hope that the size of the map never hit more than n entries, or I could have created a new class and put them into this, but I don't want anything insanely complicated, I just wanted to do something fairly straightforward.

My sole point is, if somebody built a version of Java which, for example, managed to avoid all typing keywords (by manually inserting casts or whatever), would this be as good as Ruby or Groovy etc. If not, maybe it's worth considering that dynamic typing isn't what is giving the win but something else?

For me, if Java had tuples it would make my life loads easier. Fortunately we will get something not too far off it for 1.5. (well, with significantly less finger typing anyway)

You wrote: "In general, my attitude is that static typing is desirable as long as it doesn't cost you too much. As you point out, type inference as found in ML gives you static type checking without requiring that you give extra information that the compiler can figure out itself. The new Nice language also uses type inference."

I think boo is the ideal language for you ( http://boo.codehaus.org/ ). It is virtually identical to python, but it has static typing plus type inference. Plus extra features we won't see in Python for years like anonymous methods, and features that people including Guido have wanted in Python for years, like case-insensitivity (there is a patch for boo that adds a case-insensitive option).

Another reason you didn't mention about why people transfer their model/prototype to something like java or C# at the end is speed, but with boo you have have to take that extra step because it already runs as fast as C# or any statically typed language. I don't think python is slow, there are optimizers like psyco, but with boo, everything is static and fast by default, and dynamically duck typed at runtime only when you explicitly declare it to be.


2004/12/05 18:05 EST (via web):
----

My above comment wasn't separated from the one before, so here it is again with a little extra.

You wrote: "In general, my attitude is that static typing is desirable as long as it doesn't cost you too much. As you point out, type inference as found in ML gives you static type checking without requiring that you give extra information that the compiler can figure out itself. The new Nice language also uses type inference."

I think boo is the ideal language for you ( http://boo.codehaus.org/ ). It is virtually identical to python, but it has static typing plus type inference. Plus extra features we won't see in Python for years like anonymous methods, and features that people including Guido have wanted in Python for years, like case-insensitivity (there is a patch for boo that adds a case-insensitive option).

Another reason you didn't mention about why people transfer their model/prototype to something like java or C# at the end is speed, but with boo you have have to take that extra step because it already runs as fast as C# or any statically typed language. I don't think python is slow, there are optimizers like psyco, but with boo, everything is static and fast by default, and dynamically duck typed at runtime only when you explicitly declare it to be.

See this page for explicit comparisons between python and boo feature-wise and syntax-wise: http://boo.codehaus.org/Gotchas+for+Python+Users

Here is an example of an anonymous closure in boo:

b = Button()
b.Click += do():
    print "button clicked"

correction: with boo you don't have to take the extra step of converting it to C# (although there is a tool for doing so), because it is already as fast as C# or any statically typed language.

This commentary is biased towards static typing. See http://www.chimu.com/publications/short/whyDynamicTyping.html for a conversation biased towards dynamic typing.

I prefer Python because it lets me express many idioms and algorithms that cannot be expressed in Java/C++, or must be repeatedly coded again and again in a low level fashion.


I'd still say that the biggest advantage people are noting when using Python (or any similarily dynamically type lang) is simply that you don't have to explicitly specify the types. The biggest weakness of todays' static languages is the "silly" need to manually duplicate type info on the lhs of an expression that the compiler really knows about anyway. This leads to the all to frequent "lhs type mismatch with rhs type" errors that I'd dare assert stands for the vast majority of annoying syntax-errors.

An interesting article related to this is: http://www.artima.com/cppsource/spiritofc.html At the end it toys with the idea of a "C+++" with implicit templates to achieve great syntactic reduction similarily to Python. If an "auto" or "decl" keyword shows up in a future C++ quite a large amount of everyday code-writing would greatly benefit.

Another observation I haven't seen noted previously is the advantage of Python as an interpreted lang vs a system with inference, is that Python doesn't need a meta-language! Ordinary Python code can take this role. (Non-executed code doens't provoke errors). Compare to C++ with needs some quite clever "hacking" to do the same (altough recent suggestions by Vandervoorde seems promising to amend this).

My 3c // Fredrik


2004/12/06 14:06 EST (via web):
@2004/12/03 06:39 EST

I admit that I never had the need for a tuple structure (a list of fixed size), and it's the first time that I hear somebody complain about the lack of it in Java. If I ever needed it, it wouldn't be hard to implement a fairly generic tuple class as a Collection (in Java 1.5 with a specified type), based on an array the length of which is defined at instantiation time. hashCode and equals are already defined in the Arrays class. There's nothing insanely complicated with that.


2004/12/07 05:26 EST (via web):
Tuples are insanely useful, because they allow you to easily return multiple values from a function. Imagine, for example, being able to declare a function

public (Map,Map) foo(Object[] x);

You could guarantee it returned two maps. An alternative way of doing it is either to build a structure to hold two maps everytime you need one, or to return an array of Maps (when you don't know the size remember), or to use some alternative approach. It's just a nice way of doing things.

Likewise, there are loads of cases where you might want to create a compound key, and it's really easy with tuples.

Obviously you could add Tuples to Java by defining classes, but then you lose all typing information and have to cast pretty much everywhere. With generics it will be a little better, as there will be some type safety at least.

For a program in the prototyping phase, programming and compile time is more valuable than running time (mostly), I would definitely go for dynamic typing. For a production program that intend to be run by thousands of or more users, the runtime cost easily outgrows the developing time cost, shift the type checking from run-time to compile time makes a lot of sense.

I am thinking of a language that allows both. It apparently does static type checking, but it allows dynamic type such as variant in VB and general type such as Number, String, Array, as well as very strong datatypes such as uint32, float64, utfstring, and array of int32, etc. At compile time, if dynamic data type is encountered, the compiler issues certain runtime code to check actual data type, throws exception or converts the datatype. If strong static datatype is encountered, it emits efficient code assuming correct typing. With this kind of language, to transit from dynamic typing to static typing is just matter of restricting or strengthen the variable declarations. With type inference, the data type has a chain-like effect that often restricting a few certain variable types may achieve strengthening of whole program.

I am planning a language (http://dragoncomposer.sourceforge.net) with these thoughts.

-- Hui Zhou


2004/12/08 11:48 EST (via web):
Seems I made a mistake without checking the with heading box. My previous comment starts with "For a program in ...".

Sorry.

-- Hui Zhou


2004/12/19 23:28 EST (via web):
I would like to support the statement made on the 7th that tuples are incredibly useful. Four months ago I would have said that they might occasionally be nice, but that they weren't really that significant. The difference between now and then is that I've done a fair bit of ML programming in the last few months. The tuple types in ML decended languages are extremely handy. I didn't need them that often in Java or C++ because I would design code in such a way that I didn't use them often, even if such a design was less than optimal. I think part of the reason you don't see tuples in languages not in the ML family is that the pattern matching in ML family languages is truly key to programmers being able to easily use the tuple construct. Without mattern matching, pulling tuples apart degrades into a lot of typing that might as well be method invocations on some form of container.