Jeff (moonlessnights) wrote in ood,

  • Mood:
  • Music:

Language without control structure

One of the things I have always liked about Smalltalk is that the language has no built-in concept of control structures. That is to say that structures such as if then else and various types of loops are not special, within the language, as they are within imperative languages. Specifically, I will be talking about the ifTrue: and ifFalse: messages and how they are actually directly reducible to the control flow structures in the lambda calculus model of computation.

First of all, one must realize that Smalltalk is a purely object oriented language with purely dynamic types. That is to say that the language consists of essentially three things: classes, objects, and messages (self people will claim that having classes makes Smalltalk not pure but you get the idea). Given an object, a message sent to that object (potentially having other objects as arguments) will return an object (or nothing). This paradigm is very powerful and is even used to get basic control flow without extending the language. Observe this snippet for an example:

(5 < 7) ifTrue:[self doSomething] ifFalse:[self doSomethingElse].

In this example, the object 5 (an instance of the Integer class with value 5) is sent the < message with the argument 7 (another Integer object). The result will be an object of type Boolean (an abstract class - although such things don't exist in Smalltalk, in the loaded sense of the term). In this case, an instance of the Boolean subclass True. Boolean objects have the message ifTrue:ifFalse: as well as the conveniences ifTrue: and ifFalse:, alone. These messages take code blocks (a special type of Smalltalk argument which is interpreted by the VM using normal order reduction (lazily)) and the True subclass overrides the message to invoke the argument to the ifTrue: segment while the False invokes the ifFalse:. As a result, control flow occurs without an actual grammar rule for it.

I always thought this was pretty neat and a good example of how a powerful paradigm can scale. Smalltalk is also interesting in that doing so doesn't make the code hard to understand or excessively long. Something I only found out recently, however, is that this is exactly how control flow is done in the lambda calculus (however, it uses applicative order reduction (eager)). Observe this example of the above operation (I will call the method doSomething A and doSomethingElse B):
(LaTeX notation, since that is as good as any)
(\lambda x. \lambda y. x) A B

In this example, I just hard-coded the comparison of (5 < 7) as true (\lambda x. \lambda y. x) since programming in the lambda calculus is ugly as hell and would have required me writing some really complicated predicate.

In both the lambda calculus example and the Smalltalk example, we see that the value of the predicate does the work of selecting whether we execute the true branch or the false branch of the condition. I found it interesting to notice this since I normally wouldn't have expected a very high level object oriented language to mirror a model of computation (a functional model of computation, at that) in such a direct way.

Any other observations?
  • Post a new comment


    default userpic