Sketching July 2025.

This commit is contained in:
Jesse Brault 2025-08-01 07:47:56 -05:00
parent 6f727e1cdf
commit 8c802f2a15
6 changed files with 253 additions and 0 deletions

View File

@ -0,0 +1,22 @@
fn main()
var x = 42
let cl = { i: Int ->
let result = x + i
x += 1
result
}
println cl(0) // 42
println cl(0) // 43
println cl(0) // 44
end
fn main()
var x = 42
fn cl(i: Int): Int
let result = x + 1
x += 1
result
end
println cl(0) // 42
println cl(1) // 42
end

View File

@ -0,0 +1,32 @@
pub hkt Functor[Self<T>]
fn <U> map(f: fn (t: T) -> U) -> Self<U>
end
pub int Iterable<T>
fn iter() -> Iterator<T>
end
pub int Iterator<T> = () -> Option<T>
pub enum Option<T> : Functor[Self<T>]
Some(T),
None;
fn unwrap() -> T
self is Some(t) ? t : throw Exception('Empty Option')
end
fn expect(msg: String) -> T
self is Some(t) ? t : throw Exception(msg)
end
impl Functor
fn <U> map(f: fn (t: T) -> U) -> Self<U>
self is Some(t) ? Some(f(t)) : None
end
end
static fn lift(t: T) -> Self<T>
Some(t)
end
end

View File

@ -0,0 +1,14 @@
int Greeter
fn greet(): Void
end
class MyGreeter(greeting: String) : Greeter
impl fn greet()
println greeting
end
end
fn main()
let g: Greeter = MyGreeter("Hello, World!")
g.greet()
end

View File

@ -0,0 +1,39 @@
fn main(args: Array<String>)
if args[0] == 'greet' then
println 'Hello!'
end
end
fn main(args: Array<String>)
args.each { println it }
end
fn main(args: Array<String>)
if args.find { it == 'greet' } then
println 'There was a greet arg'
end
end
// longer
fn main(args: Array<String>)
let findIndexResult: Option<Int> = args.findIndex { it == 'greet' }
if findIndexResult.isSome() then
let index: Int = findIndex.unwrap()
println "greet arg was index ${index}"
end
end
// shorter with destructuring
fn main(args: Array<String>)
if let Some(greetIndex) = args.findIndex { it == 'greet' } then
println "greet arg was index ${greetIndex}"
end
end
fn main(args: Array<String>)
let parsed: CliArgs = std::cli::parse(args)
let greetingCount = parsed.get::<Int>('--count', '-c').orElse(1)
if let Some(greeting) = parsed.get('greeting', 'g') then
greetingCount.times { println greeting }
end
end

View File

@ -0,0 +1,105 @@
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

View File

@ -0,0 +1,41 @@
pub trait HasTruth
fn isTruthy() -> Boolean
def fn isFalsy() -> Boolean = !self.truthy
end
pub trait Functor[Self<T>]
fn <U> map(f: fn (t: T) -> U) -> Self<U>
end
pub trait Lift[Self<T>]
static fn lift(t: T) -> Self<T>
end
pub trait Applicative[Self<T>, U, V] : Functor[Self] + Lift[Self] where T is fn (u: U) -> V
fn apply(us: Self<U>) -> Self<V>
end
pub trait Monad[Self<T>] : Functor[Self] + Lift[Self]
fn <U> flatMap(f: fn (t: T) -> Self<U>) -> Self<U>
end
// Traits as higher-kinded types
// - Cannot be used as concrete types, casted, etc.
// - Cannot be constructed/instantiated
// - Imports are different:
// ```
// use std::core::Option
// use std::trait::Monad[Option<*>] // bring in Monad for all Option<*>
// ```
// - Once imported, fns are in scope
// - Can also be looked-up 'dictionary' style:
// ```
// use std::trait::HasTruth[Option<Boolean>]
//
// fn main()
// let maybeTruthy: Option<Boolean> = someOtherApiCall()
// if HasTruth[maybeTruthy].isTruthy() then
// println "It's truthy."
// end
// ```