Symbolic Programming

Mathematica does a form of FunctionalProgramming and does symbolic math. Wolfram chooses to call this "SymbolicProgramming".

Note that it appears that this term differs from FunctionalProgramming only in its use by StephenWolfram and his company, WolframResearch, in promoting MathematicaPackage (which is indeed a powerful tool), and as such apparently means "whatever cool programming features that Mathematica offers". My understanding based on limited use of Mathematica is that it is a multi-paradigm tool, so the definition probably cannot be made truly concise in any case.

That is, "symbolic programming" in the Mathematica sense does not appear to be a term that has caught on in the rest of the world outside Wolfram/Mathematica.

Mathematica is a symbolic computer algebra system. They use symbolic in the mathematical sense.

I said what I meant. I know Macsyma, I know Mathematica, I know Lisp, and I'm telling you, Wolfram uses the phrase "symbolic programming" as a marketing term, with a meaning specific to Mathematica, not shared by e.g. Macsyma nor the rest of the non-Mathematica world. I know what I'm talking about; you go do your own homework.

For example, if you do 1.0/3*3 in, say, C, it divides 1.0 by 3 and then multiplies the result by 3. You get 0.9999999999998. Mathematica (and other symbolic mathematics software, for example Macsyma/Maxima) treats numbers as symbols... Like, 1/3*3 is not a lot different from a/b*b until you need the actual result in numeric form. Since a/b*b is a, 1/3*3 is 1. No computation with actual numeric values needed.

Yeah, yeah, yeah. True, and irrelevant.

Also, I don't think that SymbolicProgramming is all that new. LispLanguage is symbolic. The second oldest high level programming language.

Yeah, yeah, yeah. True, and irrelevant. I'm telling you, that's not the same thing as what Wolfram means by the term

Example from Macsyma:

 C1: expand((a+b)^2);
 A^2 + 2*A*B + B^2
Yeah, yeah, yeah, been there, done that, got the T-shirt, wrote my own computer algebra system. This is all irrelevant to my point.

Isn't this like meta programming? For example a lisp function (or any language) could do exactly above.

 CL-USER> (expand '(^ (+ a b) 2))
 ==> (+ (^ a b) (* a b) (^ b 2))

Then combine with Macro and variable binding we could have execute this

 CL-USER> (let ((a 1) (b 2))
            (expand-m (^ (+ a b) 2)))  ;expand as above and put it as code.
 ==> ;return the result of computing.


"Major new approaches to programming happen rarely and, when they do, they are often absorbed slowly. With the ObjectOrientedProgramming approach to software design now widely adopted, the world seems ready for another, even more dramatic change - symbolic programming. This methodology has now reached the point where it can be put to use immediately, enabling a new generation of computing throughout engineering." -- Originally published in IEEE Spectrum, January 1999, excerpt from http://www.wolfram.com/news/germundsson.html

"In this paradigm all different kinds of objects - formulas, lists, data, and graphics, to name a few - are represented in a uniform way as expressions. A prototypical example of a Mathematica expression is f[x]. This expression can represent a mathematical function, a graphic, a sound, a program, or even a complete Mathematica notebook. Functions can be both input and output of another function, enabling very concise and simple coding. Also, since algorithms can be parameterized not only by numbers or some fixed number of parameters but also by functions, algorithms are infinitely more flexible." http://www.wolfram.com/products/mathematica/technologies/programming.html

Another excerpt: "With all objects represented in a uniform way, computing reduces to just one fundamental operation: transforming one expression into another. Such uniformity makes it possible to mix different programming styles, just as it lets different domains of engineering and mathematics be combined."

So... this "major new approach to computing" wouldn't have been invented by JohnMcCarthy about forty years ago, then?

Pure double-speak, check out the examples.

Which bit is double-speak, and what examples am I to check out? There's nothing mentioned in the article referenced above that can't be done fairly quickly and easily by anyone who cares to using a LispLanguage. Indeed, a lot of people have already done this sort of thing using a Lisp. If you want symbolic programming to mean stuff that languages like MercuryLanguage make easy, then the article does not well serve your purpose, I think.


"...computing reduces to just one fundamental operation: transforming one expression into another."

How is this different from FunctionalProgramming?

There is more to computing than transformations. How would side effects be represented? FunctionalProgramming and LogicProgramming make writing programs with side effects more complicated than most people are willing to put up with. Would SymbolicProgramming have the same drawback?


As far as I can see, the big difference between a real FunctionalProgrammingLanguage and things like Mathematica is that Mathematica is not confluent, that is, different evaluation orders may lead to different results. For example, in Mathematica F[1+2] can produce something different than F[3]. In Lisp, macros can make such distinctions, but in Mathematica, every function has such capabilities. In interpreting something like F[x], it is not enough to know that x was bound to 1+2, we also need to know if 1+2 was evaluated before being bound to x. All this evaluation-order-dependency allows many new exciting ways to introduce bugs.


Here's a pquestion - how do you combine OO with SymbolicProgramming? For instance suppose you had Current, Voltage, Resistance, CurrentDensity? classes but you wanted to store the equations symbolically in the most compact form, and use a solve() method as needed. I'm thinking you could have an Equation Class to store the formulas, but then how do you chose the most compact set before hand? Obviously for a small set it would be easier to just hard code them without SymbolicProgramming but what if you wanted to map hundreds of equations to the respective classes of the variables? For example (pseudo-python)

  class Equation:
    Eqns =       [Voltage(v)=Current(i)*Resistance(r),      [CurrentDensity?(J)=Current(i)/Area(A),    ...]
   def simplify(self,eqn):
     ...
   def solve(self,eqn):
    ...

class Current: def value(self,Vars): e=Equation() return e.solve(Vars,"i")

class CurrentDensity?: def value(self,Vars): e=Equation() return e.solve(Vars,"J")

def Voltage: def value(self,Vars): e=Equation() return e.solve(Vars,"V") ...etc
Is this an instance of the StrategyPattern? Would it be better to store the equation in the most "representative" class ie store V=I*R in Voltage and not in an Equation class?

I think one way of doing what you want is to use an implementation of a GroebnerBasis. There is such a thing included with SymbolicCpp, which implements symbolic expressions in CeePlusPlus using an internal tree representation. I have used that code. There may be other implementations. -- JohnFletcher

The input is appreciated. The notion of basis did occur to me i.e. the smallest set of equations against which others could be referenced. But more than this both representations seem to describe the same thing, there must be a mapping between them. Not trying to build anything in particular right now, just seems to me another type of ImpedanceMismatch. Trying to understand what the correct transformer between them would be. Note I'm not saying there is any problem building a SymbolicProgramming system using OO - SymbolicCpp obviously already is. But once you have generic classes that can solve(),simplify(),expand() etc and you want to build DomainObjects? to take advantage of that functionality, what kind of patterns apply?


It's a fine distinction, but with symbolic languages equations can be compared against e axioms and theorems:

  e(del*'H'='Jc'+d('D')/d(t)).
  query: e(del*'H'=Q) returns Q='Jc'+d('D')/d(t);

as well as referenced by a label such as:

  e2(del*'H'='Jc'+d('D')/d(t),amperes_law).
  ?- e2(E,amperes_law) -> del*'H'='Jc'+d('D')/d(t);


See also SymbolicCpp, MathematicaLanguage


EditText of this page (last edited August 16, 2009) or FindPage with title or text search