8

In Mathematica 11.3 we have the new Iconize function. Say I create an iconized image grabbed from the web, like this:

 hawkings = WebImageSearch["Stephen Hawking", "MaxItems" -> 5];
 pic = Iconize[URLExecute[hawkings[[3]]["ImageHyperlink"]], "Stephen Hawking"]

If I now evaluate input such as...

 Evaluate[the-actual-icon]

... where the-actual-icon is the icon just created, then I'll get the image as output. However, if I evaluate instead...

 Evaluate[pic]

...then I just get the icon object again, not the actual image.

How can I get the image by using the name pic for the icon rather than the iconized object itself?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
murray
  • 11,888
  • 2
  • 26
  • 50

1 Answers1

12

Iconize is not meant to be used this way. Do not assign the result to a variable.

Above, you are assigning the output to a variable, i.e. storing it in kernel memory.

The purpose of Iconize is to be able to store expressions in a notebook without having them take up a lot of visual space. The icon can be copied around within the notebook, and inserted into input cells, where it will behave as if you had typed the expression it represents.

Normally, you would create an icon either by selecting an expression, right-clicking, and choosing Iconize from the menu (this method does not evaluate), or by typing Iconize[something], selecting it, then evaluating it in place (Command-Enter on Mac).

To sum up: one would not normally use the return value of the Iconize function. Instead, one would use the icon (a visual object within the notebook) that it created. It's useful only in relation with notebooks.


Before Iconize was available, I showed a very similar concept in this blog post, which in turn was inspired by a much older MathGroup post by John Fultz. Looking at this blog post may clarify the intended use of Iconize too.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • But it would be nice to be able to return them – M.R. Mar 15 '18 at 17:15
  • And exactly *why" can't an icon be assigned to a variable? The documentation does not so indicate; in fact, the documentation is, to be generous about it, skimpy. – murray Mar 15 '18 at 21:33
  • 5
    Because if the icon were the same thing as the expression, it would format as the expression, not as an icon. What's returned by Iconize must be different from the expression in order for the magic where it looks like one thing but formats as another. And I would point out that this question is directly addressed by the Possible Issues example on the ref page. In fact, I think your description of the documentation is entirely unfair. 4 notes and 11 examples? That's a reasonable amount, especially for such a tiny function. What do you think isn't addressed by the documentation? – Itai Seggev Mar 15 '18 at 21:46
  • @murray It can be assigned to a variable, but that's not what it's for. Think about it like this: there are expression stored in memory. They can be formatted (displayed on screen) using a mix of text and graphics. Then this formatted (displayed) thing can be converted back to an expression. However, there is no direct equivalence, because when you convert it back, you might not get the very same thing. This is what happens here. An IconizedObject expression is displayed as an "icon", but then that "icon" is re-interpreted as the "contents" (first argument) of the IconizedObject. – Szabolcs Mar 15 '18 at 21:48
  • This sounds complicated, but in this particular case it is very useful. It gives you a practical means to store large expressions / data in a notebook, which was a much-requested feature. This behaviour is also not unique. Defer works like this too. x = Defer[1+1] has head Defer, but it is diplayed as 1+1 on-screen, and re-interpreted simply as 1+1. Interpretation allows you to build such things yourself. Summary boxes are another example (their displayed form may or may not contain the full expression they stand for, depending on the storage space needed) – Szabolcs Mar 15 '18 at 21:51
  • 3
    @ItaiSeggev To be fair, the behaviour I tried to describe in the two comments above can be quite confusing, and I have no idea how to explain it clearly and concisely ... people get confused about Defer all the time, and don't understand the difference between it and HoldForm. Personally I love Iconize and I'm glad that this was implemented. – Szabolcs Mar 15 '18 at 21:53
  • @Szabolcs I didn't mean to suggest that it was trivial. But the documentation does directly address this question. To just dismiss it as "skimpy" and not delve into its contents is not entirely fair to the people who spent a fair amount of time try to communicate this complicated behavior I would genuinely like to know what people think is missing from the page, as I'm directly involved in this function. We're already working on some improvements, so feature requests are also fair game. :) – Itai Seggev Mar 15 '18 at 22:09
  • @ItaiSeggev Feature request: is it technically possible to make it work in earlier versions? I iconize something in 11.3, save the notebook, open it in 11.2, and I would like to see the "icon" rendered not in an error-pink colour. Of course, I don't expect it to be pretty, I'd just hope for a rendering that doesn't look like an error. I know that the icon is evaluatable despite being pink. – Szabolcs Mar 15 '18 at 22:16
  • 3
    @Szabolcs Do you mean spcifically the 4th slot, or the big surrounding pink rectangle? Either will be hard/impossible to fix, and we decide to ship without solving the problem. The basic issue is that we can't ship updates to "Core" via paclets, so a function which requires a new TemplateBox style can't be supported (it would be nice to fix that one day, but there are more pressing issues...). Note that only the 4th argument inside the brackets is actually error pink. The big pink rectangle is "TemplateBox with no know DisplayFunction pink", a less hazzardous & currently unfixable problem. – Itai Seggev Mar 15 '18 at 22:51
  • @ItaiSeggev it should be possible for users to specify a "forwards-compatible" default stylesheet though for 11.2 and friends, right? Obviously with explicit setting on the user-side. Or alternately could the current Iconize be given some option to build an explicit box-representation (i.e. just pre-apply the DisplayFunction and wrap in Interpretation)? Then any Iconize boxes built in 11.3 would work fine in 11.2. – b3m2a1 Mar 16 '18 at 19:22
  • I'm still trying to fit Iconize into my understanding of the Wolfram Language. (I do understand what it does, and in particular the difference between storing an object in the notebook itself and storing the object in memory during the kernel session.) I guess my question concerns what other things in the Wolfram Language (and Mathematica) cannot usefully be assigned to names? – murray Mar 16 '18 at 20:19
  • @ItaiSeggev: Did I miss somewhere on the Iconize Documentation Center page an explanation that the iconized object is stored in the notebook and hence immediately available whenever that notebook is opened again in a new kernel session? – murray Mar 16 '18 at 20:20
  • 1
    @murray That is the meaning of "The formatted output of Iconize[expr] will evaluate to expr when it is supplied as input." Maybe I'm too much in the weeds of the box language to appreciate what it is and is not communicating to someone who is not an expert. – Itai Seggev Mar 16 '18 at 22:21
  • @b3m2a1 Yes, you can create your own stylesheet. What you can't do is create a new "Core.nb" that appends to the installed Core.nb. But if you use your own stylesheet, or just edit the stylesheet of a single notebook, you can use a cell like the following to give a simple appearance to the iconized object: Cell[StyleData["IconizedObject"],TemplateBoxOptions->{DisplayFunction->(RowBox[{ "IconizedObject", "[", RowBox[{#2,",",#3}], "]" }]&)}, MenuSortingValue->10000] – Itai Seggev Mar 16 '18 at 22:55
  • @ItaiSeggev why can't you override Core in a version specific way by putting a "Core.nb" stylesheet in a paclet with "MathematicaVersion"->"11.2" in the stylesheets directory? Is it special somehow? Also I'm guess you can answer this one if you have the time. – b3m2a1 Mar 16 '18 at 23:19
  • 1
    @ItaiSeggev: While I don't claim to be an expert at Mathematica, just a very experienced user, I have some considerable experience in writing clear and relevant documentation (and for many more things than Mathematica). I ask again: If Iconize stores the object in the notebook, why doesn't the documentation say so?? – murray Mar 17 '18 at 00:38
  • 3
    @murray To me, you might as well be asking "Why don't you state f is continuous??" after I have stated that f is differentiable. If the formatted output evaluates to expr, how can that output (and therefore the notebook) not contain expr? (In point of fact, the output doesn't evaluate to expr, it parses to expr. That is shown via the example involving unevaluated expression, but was deemed overly technical to put in the notes.) – Itai Seggev Mar 18 '18 at 02:33
  • @b3m2a1 The issue is that stylesheets always look for inheritence in the current directory. So if we updated Core.nb, then most notebooks (which use Default.nb) would still be use the old Core.nb. We could concievably fix this by shipping updates for al the built-in stylesheets, but that's never been tested. – Itai Seggev Mar 20 '18 at 00:08
  • @ItaiSeggev Interesting I didn't realize that was the default resolution path. I assumed they used FindFileOnPath. I was more imagining that you'd place the patch in "Default.nb" as that's what most end-users seem to build off of, which would be less of an issue, but obviously that's not entirely satisfying. – b3m2a1 Mar 20 '18 at 00:11
  • I am puzzled by "The formatted output of Iconize[expr] will evaluate to expr when it is supplied as input." If I do this: pts = Iconize[RandomReal[{0,1},2000] Then shouldn't I expect Mean[pts] to work? Instead I get Mean[(*iconized object*)] – Craig Carter Feb 15 '22 at 16:55