105 lines
2.6 KiB
Plaintext
105 lines
2.6 KiB
Plaintext
pub int Display
|
|
fn toString() -> String
|
|
end
|
|
|
|
pub int LazyDisplay
|
|
fn toLazyString() -> DString
|
|
end
|
|
|
|
pub int DString : Display
|
|
parts: Array<DStringPart>
|
|
end
|
|
|
|
pub enum DStringPart
|
|
Constant(String),
|
|
Display(Display),
|
|
Lazy(Fn<Display>)
|
|
end
|
|
|
|
#internal
|
|
class DStringImpl(parts) : DString
|
|
cachedEval: Option<String>
|
|
canCache: Option<Boolean>
|
|
|
|
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<T> where T is Boolean
|
|
pub fn isTruthy() -> Boolean
|
|
self is Some(b) ? b : false
|
|
end
|
|
end
|
|
|
|
// some other file
|
|
use std::extensions::HasTruth[Option<Boolean>]
|
|
|
|
fn maybeSomeOrNone -> Option<Boolean>
|
|
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 |