# Making an expression to Iceberg-like object?

Can we construct a function Iceberg,
which maps a given expression X to Iceberg[X]
satisfying 1. and 2. and 3. ?

1. From Iceberg[X],
it is not possible to inspect/extract a part of X with usual method.
It would be better if there is no part of Iceberg[X].
Applying Iceberg to X is like putting X into an iceberg.

ex) It is not difficult to extract 3rd part of {101,102,103,104,105},
from Hold[{101,102,103,104,105}].

    In[1]  Hold[{101,102,103,104,105}][[1]][[3]]

Out[1] 103


So Hold is not like Iceberg.

Likewise, for HoldComplete, Unevaluate, Defer, Inactivate, ... and combinations of these commands, similar method can extract any part of X.

So they are not like Iceberg.

2. From Iceberg[X], there is a unique way to comeback to X.

In[2]  Icemelt[Iceberg[{101,102,103,104,105}]]
Out[2]  {101,102,103,104,105}


No function other than 'Icemelt', can do it.

3. In fact there is a function satisfying 1. and 2. :
Iceberg = ToString
Icemelt = ToExpression

But I ask you to find another solution.

I believe ToString/ToExpression is the only solution.

• "I believe ToString/ToExpression is the only solution." -- Also, Encrypt / Decrypt. Jun 11, 2021 at 8:41
• also Compress/Uncompress?
– kglr
Jun 11, 2021 at 8:51
• 1. Strings are easier to reason with -- they are simple structures, familiar, present in many programing languages. 2. Because strings are simple their application is limiting. 3. It is not clear what is your end goal. If strings let you achieve it faster or easier then use strings. Jun 11, 2021 at 9:50
• @b3m2a1's myObj[] function does what Iceberg[] is supposed to, and we can define Icemelt[myObj[data_]] := data to get #2. Jun 11, 2021 at 18:21
• Does this answer your question? Custom atomic expressions - modern tutorial Jun 11, 2021 at 18:25

ClearAll@Iceberg;
expr : HoldPattern[Iceberg[x_]] /; ! AtomQ[Unevaluated[expr]] :=
SystemPrivateSetNoEntry[Unevaluated[expr]];
Iceberg /: MakeBoxes[v_Iceberg?AtomQ, fmt_] :=
InterpretationBox[
RowBox[{"Iceberg", "[", "\[LeftAngleBracket]", "\[RightAngleBracket]", "]"}], v];
Icemelt[HoldPattern[Iceberg[x_]]] := x


Now you can do

Iceberg[{1,2,3}]


I believe it satisfies the other requirements

In[80]:= Iceberg[{101, 102, 103, 104, 105}][[1]][[3]]

During evaluation of In[80]:= Part::partd: Part specification Iceberg[\[LeftAngleBracket]\[RightAngleBracket]][[1]] is longer than depth of object.

During evaluation of In[80]:= Part::partw: Part 3 of Iceberg[\[LeftAngleBracket]\[RightAngleBracket]][[1]] does not exist.

Out[80]= Iceberg[{101, 102, 103, 104, 105}][[1]][[3]]

In[81]:= Icemelt[Iceberg[{101, 102, 103, 104, 105}]]

Out[81]= {101, 102, 103, 104, 105}


Silly, but fun

X = {101, 102, 103, 104, 105};

img = Rasterize[X];

ToExpression[TextRecognize[img]] === X
(* True *)

• This is, great :) I was thinking that it will be an interesting challenge to list or enumerate all possible ways to do the "icebergs" in WL. Jun 11, 2021 at 19:14