chime icon indicating copy to clipboard operation
chime copied to clipboard

'(dyn n 4 (inc 10))' should be 4+4i, not 5

Open masak opened this issue 5 years ago • 1 comments

Re this comment: http://arclanguage.org/item?id=21359

I discovered a bug in my own implementation just playing around with that example. But if we write inc.10 in the simpler way, as (inc 10):

Your implementation (chime 0.4.0 executable on Windows):

> (dyn n 4 (inc 10))
5

I was pleased to see your implementation nailing this one. (Unpacking it, since inc is implemented as (def inc (n) (+ n 1)), and since dynamic bindings trump lexical bindings (!), (+ n 1) evaluates as (+ 4 1).)

Then I ran it against my implementation:

> (dyn n 4 (inc 10))
4+4i

What's going on here is that another function simplify (in the dynamic call tree of +), also contains a lexical variable that get shadowed by the dynamic n. (There might be others, but this is the one I found.) Your implementation doesn't expose this, because + has been implemented natively.

I wish I was 100% confident that 4+4i is the "right" answer. (If you ask me, the behavior of dynamic variables is weird and deleterious, and I think it would make sense to have a section in the documentation that advises in quite strong words to use dynamic variables (a) sparingly, and (b) with a naming convention that's guaranteed not to collide with bel.bel code or other people's code.)

The general approach for my implementation will be to "fast-path" people who don't define dynamic variables that clash with lexical variables defined in functions, and to "slow-path" people who do. That's handwaving it a bit, but not much.

masak avatar Aug 24 '20 06:08 masak

On the other hand, both our implementations nail the second example from that comment, related to macros (expanded at eval time) and dynamic variables:

> (repeat 5 prn!hello)
hello
hello
hello
hello
hello
nil

> (dyn init 'prn!4 (repeat 5 prn!hello))
4
4
hello
hello
nil

I wasn't sure either implementation would get that one right; nice. Anyway, it's going to be important to "preserve" this behavior even in the face of various optimizations. Dynamic variables de-optimize everything.

masak avatar Aug 25 '20 07:08 masak