/* Again, should parse and type-check. */ type charList { charList cons(char); bool isEmpty(); char car(); charList cdr(); } final class MTCList() : charList impl charList { charList cons(char x) { return new ConsCList : charList (car = x, cdr = (this : charList)); } bool isEmpty() { return true; } char car() { error("There are no elements in the empty list!"); } charList cdr() { return (this : charList); } export charList : car, cdr, isEmpty, cons; } final class ConsCList() : charList impl charList { init char car; init charList cdr; charList cons(char x) { return new ConsCList : charList (car = x, cdr = (this : charList)); } bool isEmpty() { return false; } char car_func() { return car; } charList cdr_func() { return cdr; } export charList : car_func as car, cdr_func as cdr, isEmpty, cons; } type stack { char push (char elt); char pop(); } class listStack() : stack impl stack { charList stack = new MTCList : charList(); char push (char elt) { stack = stack.cons(elt); return elt; } char pop() { if stack.isEmpty() { error("The stack is empty!"); } else { char x = stack.car(); stack = stack.cdr(); return x; }; } export stack : push, pop; } type countedStack <: stack { int numElements(); } mixin addCount() : countedStack at stack impl countedStack { int numElts = 0; super(); char countedPush(char elt) { numElts = numElts + 1; push(elt); } char countedPop() { char x = pop(); numElts = numElts - 1; return x; } int getSize() { numElts; } export countedStack : countedPush as push, countedPop as pop, getSize as numElements; } subclass countedListStack = addCount(listStack); char main() { (new countedListStack : stack()).push('5'); }