This seems to make things work. I'm worried I might have an ordering bug
where we might choose the wrong precedence if we write ambiguous code
somehow, but at least for now, let's commit this and move on. Hopefully
the nonassoc stuff is actually correct.
This adds an interesting version of the struct lookup function. In the
situation where we can't type-check the field name, it will use the
optional value passed in. This makes it easy to write a function that
will pull in the desired value, even as the input struct changes type
between compilations, without having to re-write your code.
It's structurally different from the other default lookup functions,
which is why it is named differently.
If we use this to generate a zero value, we want to make sure it's
completely initialized in case we use it subsequently. We also improve
the docs at the same time.
Instead of in the lexer. I think this simplifies things and gives the
parser more information which should hopefully make it easier to parse
without shift/reduce conflicts.
It's a normally named function for now, until we think of a common
package to move it into.
Hopefully this makes improving the lexer and parser easier for now. We
can consider bringing it back if needed.
This is a big giant patch that implements the AST part of lambdas!
I don't know how Sam is able to understand the AST so well, but he does,
and we're all grateful for it. Most of this code was written by him.
Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
This will probably change up again in the future, but this is what we
need for now to make lambdas work.
Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
These test both graph shape consistency and single value outputs.
Eventually we want to make the graph shape tests more precise, and also
verify specific outputs how it used to be. For now, this is okay.
Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
This adds a new implementation of the function engine that runs the DAG
function graph. This version is notable in that it can run a graph that
changes shape over time. To make changes to the same of the graph, you
must use the new transaction (Txn) system. This system implements a
simple garbage collector (GC) for scheduled removal of nodes that the
transaction system "reverses" out of the graph.
Special thanks to Samuel Gélineau <gelisam@gmail.com> for his help
hacking on and debugging so much of this concurrency work with me.
We should check this for safety. An error is better than a panic. If we
try to set an unexported field, this would panic. We should prevent
being able to even type unify that though!
This returns the type with the arg names we'll actually use. This is
helpful so we can pass values to the right places. We have named edges
so you can actually see what's going on.
Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
This plumbs through the new Output method signature that accepts a table
of function pointers to values and relies on the previous storing of the
function pointers to be used for the lookup right now. This has the
elegant side-effect that Output generation could run in parallel with
the graph engine, as the engine only needs to pause to take a snapshot
of the current values tables.
Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
The Graph signature changes are needed for future function work, and it
also fits in nicely with the need for storing the value pointer for each
function node. These are used to later extract values during the Output
stage.
Sam deserves all of the credit for realizing both of these points and
convincing me to make the change! It worked out great, cheers!
Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
This makes some of the Graph sig changes to prepare the code for proper
functions. The remaining bits will happen later.
Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
This adds a meta state store that is preserved between graph switches if
the kind and name match. This is useful so that rapid graph changes
don't necessarily reset their retry count if they've only changed one
resource field.
This adds a new test functions package and also a new "fastcount"
function which counts up from zero as fast as is possible. You probably
don't want to use this in production, but it is useful for performance
and deadlock testing the resource and function engines.
There are many reasonable cases where we might want to allow a dynamic
format string. Support that situation by adding the new invariants that
are needed for those cases.