8

I was digging inside the Iconize implementation a little bit and saw that there's a function BoxForm`BoxFormAutoLoad which loads the FormatValues for objects.

For the most part it's boring, but one interesting function that I saw in it was Internal`WithTimeStamps. A sample usage of BoxForm`BoxFormAutoLoad is:

BoxForm`BoxFormAutoLoad[MakeBoxes, 
 IconizedObject["asd"], 
 StandardForm, 
 "NotebookTools`Iconize`", 
 {{IconizedObject, _}},
 Hold[IconizedObject]
 ]

And tracking the WithTimeStamps call inside we see it's running:

Internal`WithTimestampsPreserved[
 {IconizedObject},
 Apply[
  (BoxForm`wasProtected = Unprotect[#1];
    (* Uninteresting Which block removed *);
    Protect[Evaluate[BoxForm`wasProtected]]) &,
  {{IconizedObject, _}},
  {1}
  ];
 DumpGet[System`Private`$SystemFileDir <> 
   System`Dump`fixfile["NotebookTools`Iconize`"] <> "x"];
 ]

Running this seems to do nothing interesting so I'm wondering why it exists and in what way there are "Timestamps" in the call.

b3m2a1
  • 46,870
  • 3
  • 92
  • 239

1 Answers1

10

It is an internal and undocumented function that can be used to prevent reevaluation of expressions whenever particular symbols contained in them change. This is a simple example:

Clear[a, b];
b = 1 + a

(* 1 + a *)

Internal`WithTimestampsPreserved[{a}, a = 1];
{a, b}

(* {1, 1 + a} *)

Although the value of a changed, the evaluator did not think that b might need reevaluation.

That is because we preserved the timestamp of a, i.e. forced it to remain the same.

Contrast with the normal behavior where updating a also changed its timestamp, so now b is out of date and must be reevaluated.

a = 1; {a, b}

(* {1, 2} *)

In some sense, it accomplishes the opposite of Update, which can be used to force reevaluation in certain situations.

ilian
  • 25,474
  • 4
  • 117
  • 186
  • This example makes me a little confused about the standard evaluation process. I thought the evaluation of b would occur when it is called, which means it should have returned 2 regardless of whether WithTimestampPreserved was used to modify a. This answer seems to suggest that under normal conditions, b is actually updated when a is modified (and not when WithTimestampPreserved is used). Does that mean all symbols and definitions are normally updated each time a symbol definition is modified? – QuantumDot Mar 18 '18 at 02:30
  • 2
    No, b is updated when it is evaluated. But to avoid needless and potentially expensive reevaluations, when b evaluates, it checks whether a has changed since they last time it was evaluated. Since a hasn't (due to WithTimestampsPreserved), b uses the cached value it has from its previous evaluation, which is that a stays a. You can see this by alternately inserting Update[Unevaluated @ a] and Update[Unevaluated @ b] betwee WithTimeStampsPreserved and {a,b}. As always, internal, undocumented functions are not supported and may clean your drive, kill your pets, or do other bad things. – Itai Seggev Mar 18 '18 at 02:44
  • 2
    Exactly, the timestamps are used as a low-level optimization in the evaluator: there is no need to to do a full reevaluation of an expression if none of its parts have changed. – ilian Mar 18 '18 at 02:54