8
$\begingroup$

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.

$\endgroup$

1 Answer 1

10
$\begingroup$

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.

$\endgroup$
3
  • $\begingroup$ 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? $\endgroup$
    – QuantumDot
    Mar 18, 2018 at 2:30
  • 2
    $\begingroup$ 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. $\endgroup$ Mar 18, 2018 at 2:44
  • 2
    $\begingroup$ 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. $\endgroup$
    – ilian
    Mar 18, 2018 at 2:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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