-
Notifications
You must be signed in to change notification settings - Fork 108
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
Force bindings inside let-flow
to be unique
#201
base: master
Are you sure you want to change the base?
Force bindings inside let-flow
to be unique
#201
Conversation
Without this, the following code can randomly pick "cat" or "dog" (though "dog" is far more common, making this bug hard to detect or reproduce). ```clj @(let-flow [a "cat" a "dog"] a) ``` Note: There's a likelyhood that users updating to this code will need to update their code base due to it failing to compile. I (Ryan Smith) find this acceptable as the code is already broken, even if the user hasn't realized it yet.
This bug caused one of the most headache inducing bugs that I've ever encountered. Running API servers at Yummly returned different results using the exact same code and data. And to make it worse, when running the code in a repl & adding logging statements to try and debug, each time the code was recompiled it had the potential to randomly switch the results from expected to non. |
I'm sorry for the headache, but I think the correct thing to do here is to let variables be shadowed the way they would be in a normal |
This would be the desired behavior. The reason I went with this approach when we found the bug last year was a simple "I couldn't figure out a sane way to do this" inside the macro. I'm confident it's possible, it just wasn't something that I came up with a solution for in a reasonable period of time. |
We can make the bindings unique by turning them into a map, then back again. So, add
and use this in the definition for vars and vals'. |
@youngilchoo , there's an easier way to force the property of removing duplicate bindings to make only distinct names without throwing an exception ( @(let-flow [a (future "cat")
b (future a)
a "dog"]
[a b])
=> ["cat" "cat"] compare with (let [a "cat"
b a
a "dog"]
[a b])
=> ["dog" "cat"] |
Good point. Not used to using let bindings like a sequence of assignments! |
Probably need to do something like rename the bindings based on static single assignment. It should be simpler, since there's no need for φ functions, since there's no branching in a |
Without this, the following code can randomly pick "cat" or "dog" (though "dog" is far more common, making this bug hard to detect or reproduce).
Note: There's a likelyhood that users updating to this code will need to update their code base due to it failing to compile. I (Ryan Smith) find this acceptable as the code is already broken, even if the user hasn't realized it yet.