ns nonavosa_rail pub mod train { pub int Train { name: String primary_color: Color destination: String fn blow_horn(): IO fn set_volume_by(factor: Number) } pub enum Color { White, Blue, Red } pub fn int Printer { (message: String): IO } pub fn create(props: Props & { printer: Printer }): Train = SimpleTrain { ...props } with { volume = 80.0 } abs impl : Train { #get #set fld volume: Double } impl SimpleTrain : AbstractTrain { printer: Printer override fn set_volume(volume) { if (volume < 0 || volume > 100) { throw IllegalArgumentException { message: `Volume $volume is outside of bounds 0-100.`, argument: volume } } this.volume = volume } impl fn blow_horn() = printer(`Train named $name is blowing it's horn at volume $volume!`) -> { s => s.append('Hello from SimpleTrain!') } impl fn set_volume_by(factor) = set_volume(volume * factor) } } fn main(args) { let train = train::create { name: 'Test Train', primary_color: train::Color::Blue, destination: 'Nonavosa Central', printer: { msg => println(msg) } } train.set_volume_by(1.1) train.blow_horn() let anonymous_train = train::Train { name: 'Anonymous Train', primary_color: train::Color::Red, destination: 'Nonavosa North', impl fn blow_horn() = println('Choo Choo!') impl fn set_volume_by = throw MethodNotSupported } try { anonymous_train.set_volume_by(3.0) } catch (e: MethodNotSupported) { println e.message } anonymous_train.blow_horn() -> { println('After blow horn, assuming nothing went wrong before') } } // some other file fn log_printer(message) impl nonavosa_rail::train::Printer = msg => io::open_file('log.txt', io::Mode::Append) -> { f => f.append(msg) } -> io::close_file fn main() { nonavosa_rail::main(log_printer) } // io.dm ns io decl extern fn println(s: String) #target[lua] decl extern fn _open_file(filename: String, mode: String): LuaTable #target[lua] pub fn open_file(filename: String, mode: Mode): IO { try { let lua_file_handle = lua {% fs.open(${filename}, ${mode.as_lua_string()}) %} Success(LuaFile { lua_file_handle }) } catch (e: LuaError) { Failure(e) } } #target[lua] pub fn close_file(file): impl IO = file.close() pub int File : Stream #target[lua] impl LuaFile : File { #get fld lua_file_handle impl fn append(data) { try { lua {% ${lua_file_handle}.write(${data}) %} Success(self) } catch (e: LuaError) { Failure(e) } } impl fn close() { try { lua {% ${lua_file_handle}.close() %} Success } catch (e: LuaError) { Failure(e) } } } pub enum Mode { Append, Write, Read } pub enum IO : Chainable> { Success(stream?: S) { impl fn call() { try { do_call(stream) } catch (e: E) { Failure(e) } } }, Failure(_) { impl fn call() = self }; fn do_call(stream: S): IO } pub int Stream { fn append(data: String): IO fn close(): IO } // chain.dm pub fn int Chainable { (): N }