object ListBuilding { object Builder { def create[a]: Builder[a] = new ListBuilder[a]() } trait Builder[a] extends Function1[a, Builder[a]] { def get: List[a] def `!`: List[a] = get def `$`(x: =>a): Builder[a] def success: Boolean } class EndBuilding[a] extends Builder[a] { def apply(x: a) = this override def get = List() def `$`(x: =>a): Builder[a] = this override def success = false } class ListBuilder[a](init : List[a]) extends Builder[a] { override def success = true def apply(x: a): Builder[a] = new ListBuilder(x :: init) override def `$`(x: =>a): Builder[a] = { lazy val copy = x; try { apply(x) } catch { case Again => `$`(copy) case End => new EndBuilding[a] } } override def get = init reverse def this(init: a) = this(List(init)) def this() = this(List()) } object End extends Throwable object Again extends Throwable } object BuildingListTest { import ListBuilding._ def main(args : Array[String]) { def ask(message: String, predicate: String => Boolean) = { println (message) val value = readLine if(value == "quit") throw End else if(predicate(value)) throw Again else value } val result = Builder.create[String] $ ask ("Favourite number? (must be 42)", "42" !=) $ ask ("The favorite president? (cannot be bush)", "Bush" ==) $ ask ("Is Java important? (not empty)", "" ==) ; if(result success) { println (result !) } else { println ("quitted") } } } BuildingListTest.main(Array())