A Brief Survey of Dynamic Programming Languages

A lot has been written about static languages lately. I am going to focus on dynamic languages. Dynamic languages allow the programmer to develop software by interacting with a “live” language system. The system accepts input and gives feedback about that input immediately as it is entered and evaluated. This encourages an experimental approach to programming. What happens when I do this? Just do it and find out immediately.

I talked at some length about the oldest dynamic language, Lisp, last time. As such, it provides an example of many of the features of subsequent languages. It is classified as a multi-paradigm language. This means that it supports many different styles of programming. You have probably heard of object-oriented programming. Lisp has a very flexible object system called CLOS (Common Lisp Object System). You may have heard of functional programming. Without going into great detail about the details of what functional programming is, Lisp was one of the first languages to treat functions as directly manipulable elements. Lisp also supports rule-based programming, aspect oriented programming, and many other programming paradigms. It has been said that most new languages are just adding features that were pioneered by Lisp.

What other dynamic languages are there? Another venerable and influential dynamic language is Smalltalk. It was developed by researchers at Xerox’s Palo Alto Research Center (PARC). It was the first language to treat every element in the langage as an object. It also was a complete system including editors, code browsers, and a host of other tools, all written in Smalltalk. The system is programmed by interactively defining new objects that are immediately available for use as soon as they are defined. The entire system is graphically oriented. Many of the concepts of modern graphical systems were first introduced by Smalltalk. Unsurprisingly, there are a number of implementations of Smalltalk in use today.

Another dynamic language that has been around for a long time is Forth. Forth is another language that inspires strong opinions. Programmers either love it or hate it. It has been described as write only. It is based on the idea of using a temporary data structure called the stack to temporarily store operands to be used in subsequent computations. The stack is a mechanism where the programmer can “push” values onto the stack and later “pop” the last item pushed. All operations are done on the latest item pushed. This allows an arbitrary number of temporary values to be readily accessible. It also requires the programmer to keep track of exactly what has been pushed onto the stack at any point in the execution of their program. Hence, the “write only” label.

Forth allows the programmer to define new functions interactively through the use of a REPL (Read, Eval, Print, Loop). This is a key feature of dynamic languages and goes a long way toward making up for the cognitive load of keeping track of the contents of the stack.

One of the more recent dynamic language to gain popularity is Ruby. Ruby was inspired by Lisp but adopts the Smalltalk stance that everything is an object. It first gained widespread notice because of a popular web framework written in Ruby called Ruby on Rails. Many of the best practices of modern programming have originated in the Ruby community.

The last dynamic language that I’m going to talk about in this post has had a rather profound impact on computing in the last couple of years. I’m talking of course about Python. Python is an interesting language. Noted for the use of indentation to indicate the start and end of computing blocks and the ease of using code libraries written in other static languages, it has captured the hearts of scientists and educators alike. It is the lingua franca of the popular inexpensive computer the Raspberry Pi. It has carved out a place for itself as probably the most popular modern dynamic language.

In future posts, I’ll talk more about each of these languages and even show some examples of what programs written in them looks like.

A Short Essay on the Process of Programming

I approach programming as an exploratory process. I can’t seem to bring myself to sit down and plan a program out in minute detail beforehand. The truth is, any program that I understand well enough to plan out in minute detail beforehand, doesn’t interest me in the slightest. I want my programs to teach me something I didn’t know when I started writing them.

Consequently, I usually start out with some vague idea for a program. I write the shortest little bit that might work and compile and run it. Even better, I use an interpreted language like Lisp or scheme or ruby so that I can skip the compile part. I love dynamic languages!

At first, I find myself exploring the boundary between the language and the environment. For example, I have spent hours exploring the Dir module in ruby. I have spent similar amounts of time exploring similar functionality in Common Lisp. Knowing how to traverse the file system in a given language is an important detail.

Another facility that I often dwell on is the reflective capability of a language, that is the ability of a language to know or discover details of its structure. For example, most symbols in ruby have a method methods that returns an array of methods that the object implements. methods is a reflective method. It allows the programmer to discover details about the programming environment dynamically at run time. Reflection is also called introspection.

Java implements reflection, demonstrating that languages not typically considered dynamic can be introspective too. The clever trick to Java reflection is that Java doesn’t create data structures to describe itself until you actually need them. This adheres to one of my favorite principles that states “you shouldn’t have to pay for features that you don’t use.” I’ve heard this principle called parsimony.

The underlying theme to these language features is that they all help make a language more adaptive. One of the key characteristics of human intelligence is our ability to distance ourself from a situation and analyze it with detachment. This is an important part of our ability to adapt to rapid changes in our environment. The ability of someone to reason about their relationship to their environment is essential to intelligent behavior.

Now I’ve really tipped my hand. The romantic notion that has captured my imagination is the quest for emergent intelligent behavior or Artificial Intelligence as it is commonly called. I try to avoid the term Artificial Intelligence because I find that neither the word Artificial nor the word Intelligence lend themselves to unambiguous definition, much less objective measurement. In fact, many of the great debates in the field revolve around this shortcoming.

To be continued.