Programming with Dynamic

10

I don't understand the following:

  f[a_, b_] := a + b
  ls = {1, 2, 3};
  MapThread[f, {ls, {10, 20, 30}}]

This yields ( as expected ) {11,22,33}

If I change the code to

  f[a_, b_] := a + b
  ls = {1, 2, 3};
  MapThread[f, {Dynamic[ls], {10, 20, 30}}]

mma returns the following message:

  MapThread::mptd: Object {1,2,3} at position {2, 1} in MapThread[f,{{1,2,3},{10,20,30}}] has only 0 of required 1 dimensions. >>

Question: Why does this happen? How can it be fixed?

nilo de roock

Posted 2012-05-20T09:49:12.820

Reputation: 8 701

The first gives me {f[1, 10], f[2, 20], f[3, 30]}; I suppose you cut and pasted the wrong thing! – acl – 2012-05-20T09:54:27.593

Already changed it, sorry ! – nilo de roock – 2012-05-20T09:58:51.380

Answers

13

Even though Dynamic[ls] is presented as ls, its head is Dynamic:

x = Dynamic[ls]
Head[x]
(*
{1, 2, 3}
Dynamic
*)

or

Basically, Dynamic is a wrapper, and is there even if you cannot see it. Its like you were writing

MapThread[f, {symb, {10, 20, 30}}]

with symb undefined, or

MapThread[f, {Integrate[symb[var], var], {10, 20, 30}}] 

You can fix it by doing

Dynamic[MapThread[f, {ls, {10, 20, 30}}]]

instead.

So:

Wherever you had written Dynamic[ls], you still have Dynamic[ls]. It may be displayed by the frontend as {1,2,3}, but it is not; it's Dynamic[ls]. So, MapThread goes to look at the first part of its second argument and sees Dynamic instead of a List, so it stops and emits a message; this message includes Dynamic[ls] in it. When the message reaches the "surface" to be displayed, Dynamic[ls] gets automatically interpreted by the frontend as usual: it's displayed as {1,2,3}, because that's what ls evaluates to. But it is still Dynamic[ls], not {1,2,3}, which is simply how it is displayed.

Try this: Do[Sin[i], Dynamic@{i, 1, 2}] and think about what happens...

acl

Posted 2012-05-20T09:49:12.820

Reputation: 19 146

Sorry, I don't get this. What should I do to fix this? – nilo de roock – 2012-05-20T10:04:49.577

I still don't get, but it WORKED. Dynamic still has its mysteries to me. Thank you. :-) – nilo de roock – 2012-05-20T10:22:00.377

8

Dynamic doesn't work the way you think it does. See this answer for a full explanation.

In short, Dynamic doesn't do anything until it is actually displayed on screen.
Therefore, you are essentially doing this (note the String):

MapThread[f, {"Dynamic[ls]", {10, 20, 30}}]

As acl already showed, you can wrap the entire expression in Dynamic so that it does not attempt to evaluate the failing condition shown above.

Mr.Wizard

Posted 2012-05-20T09:49:12.820

Reputation: 259 163

Can we move here the linked topic? – Kuba – 2016-02-25T05:59:38.227

@Kuba You mean migrate the question form Stack Overflow? No, that's not done anymore. There was a one-time offer to migrate important questions when they introduced the new policy, but now nothing over 30 (or 60?) days old can be migrated. – Mr.Wizard – 2016-02-25T06:13:30.067

Pity, thanks for info. Your answer and linked topic are quite broader than the scope of this question. And often I'm linking this topic because of your answer really. A generic one would be nice. – Kuba – 2016-02-25T06:20:37.367

@Kuba Ask John Fultz to do a self-Q&A on this site to share that information, along with any updates he might want to make since 2009. If he is too busy we can just do a CW post and quote that one verbatim. – Mr.Wizard – 2016-02-25T06:23:43.877

Feel free to do that, I'm not so motiviated at the moment, maybe I will be soon. I will try to not forget that and do this when another broader but closely related question appears. – Kuba – 2016-02-25T06:26:23.210