package com.smallhacker.disbrowser interface ImmStack: Iterable { fun isEmpty(): Boolean val top: E? fun pop(): ImmStack fun push(value: E): ImmStack = ImmStackImpl(this, value) } fun immStack(): ImmStack { @Suppress("UNCHECKED_CAST") return EmptyImmStack as ImmStack } private class ImmStackImpl(private val parent: ImmStack, override val top: E): ImmStack { override fun isEmpty() = false override fun pop(): ImmStack = parent override fun iterator(): Iterator { return sequenceOf(top).plus(parent).iterator() } } private object EmptyImmStack: ImmStack { override fun isEmpty() = true override val top: Any? = null override fun pop() = this override fun iterator() = emptySequence().iterator() }