I find myself in Germany, at a Dagstuhl conference on Foundations for Scripting Languages and with a with a bit time to ponder things. For example, why do we label some languages as Scripting Languages and some not? The first part of the answer is easy enough: a language is a scripting language if we use it write scripts. But just what makes a script different from a program?

Historically, things are clear enough. Programs are sets of instructions carried out directly by computer hardware, perhaps with the cooperation of a runtime and/or operating system. Scripts, on the other hand, are sets of instructions carried out by other programs, such as text editors, command line processors and most famously, Web Browsers. At a high enough level of abstraction, there is no conceptual difference between “scripting an operating system” and “scripting a text editor”, but in practice the details matter and they are different enough to have a material affect the design of a historical scripting languages.

The first thing to bear in mind is that scripts tended to be batches of commands of the sort that end-users, not necessarily programmers, typed into the command line prompts of programs such as an interactive chart drawing systems. (Lets call such programs “execution environments”.) These commands have to be simple, easy to discover, easy to remember and should be relevant to the task at hand. Not too surprisingly, successful command languages tend to be very object oriented: The execution environment manages a set of things (objects) that have meaning in the conceptual world of its user, such as data sets, pie charts, bar charts and legends. The scripting language provides a way to find and create objects, give them handy names, and to manipulate them with commands that amount to method calls. The execution environment takes care of managing the lifetimes of the objects and efficiently implement the objects in a way that does not complicate the user model, and that may change from version to version without impacting the user model.

All this has a number of implications:

  1. The execution environment interprets batches of commands that are dynamically entered by users, i.e. it has to deal with dynamic code loading.
  2. There is a sharp distinction between the implementation knowledge and privileges of the execution environment’s own code and that of the dynamically loaded code.
  3. There is little incentive for the scripting language to provide a language for defining new types of objects.
  4. Compile time and runtime merges together in such a way that there is little to be gained from compile time type checking.

As a result, even today, “scripting language” is synonymous with “interpreted” and “dynamically typed”. And the typical lack of declarations, and annotations and syntactic conventions that help static error checking, translate into perceptions that scripting languages are more concise and powerful than general purpose programming languages. It is indeed  common for professional programmers to resort to writing small “throw away” programs in scripting languages rather than their day to day “professional” languages because of the perceived (and often real) ease of doing simple things simply in scripting languages.

Had it not been for “Web 2.0” the above may well have been all that one needs to say about scripting languages. But the new reality is that JavaScript, which strongly resembles scripting languages in its nature, has become a very important programming language used for applications that seldom resemble batches of commands entered into interactive programs by non professional programmers. Likewise other languages such as Perl, Python, Ruby and Lua, which are scripting languages that sometimes are used to write scripts, have grown up to become much more general purpose and are more often than not used to write ambitious programs.

Furthermore, non scripting languages, have gradually acquired many of the abilities and characteristics of scripting languages. For example, C# runs in an “execution environment” and now has support for dynamic typing and various forms of dynamic code loading. REPL support is on the way. On the whole, the language appears on track to subsume most of the features of scripting languages, except for simplicity (and most established scripting languages are far from simple these days).

As a result, I no longer think of scripting languages are a world apart. To me, they are just more programming languages. The foundations were are to concern ourselves with are simply, how can we discipline dynamic typing and dynamic code loading to make programs better behaved and easier to analyze, while maintaining the power and ease of use that comes with such free wheeling ways.