# Understanding strange behavior with ToExpression in DynamicModule: Losing Apply

## Short Version

Consider the following code:

test = "I";
label = "I";
paramlist = {a, b};
ToExpression[StringReplace[test, {label -> "(v2@@paramlist)[t]"}]]

(* v2[a,b][t] *)


When I try this inside a DynamicModule, it fails:

DynamicModule[
{dispVar2 = "I",
varyingparamlist,
fitExpression = "I",
fitfn},
varyingparamlist = {a, b};
fitfn = ToExpression[
StringReplace[fitExpression,
{dispVar2 -> "(v2@@varyingparamlist)[t]"}]];
Dynamic@Panel[fitfn]]

(* {a,b}[t] *)


What is going on here, and how can I get the correct expression inside a DynamicModule?

## Context

I have a system where I want non-Mathematica-savy users to be able to enter an expression in a (limited) natural notation for them as part of a dynamic interface. They can specify labels for variables and a system of differential equations which are then fit against experimental data using a combination of ParametricNDSolve and NonlinearModelFit. So if they specify

a S I


where S and I are the first and second time-dependent quantities in the system, this gets translated to

a v1[t] v2[t]


After solving the system of equations, I have parametric models that I need to access via something like:

((v1/.solution)@@varParams)[t]


The problem comes in when the fitting variable isn't a single value, like S or I. If I need S+I, I need to do something like:

ToExpression[StringReplace["S+I",
{"S"->"(v1@@varParams)[t]",
"I"->"(v2@@varParams)[t]"}]]/.solution


1.

DynamicModule[{dispVar2 = "I", varyingparamlist, fitExpression = "I",
fitfn}, varyingparamlist = {a, b};
fitfn = ToExpression[
StringReplace[fitExpression, {dispVar2 -> "(v2@@varyingparamlist)[t]"}],
StandardForm, Dynamic];
Panel[fitfn]] 2.

DynamicModule[{dispVar2 = "I", varyingparamlist, fitExpression = "I",
fitfn}, varyingparamlist = {a, b};
fitfn = ToExpression[
StringReplace[fitExpression, {dispVar2 -> "(v2@@varyingparamlist)[t]"}],
StandardForm, Hold];
Dynamic @ ReleaseHold @ Panel[fitfn]] 3.

DynamicModule[{dispVar2 = "I", varyingparamlist = {a, b},
fitExpression = "I", fitfn},
fitfn = MakeExpression[
StringReplace[fitExpression, {dispVar2 -> "(v2@@varyingparamlist)[t]"}]];
Dynamic @ ReleaseHold @ Panel[fitfn]] Notes:

DynamicModule[{dispVar2 = "I", varyingparamlist = {a, b},
fitExpression = "I", fitfn},
fitfn = ToExpression[
StringReplace[fitExpression, {dispVar2 -> "(v2@@varyingparamlist)[t]"}]];
Panel[fitfn]] What happened to v2?:

 foo @@ x

 x


Now, wrapping this with Dynamic updates varyingparamlist$$ and injects {a, b} for it: DynamicModule[{dispVar2 = "I", varyingparamlist = {a, b}, fitExpression = "I", fitfn}, fitfn = ToExpression[ StringReplace[fitExpression, {dispVar2 -> "(v2@@varyingparamlist)[t]"}]]; Dynamic @ Panel[fitfn]] That is, ToExpression (without the third argument) evaluates the string "(v2@@varyingparamlist)[t]" before varyingparamlist is updated so that v2@@varyingparamlist evaluates to varyingparamlist$$ and the result is varyingparamlist[t]. Using the Hold as the third argument of ToExpression or using MakeExpression (which "returns the result wrapped in HoldComplete") prevents this untimely evaluation.

• Works beautifully! Can you share some insights into why it works? Regardless, thank you! – Kevin Ausman Apr 16 at 17:41
• @Kevin, added a few comments re "why it works". Hope it helps. – kglr Apr 16 at 19:27