Defining new format wrappers in Mathematica

One problem I had with the expression-to-C converter is that CForm converts negations of terms into a negation of parenthesized terms.

For example:

In[1]:= -a b // CForm

Out[1]//CForm= -(a*b)

That looks ugly. I tried to define a new format for Times[-1, v], but this requires unprotecting Times, and led to an infinite recursion when I tried to use it. I finally found a suggestion on how to define whole new format wrappers on the comp.soft-sys.math.mathematica list, in a message posted by Carl Woll (a Wolfram employee). This is how it works:

This assignment marks CCForm (my new formatter) as a format wrapper.

In[2]:= Format[CCForm[expr_], CCForm] := expr

Note that the Out[3] text shows the new formatter name.

In[3]:= 2 + 3 // CCForm

Out[3]//CCForm= CCForm[5]

It’s showing the CCForm wrapper, though, which we don’t want to look at, so we define a top-level format for CCForm that replaces it with its argument.

In[4]:= Format[CCForm[expr_]] := expr

Now, the output looks correct.

In[5]:= 2 + 3 // CCForm

Out[5]//CCForm= 5

The case I’m trying to fix isn’t helped by this. We need to make it produce the CForm.

In[6]:= -a b // CCForm

Out[6]//CCForm= -a b

In[7]:= Format[CCForm[expr_]] := CForm[expr]

In[8]:= -a b // CCForm

Out[8]//CCForm= -(a*b)

We don’t want the result to be evaluated, so we add a HoldForm.

In[9]:= Format[CCForm[expr_]] := HoldForm[CForm[expr]]

In[10]:= -a b // CCForm

Out[10]//CCForm= -(a*b)

Now it’s in CForm, but we still have the parenthesis. I don’t understand just why this works, but making CCForm HoldAll fixes the problem.

In[11]:= SetAttributes[CCForm, HoldAll]

In[12]:= -a b // CCForm

Out[12]//CCForm= -a * b

This also prevents evaluation of the expression being formatted.

In[13]:= 2 + 3 // CCForm

Out[13]//CCForm= 2 + 3

Note that CForm does what I want if it’s made HoldAll.

In[14]:= -a b // CForm

Out[14]//CForm= -(a*b)

In[15]:= SetAttributes[CForm, HoldAll]

In[16]:= -a b // CForm

Out[16]//CForm= -a*b

Although it’s not styled as nicely as the CCForm version, and could mess up existing code, so we won’t do that.

In[17]:= ClearAttributes[CForm, HoldAll]

Now I can use CCForm instead of CForm for the output formatting of my converter, and have nicer-looking results.



, ,