You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, variables bound in the match pattern of an auto_assert are not accessible except in guards within that same assertion. For instance:
auto_assertpidwhenis_pid(pid)<-self()pid# error, pid is not bound here
The work around is that the assertion returns the value, so if you really needed the result, you could do this:
pid=auto_assertpidwhenis_pid(pid)<-self()
Optimally, variables would be accessible in the block containing the assertion, as is the case with ExUnit's assert:
assert%{foo: foo,bar: bar}=some_call()foo# foo and bar are available
How ExUnit does it
ExUnit statically extracts variables from the match expression and ensures that they are returned in the same order when the assertion is run. This is pseudo-code for demonstration purposes, but you can imagine the above assert example expanding to something like this:
This means the assertion would return the value, which is desired, but would also bind the variables in the current scope.
Challenges for Mneme
The fundamental challenge is that Mneme doesn't know the vars that should be bound until runtime. Let's consider three cases:
# 1) new assertionauto_assertself()# 2) existing assertionauto_assertpidwhenis_pid(pid)<-self()# 3) incorrect assertion that will be updatedauto_assertpidwhenis_pid(pid)<-make_ref()
It turns out that cases 1) and 2) are possible to deal with. The second case can use the same technique that ExUnit uses, and the first can be handled by maintaining a sort of "private binding" that Mneme can draw from for future assertions. Since Mneme knows what new variables will be introduced by a new pattern, it can use those to e.g. pin that variable for future patterns in that test.
The third case is where things get really problematic, since a change in the value of an existing assertion can result in code that has a completely different set of variables. I'm not sure that there is an elegant solution to this.
I did some experimentation with this on this branch.
The text was updated successfully, but these errors were encountered:
If this ends up being possible, we could also switch to using = instead of <- at that point. (One of the reasons I chose <- is to signal that the binding semantics are like with/for/etc.)
One option for handling case 3 would be to always fail if an existing variable will no longer be present after updating, then prompt the user to re-run tests (or force-recompile and do it ourselves). If a variable was previously used that no longer exists, something will blow up.
zachallaun
changed the title
Variable bindings should be accessible outside of auto_assert
Make variable bindings accessible outside of auto_assertApr 4, 2023
Currently, variables bound in the match pattern of an
auto_assert
are not accessible except in guards within that same assertion. For instance:The work around is that the assertion returns the value, so if you really needed the result, you could do this:
Optimally, variables would be accessible in the block containing the assertion, as is the case with ExUnit's
assert
:How ExUnit does it
ExUnit statically extracts variables from the match expression and ensures that they are returned in the same order when the assertion is run. This is pseudo-code for demonstration purposes, but you can imagine the above
assert
example expanding to something like this:This means the assertion would return the value, which is desired, but would also bind the variables in the current scope.
Challenges for Mneme
The fundamental challenge is that Mneme doesn't know the vars that should be bound until runtime. Let's consider three cases:
It turns out that cases 1) and 2) are possible to deal with. The second case can use the same technique that ExUnit uses, and the first can be handled by maintaining a sort of "private binding" that Mneme can draw from for future assertions. Since Mneme knows what new variables will be introduced by a new pattern, it can use those to e.g. pin that variable for future patterns in that test.
The third case is where things get really problematic, since a change in the value of an existing assertion can result in code that has a completely different set of variables. I'm not sure that there is an elegant solution to this.
I did some experimentation with this on this branch.
The text was updated successfully, but these errors were encountered: