Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
masak opened this issue Aug 24, 2020 · 1 comment
Open

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

masak opened this issue Aug 24, 2020 · 1 comment

Comments

@masak
Copy link

masak commented Aug 24, 2020

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
Copy link
Author

masak commented Aug 25, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant