2

I was surprised by the following sequence of expressions:

Remove[foo$, bar$];
foo$ = Function[Set[bar$, 42]];

At this point, I expected foo$ to be defined and bar$ not to be defined, because I had not called the function named foo$ yet. Indeed, the notebook interface shows bar$ in blue (undefined) and foo$ in black (defined). However, bad news, bar$ has a value:

foo$
(* (bar$ = 42) & *)
bar$
(* 42 *)

Running the command-line version of Mathematica produces different results:

Remove[foo$, bar$]
foo$ = Function[bar$ = 42];
foo$
(* (bar$ = 42) & *)
bar$
(* bar$ *)

The following does not help; in the notebook:

Remove[foo$, bar$]
bar$
(* bar$ *)
foo$ = Function[SetDelayed[bar$, 42]]
(* (bar$ := 42) & *)
bar$
(* 42 *)

and in the command-line:

Remove[foo$, bar$]
foo$ = Function[SetDelayed[bar$, 42]]
(* (bar$ := 42) & *)
bar$
(* bar$ *)

I found only the following to work, but it's unacceptable because I want a functional way to delay and to force evaluation, that is, a method that uses the construction and calling of functions:

In the notebook:

Remove[foo$, bar$]
foo$ = Hold[Set[bar$, 42]]
(* Hold[bar$ = 42] *)
bar$
(* bar$ *)
ReleaseHold[foo$]
(* 42 *)
bar$
(* 42 *)

and identical results in the command-line.

Silvia
  • 27,556
  • 3
  • 84
  • 164
Reb.Cabin
  • 8,661
  • 1
  • 34
  • 62
  • 1
    Interesting and confirmed.. Even simpler, simply evaluating (x=42)& sets x in the front end but not in the math kernel CLI. (The first case is what I'd expect, FWIW.. ) – george2079 Dec 24 '13 at 15:12
  • 1
    After playing with this more, the GUI itself is inconsistent. If I put (x=0)&; and x in seperate cells the behavior is different if I evaluate the cells together vs. one at a time.. Looking forward to a good explination.. – george2079 Dec 24 '13 at 15:37
  • 1
    I'm afraid I can't reproduce the results. Mma 9.0.1, Max OS 10.8.5. – Michael E2 Dec 24 '13 at 17:59
  • 1
    9.0.0.0 windows and 9.0.1.0 linux.. – george2079 Dec 24 '13 at 18:54
  • mma 9.0.1.0, Mac OS X 10.9.1 – Reb.Cabin Dec 24 '13 at 21:40
  • 1
    I can't reproduce it either. 9.0.1, 64-bit Windows. Everything looks exactly as expected here. I find it surprising that this could be system-dependent? I do agree about the difference between separate cells (or separate lines in the same cell) and on the same line, but that is not exactly unexpected (to me, anyway). – Oleksandr R. Dec 25 '13 at 15:00
  • Three repros (counting @george2079's two), two non-repros. I'm going to add "one more layer of abstraction" and emulate Scheme's Delay and Force. – Reb.Cabin Dec 25 '13 at 17:44
  • Let me be a bit more explicit. I would find it disturbing if I could reproduce your observations here, so I can definitely sympathize with your feelings about it. It seems almost certainly a bug of some sort. But, I'm not sure whether this question is actually answerable, unless we can get to the bottom of why (or at least, under what conditions) this happens? – Oleksandr R. Dec 25 '13 at 21:39
  • The condition seems to be that the pure function is the last thing evaluated - last line in a cell (with no semicolon termination) - and it must be in the last cell in case you evaluate multiple cells. I'll call it an innocuous bug, since you ought not be assigning to a global symbol inside a pure function anyway. – george2079 Dec 26 '13 at 16:12
  • It's interesting that you say "ought not be assigning to a global symbol inside a pure function." Why not? Seems a handy way to modify state. If the function body is in the scope of the variable, why shouldn't one be able to read and write the variable? – Reb.Cabin Dec 26 '13 at 18:26
  • Cannot reproduce it (except the last example) on 9.0.1, win8.1 x64. – Silvia Dec 27 '13 at 17:21

0 Answers0