0
votes

I was looking at this post about differences between statically and dynamically typed language and a comment pointed out to the following definition taken from this reference:

Static typing is very often misunderstood to mean that values are associated with types at CompileTime, when instead it means that that a ReferenceValue is manifestly (which is not the same as at CompileTime) constrained with respect to the type of the value it can denote, and that the language implementation, whether it is a compiler or an interpreter, both enforces and uses these constraints as much as possible.

If I'm not wrong, this definition states that being or not being statically typed doesn't depend on having (or not) a compiled implementation of the language.

But said in this way, what's the advantage of having an interpreted implementation with a statically typing system? I mean, the check is always made at run-time.

1
It would still find errors before actually executing any of the code.melpomene
Do you mean that before starting to execute the first line of code an entire type checking is done? Isn't it done in parallel with the execution?zer0uno
On rereading your quote I don't understand what it's trying to say. My best guess is that it's simply wrong.melpomene

1 Answers

0
votes

There are a few aspects to your question.

The first I'll say is that the combination of statically typed code with an interpreted, dynamic runtime is most common as a complementary solution to an existing dynamic language. JavaScript, Python and Racket/Scheme/Lisp all have variants with static type checking*. All of these still use the runtime(s) of the original language though. Static type checking gives value to the programmer even if the static type information is not actually used by the runtime engine.

The second aspect is what I think the definition you cited might refer to. While some static languages throw away type information when compiling, and use it just to make the code not have to check types, others such as Java and C# keep the type information around for the runtime to use as well. What makes static type checking static though is that it can be done without executing the code. Additional checks may be done at runtime (such as that which results in a ClassCastException in Java), but that is then dynamic type checking (done based on information from statically typed code).

As for the benefit of actually creating an interpreted implementation for a statically typed language: Compilers are hard. Not quite as hard as they used to be (with the rise of LLVM for example), but still usually harder than prototyping an interpreted runtime. If you are experimenting with advanced type systems it might be easier to make the first implementation interpreted. If it is statically type checked you would then have a separate type checking phase without executing the code. This could potentially make the runtime not have to worry about checking types during the actual execution of the code.

*: TypeScript, Flow, mypy and Typed Racket to mention some.


Edit: Example mentioned in comment. Standard ML of New Jersey(SML/NJ) is an interpreter for the statically typed language Standard ML. Take the following very simple program:

val _ = print "hello\n";
val foo : string = 4;

In SML/NJ each statement is type checked and then evaluated separately in the existing type enviroment, before moving on to the next statement. As such all code is type checked before it is executed, but the above program would still print hello before failing. The following program however would not print anything:

val foo : int = print "hello\n";

It would not print hello then attempt to store nil into foo. It fails before that, in the separate type checking phase.