It would be nice to have a "bullet-proof" Manipulate[]
that does not depend on, or is not affected by, global values, such as one for t
. There are a few problems, challenges and requirements:
- The use of
Global`t
in the Manipulate
code means users can interfere with its operation by setting t
equal to something.
- More significantly,
InputField
does not localize symbols. One has to do one's own localization.
- Another requirement I sought was to be able to display the localized
t
as t
, in both StandardForm
and TraditionalForm
.
- A bigger challenge is that
Manipulate
rather aggressively rewrites the user's code to remap symbolic expressions in terms of localized expressions (e.g. in terms of $CellContext`t$$
, which is later converted to FE`t$$nnn
), while sometimes allowing global values of t
to slip in. It seems bigger to me, because I have been unable to predict with 100% confidence when global t
gets evaluated in the process of building the DynamicModule[]
output of Manipulate[]
.
Well, with a bit of luck, I've got it down to the following:
t = 4; (* to try to cause trouble *)
(* periphrasis needed, to get around Manipulate's remapping of Symbol["t"]
Fails: PlotLabel -> ({f, df} /. HoldPattern[t] :> Symbol["t"]) *)
Manipulate[
With[{f = ReleaseHold[
xx /. HoldPattern[tt_ /; MatchQ[tt, Symbol["t"]]] :> t
]},
With[{df = D[f, t]}, (* @lowriniak's idea *)
(* other code as needed *)
Plot[df, {t, 0, 1}, PlotLabel -> ({f, df})]
]],
{{xx, Unevaluated[t^2], "x(t)="}, (* Manipulate does not localize initial value *)
InputField[#, Hold[Expression]] &}, (* @Nasser's String method can be adapted, too *)
{{t, Unevaluated[t]}, (* Manipulate does not localize initial value *)
ControlType -> None},
Initialization :>
(MakeBoxes[t, form_] := FormBox["t", form]) (* Otherwise get things like FE`t$$959 *)
]
Manipulate[Plot[Evaluate@{xx, D[xx, t]}, {t, 0, 1}], {{xx, t^2, "x(t)="}}]
$\endgroup$