* effers effect handlers in rust ** how to use *** defining effects effects are defined with traits #+begin_src rust trait Printer { fn print(&mut self, s: &str); } trait Logger { fn debug(&mut self, s: &str); fn info(&mut self, s: &str); } #+end_src all the trait functions (that are used in programs) must take ~&mut self~ as a parameter *** defining a program programs are defined as a normal function, with the added ~program~ attribute #+begin_src rust #[program(Smth => Printer(print as p), Logger(debug, info))] fn smth(val: u8) -> u8 { p("hey hi hello"); debug("this is a debug-level log"); info("this is a info-level log"); val + 3 } #+end_src the first token (~Smth~) will be the name of the program. effects are listed after the ~=>~ token **** listing effects effects are listed by writing the trait's name, followed by a parenthesized list of the functions that will be used functions can be given an alias using the ~as~ keyword *** defining effect handlers effect handlers are defined by declaring a struct, and implementing the trait on it #+begin_src rust struct IoPrinter; impl Printer for IoPrinter { fn print(&mut self, s: &str) { println!("{}", s) } } struct FileLogger; impl Logger for FileLogger { fn debug(&mut self, s: &str) { println!("debug: {}", s) } fn info(&mut self, s: &str) { println!("info: {}", s) } } #+end_src *** running programs programs are run by providing the corresponding handlers in order, and finally calling the ~run~ method, providing it the required parameters #+begin_src rust let result: u8 = Smth.add(IoPrinter).add(FileLogger).run(3); assert_eq!(result, 6); #+end_src ** full example #+begin_src rust use effers::program; #[program(Smth => Printer(print as p), Logger(debug, info))] fn smth(val: u8) -> u8 { p("hey hi hello"); debug("this is a debug-level log"); info("this is a info-level log"); val + 3 } fn main() { // maybe smth like this? let result: u8 = Smth.add(IoPrinter).add(FileLogger).run(3); assert_eq!(result, 6); let other_result: u8 = Smth .add(IoPrinter) .add(NetworkLogger { credentials: "secret password".to_string(), }) .run(8); assert_eq!(other_result, 11); } // effects trait Printer { fn print(&mut self, s: &str); } trait Logger { fn debug(&mut self, s: &str); fn info(&mut self, s: &str); } struct IoPrinter; impl Printer for IoPrinter { fn print(&mut self, s: &str) { println!("{}", s) } } struct FileLogger; impl Logger for FileLogger { fn debug(&mut self, s: &str) { println!("debug: {}", s) } fn info(&mut self, s: &str) { println!("info: {}", s) } } struct NetworkLogger { credentials: String, } impl Logger for NetworkLogger { fn debug(&mut self, s: &str) { println!( "debug through network: {}; with password {}", s, self.credentials ) } fn info(&mut self, s: &str) { println!( "info through network: {}; with password {}", s, self.credentials ) } } #+end_src