1
$\begingroup$

I have a notebook with a list of operation where the result of a function is the input of the following.

Example:

a = DoSomething1[OriginalInput];
b = DoSomething2[a];
c = DoSomething3[b];
ShowData[c]

If I want to dynamically update the data I can use the "Dynamic" function like this:

Dynamic[
   ShowData[DoSomething3[DoSomething2[DoSomething1[OriginaInput]]]]
]

But this is very inconvenient. Probably I can use Function

a[Input_]:=DoSomething1[Input];
[...]
ShowData[c[b[a[CurrentInput]]]

But again it's quite similar.

Is there a better way to achieve the dynamic evaluation of a series of Function?

Extra: my program Use CurrentImage[] as input and then apply some image transformation based on the position of several elements in the picture

$\endgroup$
5
  • $\begingroup$ foo[x_]:= c @ b @ a @ x; Dynamic[foo @ input]? $\endgroup$
    – Kuba
    Feb 4, 2019 at 13:42
  • $\begingroup$ thanks @Kuba for your comment. in you example a, b, c are function name like a[input_]:=DoSomething1[input]? $\endgroup$
    – Grigno
    Feb 4, 2019 at 13:46
  • 1
    $\begingroup$ yep, does it fit your needs? p.s. look out for single capital letters because many have built-in meaning. C, D, K, I, E, O for example. $\endgroup$
    – Kuba
    Feb 4, 2019 at 13:49
  • 1
    $\begingroup$ Or foo = Composition[c, b, a] (equivalently, foo = c@*b@*a). -- But frankly, I don't see what's inconvenient about your two proposed solutions. $\endgroup$
    – Michael E2
    Feb 4, 2019 at 13:58
  • $\begingroup$ It works! Thank you @Kuba ! But if I have one of my function (eg: b) that needs more than one parameter, is it possible to use the same approach? (not for this case, but as a general question) p.s. Capital letters were just an example, but you are right! $\endgroup$
    – Grigno
    Feb 4, 2019 at 14:10

1 Answer 1

5
$\begingroup$

You can just wrap Dynamic around the whole thing if you want:

Dynamic[
  a = DoSomething1[input];
  b = DoSomething2[a];
  c = DoSomething3[b];
  ShowData[c],
  TrackedSymbols :> {input}
]

By using the TrackedSymbols option, the whole thing will only update if the variable input changes (if you don't specify this option, it may update many more times than necessary).

Note, however, that the evaluation will only take place whenever the Dynamic expression is being displayed. If it's hidden in some way or another, it may not update. This may not matter if you're only interesting in seeing the result of ShowData[c]. On the other hand, if you rely on a, b and c to be up-to-date with the variable input, you may run into problems if the dynamic expression is not currently on-screen.

Furthermore, it the computations take a significant amount of time, it's recommended to use the SynchronousUpdating -> False option for Dynamic, otherwise your notebook will freeze constantly (and the computation may even time out).

Finally, you may want to localize the intermediate variables a, b and c with a scoping construct (DynamicModule, Module or Block), depending on what you're doing. For example:

Dynamic[ Module[{a, b, c},
   a = DoSomething1[input];
   b = DoSomething2[a];
   c = DoSomething3[b];
   ShowData[c]
  ],
  TrackedSymbols :> {input}
]
$\endgroup$
1
  • $\begingroup$ That's exactly what I'm looking for! TrackedSymbols and SynchronousUpdating are very useful. Thank you @Sjoerd Smit $\endgroup$
    – Grigno
    Feb 4, 2019 at 20:42

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.