deimos-lang/sketching/july_2025/string.dm
2025-08-01 07:47:56 -05:00

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