Function Repository Resource:

ToCompressedBoxes

Source Notebook

Generate boxes corresponding to the printed form of an expression that are compressed where possible

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["ToCompressedBoxes"][expr]

generates boxes corresponding to the printed form of expr using compression where appropriate.

ResourceFunction["ToCompressedBoxes"][expr,form]

gives the boxes corresponding to expr in the specified form.

Details and Options

ResourceFunction["ToCompressedBoxes"] typically produces smaller results than ToBoxes (particularly when images are involved).
ResourceFunction["ToCompressedBoxes"] uses any relevant definitions given for Format and MakeBoxes.
You can see how box structures generated by ResourceFunction["ToCompressedBoxes"] would be displayed by using DisplayForm or RawBoxes.

Examples

Basic Examples (2) 

Generate a compressed box representation of an image:

In[1]:=
ResourceFunction["ToCompressedBoxes"][ConstantImage[0, {100, 100}]]
Out[1]=

Display boxes as formatted:

In[2]:=
RawBoxes[%]
Out[2]=

Compare to ToBoxes:

In[3]:=
ToBoxes[ConstantImage[0, {100, 100}]]
Out[3]=

Convert an expression to its box representation:

In[4]:=
expr = ResourceFunction["BirdSay"]["neat"]
Out[4]=
In[5]:=
Short[compressed = ResourceFunction["ToCompressedBoxes"][expr]]
Out[5]=

Check the size:

In[6]:=
ByteCount[compressed]
Out[6]=

Compare to ToBoxes:

In[7]:=
uncompressed = ToBoxes[expr];
ByteCount[uncompressed]
Out[8]=

Check the appearance of both:

In[9]:=
RawBoxes /@ {compressed, uncompressed}
Out[9]=

Scope (5) 

Use the second argument of ToCompressedBoxes to choose the format type:

In[10]:=
{b, w} = ResourceFunction["PartyParrot"][{"Birdnardo", "PartyWolf"}];
In[11]:=
ResourceFunction["ToCompressedBoxes"][Limit[w[x], x -> b], TraditionalForm] // RawBoxes
Out[11]=
In[12]:=
ResourceFunction["ToCompressedBoxes"][Integrate[f[b, w], b], StandardForm] // RawBoxes
Out[12]=

Using a single argument is equivalent to choosing StandardForm:

In[13]:=
ResourceFunction["ToCompressedBoxes"][f[b]/g[w]] // RawBoxes
Out[13]=
In[14]:=
ResourceFunction["ToCompressedBoxes"][f[b]/g[w], StandardForm] // RawBoxes
Out[14]=

Compare to TraditionalForm:

In[15]:=
ResourceFunction["ToCompressedBoxes"][f[b]/g[w], TraditionalForm] // RawBoxes
Out[15]=

Reduce the box size of large Iconize expressions:

In[16]:=
data = Iconize[IdentityMatrix[250]]
Out[16]=
In[17]:=
ResourceFunction["ToCompressedBoxes"][data]
Out[17]=

Check the size:

In[18]:=
ByteCount[%]
Out[18]=

Compare to ToBoxes:

In[19]:=
ByteCount[ToBoxes[data]]
Out[19]=

Use Unevaluated to yield behavior like MakeBoxes instead of ToBoxes:

In[20]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/7ae304f9-72f0-44c3-869f-254fd4a894af"]
Out[20]=
In[21]:=
RawBoxes[boxes]
Out[21]=

Without Unevaluated, the given expr will evaluate:

In[22]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/3f41f030-9825-456b-a6f9-bdbc390b917b"]
Out[22]=
In[23]:=
RawBoxes[boxes]
Out[23]=

The boxes produced by ToCompressedBoxes can be smaller than ToBoxes even when raster boxes are not involved:

In[24]:=
expr = ComplexPlot3D[(z^2 + 1)/(z^2 - 1), {z, -2 - 2 I, 2 + 2 I}]
Out[24]=
In[25]:=
compressed = ResourceFunction["ToCompressedBoxes"][expr];
ByteCount[compressed]
Out[21]=
In[26]:=
uncompressed = ToBoxes[expr];
ByteCount[uncompressed]
Out[23]=

Check the display form:

In[27]:=
RawBoxes /@ {compressed, uncompressed}
Out[27]=

Applications (2) 

Compress data stored in a DynamicModule:

In[28]:=
dm = DynamicModule[{n = Sort[RandomInteger[10, 1000]], i}, Column[{Slider[Dynamic[i], {1, 1000}], Dynamic[n[[i]]]}]]
Out[28]=
In[29]:=
ResourceFunction["ToCompressedBoxes"][dm]
Out[29]=
In[30]:=
ByteCount[%]
Out[30]=

Define custom formatting for a function using MakeBoxes:

In[31]:=
gplus /: MakeBoxes[gplus[x_, y_, n_], StandardForm] := RowBox[{MakeBoxes[x, StandardForm], SubscriptBox["\[CirclePlus]", MakeBoxes[n, StandardForm]], MakeBoxes[y, StandardForm]}];
In[32]:=
gplus[x, y, z]
Out[32]=

ToCompressedBoxes uses the new formatting automatically:

In[33]:=
ResourceFunction["ToCompressedBoxes"][gplus[x, y, z]]
Out[33]=
In[34]:=
RawBoxes[%]
Out[34]=

Properties and Relations (2) 

ToCompressedBoxes will be equivalent to ToBoxes when there is nothing to compress:

In[35]:=
ResourceFunction["ToCompressedBoxes"][a + b^2]
Out[35]=
In[36]:=
ToBoxes[a + b^2]
Out[36]=

Boxes produced by ToCompressedBoxes will usually round-trip to other formats without significant changes in size:

In[37]:=
img = \!\(\*
NamespaceBox["LinguisticAssistant",
DynamicModuleBox[{Typeset`query$$ = "picture of a cat", Typeset`boxes$$ = RowBox[{
TemplateBox[{"\"domestic cat\"", 
RowBox[{"Entity", "[", 
RowBox[{"\"Species\"", ",", "\"Species:FelisCatus\""}], "]"}], "\"Entity[\\\"Species\\\", \\\"Species:FelisCatus\\\"]\"", "\"species specification\""}, "Entity"], "[", 
TemplateBox[{"\"image\"", 
RowBox[{"EntityProperty", "[", 
RowBox[{"\"Species\"", ",", "\"Image\""}], "]"}], "\"EntityProperty[\\\"Species\\\", \\\"Image\\\"]\""}, "EntityProperty"], "]"}], Typeset`allassumptions$$ = {{"type" -> "Clash", "word" -> "cat", "template" -> "Assuming \"${word}\" is ${desc1}. Use as ${desc2} instead", "count" -> "2", "Values" -> {{"name" -> "Species", "desc" -> "a species specification", "input" -> "*C.cat-_*Species-"}, {"name" -> "CatBreedClass",
           "desc" -> " referring to cat breeds", "input" -> "*C.cat-_*CatBreedClass-"}}}}, Typeset`assumptions$$ = {}, Typeset`open$$ = {1}, Typeset`querystate$$ = {"Online" -> True, "Allowed" -> True, "mparse.jsp" -> 1.7209433, "Messages" -> {}}}, 
DynamicBox[ToBoxes[
AlphaIntegration`LinguisticAssistantBoxes["", 4, Automatic, 
Dynamic[Typeset`query$$], 
Dynamic[Typeset`boxes$$], 
Dynamic[Typeset`allassumptions$$], 
Dynamic[Typeset`assumptions$$], 
Dynamic[Typeset`open$$], 
Dynamic[Typeset`querystate$$]], StandardForm],
ImageSizeCache->{119.8, {9., 15.8}},
TrackedSymbols:>{Typeset`query$$, Typeset`boxes$$, Typeset`allassumptions$$, Typeset`assumptions$$, Typeset`open$$, Typeset`querystate$$}],
DynamicModuleValues:>{},
UndoTrackedVariables:>{Typeset`open$$}],
BaseStyle->{"Deploy"},
DeleteWithContents->True,
Editable->False,
SelectWithContents->True]\)
Out[37]=
In[38]:=
box1 = ResourceFunction["ToCompressedBoxes"][img];
In[39]:=
ByteCount[box1]
Out[39]=

Convert to a String and back:

In[40]:=
rt1 = ToExpression[ToString[box1, InputForm]];

The size is unchanged:

In[41]:=
ByteCount[rt1]
Out[41]=

ToBoxes will yield NumericArray objects in rasters, which are efficient when packed:

In[42]:=
box2 = ToBoxes[img]
Out[42]=
In[43]:=
ByteCount[box2]
Out[43]=

However, these will not round trip as well as the boxes produced by ToCompressedBoxes since GraphicsBox prevents evaluation:

In[44]:=
rt2 = ToExpression[ToString[box2, InputForm]]
Out[44]=
In[45]:=
ByteCount[rt2]
Out[45]=

The size increased by a factor of 32:

In[46]:=
%/ByteCount[rt1] // Round
Out[46]=

Both forms are equivalent when passed to the front end for display:

In[47]:=
RawBoxes[rt1]
Out[47]=
In[48]:=
displayed1 = NotebookRead[PreviousCell[]]
Out[48]=
In[49]:=
RawBoxes[rt2]
Out[49]=
In[50]:=
displayed2 = NotebookRead[PreviousCell[]]
Out[50]=
In[51]:=
First[displayed1] === First[displayed2]
Out[51]=

Possible Issues (1) 

ToCompressedBoxes trades time for space:

In[52]:=
expr = ConstantImage[Red, {1000, 1000}];
In[53]:=
RepeatedTiming[ByteCount[ResourceFunction["ToCompressedBoxes"][expr]]]
Out[53]=
In[54]:=
RepeatedTiming[ByteCount[ToBoxes[expr]]]
Out[54]=

Neat Examples (1) 

Define formatting for a symbol that uses compressed boxes automatically:

In[55]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/24ca0ee9-62c9-4d87-98df-8ca557cecf2e"]
In[56]:=
CatSay["meow"]
Out[56]=
In[57]:=
InputForm[%]
Out[57]=

Version History

  • 1.0.0 – 24 September 2020

Related Resources

License Information