Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I've noticed that Mathematica 8 seems to have some kind of string interpolation feature, but I couldn't find any documentation on it and I can't figure out how it works.

For example, if I enter

StringForm["x=``", 1 + 2]

in a notebook and evaluate it, I get the string "x=3". If I select that cell and choose Cell->Convert To->StandardForm (Ctrl-Shift-N], Mathematica converts the cell to an expression that looks like this:

"x=\!\(1 + 2\)"

that also evaluates to "x=3"

However, if I enter the exact same character sequence on a new cell, it evaluates to "x=1 + 2".

My question is: Is this documented somewhere? How does it work?

share|improve this question
2  
If you haven't already seen it, the tutorial String-Oriented Output Formats contains some useful information. –  kguler Feb 20 '12 at 10:07
    
@kguler would you please give me your output for: Attributes[StringForm] –  Mr.Wizard Feb 20 '12 at 10:14
    
@Mr.Wizard, Attributes[StringForm] gives {Protected} (version 8.4). –  kguler Feb 20 '12 at 10:16

4 Answers 4

up vote 8 down vote accepted

StringForm does not create a string. As StringForm["x=``", 1] // FullForm will show you, it stays unevaluated. But it is shown in a special way in the notebook (i.e. the `` replaced by 1).

You can create a plain string from it using

ToString[ StringForm["x=``", 1] ]

which will give

"x=1" 

Unfortunately, when we need to build strings, this does not always work perfectly:

ToString[ StringForm["x=``", 1/2] ]

  1
x=-
  2

This gave the result as a three-line string, in OutputForm. We can try ToString[ StringForm["x=``", 1/2], InputForm ], but it'll return "StringForm[\"x=``\", 1/2]" (unformatted). We can also try ToString[ StringForm["x=``", 1/2], StandardForm], but the result will be a string containing box expressions (as you noticed). These special expressions can contain information about formatting (everything from font styles to two-dimensional math such as $\frac{1}{2}$), but they can only be shown in a Mathematica notebook. They are not human readable and cannot be used by other programs.

To get the desired "x=1/2", the workaround is

ToString@StringForm["x=``", InputForm[1/2]]

Recap:

  • StringForm does not change the expressions passed to it at all. StringForm expressions are merely displayed specially in notebooks.

  • How StringForm is displayed depends on the output format set (OutputForm, StandardForm, TraditionalForm, etc.)

  • Use ToString to obtain an actual string.

share|improve this answer
1  
Why not simply ToString@StringForm["x=``", InputForm[1/2]] ? –  Mr.Wizard Feb 20 '12 at 10:18
    
@Mr.Wizard Fixed before I saw your comment. –  Szabolcs Feb 20 '12 at 10:20

On version 7 I get this using Show Cell Expression (Ctrl+Shift+E) on the output cell:

Mathematica graphics

If you use InputForm you get:

StringForm["x=``", 1 + 2] // InputForm
StringForm["x=``", 3]

Which makes it clear this is a wrapper.

On your version it appears that StringForm has attribute HoldRest so that 1 + 2 is preserved in that wrapper.

As far as I know no evaluation ever takes place automatically inside a string itself, therefore entering "x = 1 + 2" by itself with any kind of trim will not result in "x = 3".

share|improve this answer

I think the key to understand what happens under the hood is that cells contain boxes which will be rendered by the frontend and sent to the kernel for evaluation. Using "Convert To" -> "StandardForm" will modify this box structure ("Cell" -> "Show Expression" or Ctrl-Shift-E to see the box structure before and after using it). Using convert to standardform on StringForm is an edge case which produces something that is probably causing more trouble than benefit, namely an InterpretationBox. This will show as one thing but evaluate as something else. You can create interesting effects with them, e.g. a string within an identification process (evaluate the cell that the following CellPrint creates):

CellPrint[
  Cell[BoxData[
    InterpretationBox[
       "\"I am a string but would rather be a plot!\"", 
       Plot[x, {x, 0, 1}]
    ]
 ], "Input"]
]

I probably should add that InterpretationBox of course has many use cases where it causes more benefit than trouble and that it is nothing new but has existed at least since version 4.

share|improve this answer

As mentioned before StringForm together with ToString will give the desired results.

Here are some examples, that reproduce the functionality that is provided in other languages by sprintf (or similar functions):

myStrings = {
   ToString[StringForm["This is a floating point: `1`\n" , 
     ToString[NumberForm[5.6 10^9, NumberFormat -> (SequenceForm[#1, "e", #3] &)]]
   ]],

   ToString[StringForm["This is a integer in blocks : `1`\n" ,
     ToString[NumberForm[10^9, DigitBlock -> 3]]
   ]],

   ToString[StringForm["This is a number with funny padding : `1` " , 
      ToString[NumberForm[6.888, {7, 3}, NumberPadding -> {"_", "0"}]]
   ]],

   ToString[StringForm["This is just a string : `1` " , "FOO"]]
   };
myCompleteString = StringJoin[myStrings]

FullForm[myCompleteString]

Export["text.txt", myCompleteString, "Text"]

this will give you:

This is a floating point: 5.6e9
This is a integer in blocks : 1,000,000,000
This is a number with funny padding : ____6.888 This isjust a string : FOO 

"This is a floating point: 5.6e9\nThis is a integer in blocks : 1,000,000,000\nThis is a number with funny padding : ____6.888 This is just a string : FOO "

and a file text.txt with the expected output.

See also these discussions:

*) Converting a large floating-point number to a single-line string

*) sprintf() or close equivalent, or re-implementation?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.