fix: Astrid.Query.andThen compose with map*

Reserve stack slots for andThen values and fill them in later. The old
approach of a strict stack machine was wrong.
This commit is contained in:
YetAnotherMinion 2022-01-07 23:57:28 +00:00 committed by nobody
commit 401aec67d0
Signed by: GrocerPublishAgent
GPG key ID: D460CD54A9E3AB86
5 changed files with 271 additions and 85 deletions

127
src/exec/fixtures/README.md Normal file
View file

@ -0,0 +1,127 @@
# Query batching
Step 1)
queries = [ (0, map3 fA (succeed x) (map fB (andThen (\_ -> succeed j) (succeed k))) (succeed y)) ]
values = [ Pending ]
callbacks = []
Step 1.A)
query = map3 fA (succeed x) (map fB (andThen (\_ -> succeed j) (succeed k))) (succeed y) ]
Step 2)
queries = [ (1, succeed x), (2, (map fB (andThen (\_ -> succeed j) (succeed k)))), (3, (succeed y)) ]
values = [Pending, Pending, Pending, Pending]
callbacks = [ (0, fA) ]
Step 2.A)
query = (3, succeed y)
Step 3)
queries = [ (1, succeed x), (2, (map fB (andThen (\_ -> succeed j) (succeed k)))), ]
values = [ Pending, Pending, Pending, Ready y ]
callbacks = [ (0, fA) ]
Step 3.A)
query = (2, (map fB (andThen (\_ -> succeed j) (succeed k))))
Step 4)
queries = [ (1, succeed x), (4, (andThen (\_ -> succeed j) (succeed k))) ]
values = [ Pending, Pending, Pending, Ready y, Pending ]
callbacks = [ (0, fA), (2, fB) ]
Step 4.A)
query = (4, (andThen (\_ -> succeed j) (succeed k)))
Step 5)
queries = [ (1, succeed x), (5, succeed k) ]
values = [ Pending, Pending, Pending, Ready y, Pending, Pending ]
callbacks = [ (0, fA), (2, fB), (4, andThen (\_ -> succeed j)) ]
Step 5.A)
query = (5, succeed k)
-- insert the value into position 5
Step 6)
queries = [ (1, succeed x) ]
values = [ Pending, Pending, Pending, Ready y, Pending, Ready k ]
callbacks = [ (0, fA), (2, fB), (4, andThen (\_ -> succeed j)) ]
Step 6.A)
query = (1, succeed x)
-- insert the value into position 1
Step 6)
queries = []
values = [ Pending, Ready x, Pending, Ready y, Pending, Ready k ]
callbacks = [ (0, fA), (2, fB), (4, andThen (\_ -> succeed j)) ]
> Now go to reduce phase
Reduce Step 1)
queries = []
values = [ Pending, Ready x, Pending, Ready y, Pending, Ready k ]
callbacks = [ (0, fA), (2, fB), (4, andThen (\_ -> succeed j)) ]
Reduce Step 1.A)
last = (4, andThen (\_ -> succeed j))
value = values.pop() -- It should always be ready
-- call the callback to get the new query
queries.push(4, succeed j)
Reduce Step 2)
queries = [ (4, succeed j) ]
values = [ Pending, Ready x, Pending, Ready y, Pending ]
callbacks = [ (0, fA), (2, fB) ]
Reduce Step 2.A)
-- check that we have 1 arg ready at end of stack, no, so break the reduce step
> Now go back to query phase
Step 7)
queries = [ (4, succeed j) ]
values = [ Pending, Ready x, Pending, Ready y, Pending ]
callbacks = [ (0, fA), (2, fB) ]
Step 7.A)
query = (4, succeed j)
-- place value in slot 4
Step 8)
queries = []
values = [ Pending, Ready x, Pending, Ready y, Ready j ]
callbacks = [ (0, fA), (2, fB) ]
> Now go to reduce phase
Reduce Step 3)
queries = []
values = [ Pending, Ready x, Pending, Ready y, Ready j ]
callbacks = [ (0, fA), (2, fB) ]
Reduece Step 3.A)
last = (2, fB)
-- We look at last 1 arg
args = [ Ready j ]
-- place (fB j) in slot 2
Reduce Step 4)
queries = []
values = [ Pending, Ready x, Ready (fB j), Ready y ]
callbacks = [ (0, fA) ]
Reduece Step 4.A)
last = (0, fA)
-- We look at last 3 args
args = [ Ready x, Ready (fB j), Ready y ]
-- They are all ready
-- place (fA x (fB j) y) in slot 0
Reduce Step 5)
queries = []
values = [ Ready (fA x (fB j) y) ]
callbacks = []
-- Termination criteria reached, return values[0]

View file

@ -210,11 +210,15 @@ pub(crate) fn exec(
)
.replace(
"var $author$project$Astrid$Query$map2 = F3(\n\tfunction (f, a, b) {\n\t\treturn $author$project$Astrid$Query$Dummy;\n\t});",
r#"var $author$project$Astrid$Query$map3 = _Query_map2;"#,
r#"var $author$project$Astrid$Query$map2 = _Query_map2;"#,
)
.replace(
"var $author$project$Astrid$Query$map = F2(\n\tfunction (f, a) {\n\t\treturn $author$project$Astrid$Query$Dummy;\n\t});",
r#"var $author$project$Astrid$Query$map3 = _Query_map1;"#,
r#"var $author$project$Astrid$Query$map = _Query_map1;"#,
)
.replace(
"var $author$project$Astrid$Query$andThen = F2(\n\tfunction (f, q) {\n\t\treturn $author$project$Astrid$Query$Dummy;\n\t});",
r#"var $author$project$Astrid$Query$andThen = _Query_andThen;"#,
);
// final_script.replace("var $author$project$Astrid$Query$run = ", "JSON.stringify(x)");