-It's possible to build cooperative threads without using those tools, however. Already our [[solution using streams|/exercises/assignment12#streams2]] uses neither zippers nor any mutation. Instead it saves the thread's state in explicitly-created thunks, and resumes the thread by forcing the thunk.
-
-Some languages have a native syntax for coroutines. Here's how we'd write the same-fringe solution above using native coroutines in the language Lua:
-
- > function fringe_enumerator (tree)
- if tree.leaf then
- coroutine.yield (tree.leaf)
- else
- fringe_enumerator (tree.left)
- fringe_enumerator (tree.right)
- end
- end
-
- > function same_fringe (tree1, tree2)
- local next1 = coroutine.wrap (fringe_enumerator)
- local next2 = coroutine.wrap (fringe_enumerator)
- local function loop (leaf1, leaf2)
- if leaf1 or leaf2 then
- return leaf1 == leaf2 and loop( next1(), next2() )
- elseif not leaf1 and not leaf2 then
- return true
- else
- return false
- end
- end
- return loop (next1(tree1), next2(tree2))
- end
-
- > return same_fringe ( {leaf=1}, {leaf=2} )
- false
-
- > return same_fringe ( {leaf=1}, {leaf=1} )
- true
-
- > return same_fringe ( {left = {leaf=1}, right = {left = {leaf=2}, right = {leaf=3}}},
- {left = {left = {leaf=1}, right = {leaf=2}}, right = {leaf=3}} )
- true
+It's possible to build cooperative threads without using those tools, however. Already our [[solution using streams|/exercises/assignment12#streams2]] uses neither zippers nor any mutation. Instead it saves the thread's state in the code of explicitly-created thunks, and resumes the thread by forcing the thunk.
+
+Some languages have a native syntax for coroutines. Here's how we'd write the same-fringe solution using native coroutines in the language Lua:
+
+
+ > function fringe_enumerator (tree)
+ if tree.leaf then
+ coroutine.yield (tree.leaf)
+ else
+ fringe_enumerator (tree.left)
+ fringe_enumerator (tree.right)
+ end
+ end
+
+ > function same_fringe (tree1, tree2)
+ -- coroutine.wrap turns a function into a coroutine
+ local next1 = coroutine.wrap (fringe_enumerator)
+ local next2 = coroutine.wrap (fringe_enumerator)
+ local function loop (leaf1, leaf2)
+ if leaf1 or leaf2 then
+ return leaf1 == leaf2 and loop( next1(), next2() )
+ elseif not leaf1 and not leaf2 then
+ return true
+ else
+ return false
+ end
+ end
+ return loop (next1(tree1), next2(tree2))
+ end
+
+ > return same_fringe ( {leaf=1}, {leaf=2} )
+ false
+
+ > return same_fringe ( {leaf=1}, {leaf=1} )
+ true
+
+ > return same_fringe ( {left = {leaf=1}, right = {left = {leaf=2}, right = {leaf=3}}},
+ {left = {left = {leaf=1}, right = {leaf=2}}, right = {leaf=3}} )
+ true