StaDyn

Extending Dynamic features of the SSCLI

The main objective of this project is to break the programmers' black or white choice between static or dynamic typing. StaDyn is a programming language that offers both dynamic and static typing following the Separation of Concerns principle, obtain both the benefits of static typing (performance, early error detection, better documentation and legibility, and better IDE features) and dynamic typing (flexibility, rapid prototyping, less verbose, less rigid, and dynamically adaptable).

Dynamic Languages

Dynamic languages like Python, Ruby, Lua, Dylan or Groovy are becoming increasingly popular for developing different kinds of applications. These languages build on the Smalltalk idea of supporting reasoning about (and customizing) program structure, behavior and environment at runtime. Different examples are the success of the Ruby on Rails framework for creating database-backed web applications and the AJAX (Asynchronous JavaScript And XML) Web development technique for creating interactive web applications; the incorporation of a standard framework to allow dynamic scripting programs to be executed from, and have access to, the Java platform version 1.6 (JSR 223), and the invokedynamic instruction to support the implementation of dynamically typed object oriented languages to be included in Java SE 1.7; the Dynamic Language Runtime (DLR) launched by Microsoft to add to the .Net platform a set of services to facilitate the implementation of dynamic languages; the wide range of dynamic aspect-oriented tools that has been built over dynamic languages; and the Zope application server for building content management systems, intranets and custom applications.

Outline

A language is said to be safe if it produces no execution errors that go unnoticed and later cause arbitrary behaviour. Static languages ensure safety of programs by using type systems. However, this type systems do not compile some expressions that have a correct behaviour at runtime (e.g. to pass a message called m to an object, the reference of that object must implement an interface that declares this public method). This happens because their static type system requires ensuring that only good expressions are typable. Figure 1 illustrates this situation.

Correct programs in a static language.
Figure 1. Correct programs in a static language.

At the same time, static languages also permit the execution of programs that might cause the immediate stop of a running application, producing an execution error (e.g. array index out of bounds or null pointer exception).

The approach of dynamic languages is totally different. Instead of making sure that all correct expressions will be able to be executed, they make all syntactic correct programs compilable (Figure 2). This is a too optimistic approach that causes a lot of runtime errors that might be detected at compile time. Dynamic languages do not apply any type checking at compile type, causing too much wrong behaviour at runtime.

Correct programs in a dynamic language.
Figure 2. Correct programs in a dynamic language.

The StaDyn programming language makes type inference at compile type, minimizing the compilable and wrong behaviour region of dynamic languages (Figure 2) and the not compilable and correct behaviour area of static languages (Figure 1). For both proposes we will use the same programming language and platform and let the programmer move form an optimistic, flexible and rapid development (dynamic) to a more robust and efficient (static) one. This will be done using the same source code, changing the compiling settings. We separate the concern of flexibility, robustness and performance, from functional requirements of the application.

Objectives and Benefits

The StaDyn programming language has been created following the next objectives:

Runtime Performance

Since once of the main advantages of static typing is runtime performance, we keep doing type reconstruction for dynamic languages. When types could be inferred at compile time (not always possible), runtime performance and safety will be increased in dynamic languages. Moreover, JIT compilation and adaptive hotspot optimization will be used in both scenarios at runtime.

Flexibility

When the programmer wants to make parts of an application (or the whole program) more flexible —rapid prototyping of views, adaptive code, web engineering or interactive development— he or she will only need to specify it in separate files, without changing the source code. These parts of the application will use a more optimistic type checking scheme.

Type Safety

As described in the previous point, the programmer may identify parts of an application as critical in performance and safety. In this case, static references will be used and the same code will be compiled in a pessimistic way. In case the programmer moves from dynamic to static, it will be common to obtain new compile-time errors. This behaviour is the one described in the outline section.

Language and Platform Interoperability

Since we do type inference both in dynamic and static compilation modes, it is possible to make dynamic and static code interoperate. Currently, IronPython and the Java Scripting API are two common examples that show how dynamic languages can interoperate with static ones, but not the other way round. If the programmer creates a class instance in Python, the static code cannot directly retrieve its type. This lack is due to the fact that Python does not static type checking. Therefore, types created by the programmer in Python are not included in the type system of the static program.

This interoperability is also important at the platform level. The target platforms (ЯRotor and DLR) must offer a reflective object-oriented prototype-based model. This computational model supports both the static class-based one and the reflective model supported by dynamic languages. This will also facilitate the interoperation between StaDyn and existing programming languages.

Separation of Concerns

StaDyn is created following the separation of two important concerns. One is the application functionality that is described with its source code. The other is safety and performance (contrary to flexibility and rapid development) that is described in separate files, used as compiler settings in specific parts of a program. This separation of concerns promotes the movement from agile and rapid-prototyping software development to robust, safe and efficient software. It also facilitates making more flexible specific parts of a system, without changing its source code.

Simplicity

Our type reconstruction (inference) scheme uses parametric polymorphisms and detects type constraints by doing static program analysis. This implies that the programmer should not have to explicitly specify type variables (generics) and type constraints (bounded polymorphism). The compiler will extract all this information at compile time.

To see sample code in a brief tutorial, see Getting Started.