Removing scope. Instead opting for tree creation from Air vector and back. #481
Closed
MicroProofs
started this conversation in
Core language features
Replies: 1 comment
-
This was implemented as of version 1.0.14-alpha. Worked as expected and was a great improvement. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
First the Why?
Is something wrong with scope?
No, In fact scope is a linear way to attempt to represent information that a certain Air element is embedded as a leaf or branch to an Air element that came before. We use scope to allow us to detect if a function that is used in multiple locations is properly hoisted such that the function is in scope for all locations where that function. We also don't want to just hoist all the functions at the top since that would mean a big main function would perform much better then this case. Scope allows us to find some scope ancestor that would cover the usages of that function, thus we hoist to just above the Air element that contains the ancestor scope.
So then why remove scope?
Function hoisting code is complicated. Since we are using a linear array to mimic tree depth and tree scope, extra code is needed to track what the scope currently is and how to transform scope to match the desired depth to hoist a function. Also function hoisting is currently not optimal. When we hoist a function, any dependency functions that it alone uses are hoisted at the same time above the function itself. While at first sight this may not seem wrong, consider that one of the dependency functions is only used by that function in an edge case. like:
Instead of always hoisting that 'handle_condition' function above this function in the Air stack, we instead should hoist within the function itself thus reducing the overhead of using functions in Aiken
So what's the alternative?
Converting from linear vec of Air elements to a tree (not binary) of Air elements
Instead of working with code that mimics tree behavior, we can instead '1 to 1' convert our linear Air vec to a tree format and then back. While in the tree format, we can do all of our function hoisting using code with less complexity and then once finished, converting back to a vec is straight forward.
Function Hoisting when using a tree structure
So now that we have a tree of Air elements, how do we hoist functions? We first check air elements for vars that make use of a function. If only one we can hoist a DefineFunc Air element directly in to the tree as a parent of the air element that contained the single usage.
In the case of multiple sites of usage for that function, we find a depth where all usage sites have the same common parent node. Now we just hoist a DefineFunc Air element as the parent of that common parent. The code to do this is much simpler than working with scope and the uplc is more efficient as a result of this better method of function hoisting. This still requires recursion detection and ordering function insertion in such a way that functions with the least dependencies are inserted first. But this code is required regardless of whether scope is used or not.
TBC Later
Beta Was this translation helpful? Give feedback.
All reactions