Wolfram Computation Meets Knowledge

Symbolic Programming Visualized

Symbolic programming has been a core idea in Mathematica since the very beginning. But it is a big idea and an abstract idea. And people understandably just want to know what the bottom-line benefit is, and could care less about what went into making it happen. Fortunately, Mathematica 6 is making it a lot easier to illustrate ideas about symbolic computation in visual and interactive forms.

High-Level Functions

For starters, illustrating the core programming primitives with visual examples is a piece of cake with the new graphics and typesetting functions. For example, Map will take a function and apply it to each element in a list:

In[1]:= Map[Framed, {a, b, c, d, e}]  |  Out[1]:= {[a], [b], [c], [d], [e]}

NestList will take a function and apply it over and over again to the initial seed, returning a list of all the iterations:

In[2]:= NestList[Magnify, a, 4] | Out[2]:= {a, a, a, a, a}

Programming in Mathematica is based on transforming trees. The built-in function TreeForm allows us to visually represent the tree backbone of Mathematica programs and data structures:

In[3]:= TreeForm[a+b^2+c^3+d] | Out[3]/TreeForm:= Plus a Power Power d b 2 c 3

System-Wide Design and Integration

The symbolic language of Mathematica allows us to create simple structures that are then highly integrated everywhere in the system. There are lots of good examples in mathematics and in programming (for example Piecewise), but user-interface structures make the point in a visual way.

Take, for example, Tooltip, which is used inside documents and inside 2D and 3D graphics—even functions like Plot can use it to automatically “tooltip” different curves. Here is a minimal Tooltip illustrating its syntax:

In[4]:= Tooltip[some text, its tooltip] | Out[4]:= some text its tooltip

The various plotting functions have been taught about Tooltip, so Mathematica will compute the curve using a variety of technologies and then apply Tooltip appropriately to the resulting graphics:

In[5]:= Plot[{Tooltip[BesselJ[1, x], Bessel 1], Tooltip[BesselJ[2, x], Bessel 2]}, {x, 0, 10}, Filling -> Axis] | Out[5]:= Bessel 2

If you are constructing your own graphics out of a set of pieces, you can just wrap Tooltip around any polygon or other shape, and its location and behavior will be automatically taken care of. Here we build up a map of Africa, using each country’s flag as its Tooltip:

Graphics[{EdgeForm[Red], Tooltip[CountryData[#,

One thing I really appreciate from a design standpoint is that buttons and mouseovers work in exactly the same way, using the same minimal syntax. For example, if we want the countries to highlight when we mouse over them, we just make a Mouseover with a polygon in a different color:

Graphics[{EdgeForm[Red], Mouseover[CountryData[#,

What makes this possible is the fact that Tooltip and other such features are not merely functions or objects—they’re lightweight declarative descriptions that can easily be passed around from one structure to the next. They have simple, clear meanings, and there is no overhead involved in setting them up. Therefore, it’s easy to incorporate them into the design of other functions, essentially “teaching” different parts of the system—like graphics, or plotting functions—about their existence.

Ridiculous Levels of Generality for Free

Mathematica’s use of symbolic programming allows its algorithms to operate at the appropriate level of abstraction. This makes code simpler, cleaner and more general. For example, this algebraic expansion doesn’t care what abstract entities it is dealing with:

In[8]:= Expand[(1 + )^3] | Out[8]:= 1 + 3  + 3(  )^2 + ( )^3

A somewhat more useful example is drawing a graph, where we want the nodes to be represented by graphics:

GraphPlot

The fact that the GraphPlot function can trivially accommodate graphics in its syntax is just one of many useful consequences of the generality of Mathematica, as is the fact that I can take those graphics from anywhere and just paste them in as arguments to the function as if they were text as an alternative to laboriously using code to get them to massage into the right place in some complicated structure.

I’ll be writing more about symbolic programming in the future, particularly on what symbolic programming really means and how its structures compare to other languages.