pub int Display fn toString() -> String end pub int LazyDisplay fn toLazyString() -> DString end pub int DString : Display parts: Array end pub enum DStringPart Constant(String), Display(Display), Lazy(Fn) end #internal class DStringImpl(parts) : DString cachedEval: Option canCache: Option fn getCanCache() -> Boolean for part in parts do if part is Lazy then return false end end true end impl Display pub fn toString() -> String if cachedEval is Some(s) then return s end if canCache is None then canCache = Some(getCanCache()) end // Note the groovy-like property getter if canCache.truthy then cachedEval = Some( parts.reduce('') { acc, part -> let partAsString = match part as Constant(s) => s, Display(d) => d.toString(), Lazy(f) => throw DumbProgrammerException( 'Cannot cache when parts contains a Lazy.' ) end acc + partAsString } ) cachedEval.unwrap() else parts.reduce('') { acc, part -> let partAsString = match part as Constant(s) => s, Display(d) => d.toString(), Lazy(f) => f().toString() end acc + partAsString } end end end end // Special "extension" implementation of Option for all T where T : Boolean pub int HasTruth fn isTruthy() -> Boolean end impl HasTruth for Option where T is Boolean pub fn isTruthy() -> Boolean self is Some(b) ? b : false end end // some other file use std::extensions::HasTruth[Option] fn maybeSomeOrNone -> Option Some(true) end fn main() let o = maybeSomeOrNone() if o.truthy then println "It's truthy!" else println "It's falsy..." end end fn stringDemo() -> Void let plain = 'Hello, World!' let x = 42 let withDisplay = "Hello! x is $x" let withLazy = "Hello! x is ${ x + 42 }" println plain // Hello, World! println withDisplay // Hello! x is 42 println withLazy // Hello! x is 84 x += 42 println withLazy // Hello! x is 126 end