""" Iterate Through Recursive Data With Yield If you study the _scanInOrder method below you will see that implementing it with `yield` is very straightforward. Without `yield` the alternative is to write a helper class that implements IEnumerator and maintains state variables to track its current position in between calls to .moveNext. Yuck! This example was adapted from http://msdn.microsoft.com/msdnmag/issues/06/00/C20/default.aspx """ class Node where T must be IComparable cue init(item as T) .init(item, nil, nil) cue init(item as T, left as Node?, right as Node?) base.init _item = item _left = left _right = right pro left from var as Node? pro right from var as Node? get item from var as T def compareTo(node as Node) as int # this method enables comparison operators in Cobra like "a < b" where a and b are Nodes return .item.compareTo(node.item) def toString as String is override return '[.typeOf.name](item=[.item])' def dump print this stop if _left, print ' left:', _left stop if _right, print ' right:', _right stop print if _left, _left.dump if _right, _right.dump class BinaryTree where T must be IComparable cue init(root as Node) base.init _root = root pro root from var as Node def add(items as vari T) for item in items, .add(item) def add(item as T) _add(Node(item), _root) def _add(newNode as Node, root as Node) if newNode > root right = root.right if right _add(newNode, right) else root.right = newNode else if newNode < root left = root.left if left _add(newNode, left) else root.left = newNode get inOrder as IEnumerable return _scanInOrder(_root, 0) def _scanInOrder(node as Node?, level) as IEnumerable if node if node.left for item in _scanInOrder(node.left to !, level+1) yield item yield node.item if node.right for item in _scanInOrder(node.right to !, level+1) yield item class Program def main tree = BinaryTree(Node(0)) tree.add(4, 6, 2, 7, 5, 3, 1) values = List() for value in tree.inOrder # print value values.add(value) assert values == [0, 1, 2, 3, 4, 5, 6, 7]