I think I’m going to go back to programming
in APL and Lisp. The concepts
and methodologies of decades
ago are being reborn in today’s languages,
like Microsoft’s C# and Sun’s Java.
Of course, languages like C#, C++, and
Java were designed to take advantage of
other object-oriented precursors such
as Simula and SmallTalk.
However, in trying to minimize
the complexity of the new languages,
designers left out many features. Some
of these features found their way back
into the new languages through runtime
support or extensions that can be
added within the language’s normal
extension mechanisms.
Yet in many cases, a fundamental
change is necessary to the syntax
or semantics. These types of changes
aren’t taken lightly, since they can break
existing applications. Still, enhancing
a language this way can have a major
impact on developers in areas such as
efficiency and code quality.
I Say Tomato, You Say...
Lisp is built around lists and lambda
expressions. Lambda expressions are
closures that include any bound variables
at the time the closure is created.
Take this short interactive Lisp session:
> (define timesN (lambda (N)
(lambda (x) (* x N)))
> ((timesN 4) 3)
12
The timesN variable is assigned a
lambda expression that takes a single
parameter. It returns another lambda
expression that also has a single parameter.
The difference is that the inner
unnamed lambda expression references
the N parameter.
The first parameter of a list being
evaluated in Lisp is the function to be
executed. This works recursively so the
second statement executed in the example
evaluates (timesN 4), which returns
a lambda expression that will multiply
its parameter by four. In this example,
it is applied to parameter 3 with a result
of 12. As shown, lambda expressions are
first-class values that can be stored and
passed as parameters.
I Say Delegate, You Say...
C# 2.0 introduced the concept of
anonymous methods, which allowed
the creation of method definitions
without names that are common in
the callback approach commonly
used throughout Microsoft’s Windows
operating system. This was more
shorthand than a radical semantic
enhancement because the same thing
could be done, albeit with more textual
decorations.
C# 3.0 adds explicitly or implicitly
typed lambda expressions to the mix.
In the latter case, the types are inferred
from the surrounding code context.
The syntax is simpler as well.
(int x) => return x * 4;
Similar closure functionality is being
considered for Java 7.
From a C# or Java developer’s point
of view, enhancements like lambda
expressions are favorable additions.
Their implementation may lack the
elegance and consistency of Lisp since
the new features are tacked on rather
than part of the original language definition.
But, elegant or not, they will get
a lot of use.
So what about C and C++, since
they’re used in the bulk of embedded
applications? Callback functions are
already the norm, but two issues crop
up: syntax and garbage collection.
Syntax is arbitrary since there is no
standard. C macros and C++ class definitions
can hide this, though an implementation
may have to deal with ugly
issues such as casting void* pointers.
Memory allocation is more problematic
since the memory must be explicitly
deallocated. C++ has the edge over C
here. With C++, though, developers still
need to deallocate the closure. Either
way, the solution isn’t very elegant.
Microsoft • www.microsoft.com
Sun • www.sun.com