Arc Forumnew | comments | leaders | submitlogin
1 point by shiro 6137 days ago | link | parent

I don't think so. Since Arc (and most Lisp dialects) are applicative order, (foo) is evaluated once when (= bar (foo)) is evaluated. Redefining foo won't affect the value of bar (and it doesn't matter whether foo is a macro or a function).

Of course, if (= bar (foo)) is a part of a function, then the function should be recompiled.



1 point by elibarzilay 6136 days ago | link

A real solution for this will be really hard. For example, I'd expect this work:

  (mac foo () 1)
  (def bar () (let x (foo) (fn () x)))
  (= x (list (bar)))
  (mac foo () 2)
  ((car x))
    --> 2
(And the usual solution is to lower your expectations...)

-----

1 point by shiro 6136 days ago | link

Why? No matter whether foo is a macro or a function, a closed value of 'x' is fixed in the closure returnd by bar, so redefining foo shouldn't affect the closure bound to x. (But the next call of bar returns a closure that closes 2 as 'x'). Am I missing something?

-----

2 points by elibarzilay 6136 days ago | link

Like I said -- the usual solution, which you think about, is to lower your expectations. And I'm not joking when I say that: you really just decide to expect that `x' is not going to changed since it's "closed", so you're happy with the result. Some people set their expectations lower, and they expect a macro redefinition to not change anything about existing bindings, so they won't think about your hack as necessary.

And BTW, this is not just some cooked up academic non-problem. It's a practical issue. Consider this example:

  (mac foo () ...)
  (def bar ()
    ...do something...
    ...change foo...
    ...continue doing stuff...)
If that macro change will (with your suggestion) lead to recompiling `bar', but that will not affect the current active call. This is a very common problem with hacking live servers (as pg often talk about):

* You cannot change the main server handler loop unless you make it call itself via its name, so the recursive call will use the new definition.

* Even if you do, you should still be extremely careful since you might change the code when there's a live thread around which was compiled with the old macros, and might rely on the old macros. For example, `f1' and `f2' use `foo', `f1' is invoked in a thread, now `foo' gets redefined, after that's done `f1' continues to call `f2': old code is calling new one, things break.

-----

1 point by shiro 6136 days ago | link

I still believe you are talking different things. My "expectation" is derived from these axioms:

* Macro is a local source-code transformation that replaces macro call with the macro definition (with some hygienic magic, if you prefer).

* The language adopts applicative order.

If you want redefining foo to affect the value of the closed variable 'x', then either you have a non-trivial definition of macros (macro transformation requires transformation of code surrounding the macro call) or you are adopting different evaluation semantics (like x is bound by call-by-name).

Note that your problem occurs even foo is a procedure. It's not a macro problem. It's a problem of semantics of closed variables.

-----