Crate yerevan

Source
Expand description

§yerevan.rs

yerevan.rs is a PoC package where I experiment with adding functionality and syntax of Computation Expressions (CEs) from F#, aka do-notations from Haskell, but with several changes and improvements.

Main component of yerevan.rs package is the yer! macro.

§Note

The things called computation expressions from F# are almost the same as do-notations from Haskell.

§Features and syntax of yer! macro:

FeatureSyntaxF# way
let! unwrapping-bindinglet! your_var = some_expression_to_bind;let! your_var = some_expression_to_bind
let usual var-defininglet your_var = some_expression;let your_var = some_expression
do! unwrapping expression without bindingdo! some_expression_to_unwrap;do! some_expression_to_unwrap
do just executing expressionlet some_expression;do some_expression
ret wrapping and returningret expression_to_return;return expression_to_return
ret! return without wrappingret! expression_to_return;return! expression_to_return
yield wrapping and yieldingyield expression_to_yield;yield expression_to_yield
yield! flattening value of accamulated type (flattened yielding)yield! expression_to_yield_from;yield! expression_to_yield_from
StructName => setting up or changing the CE-struct (struct which is providing specific methods for yer! macro)YourStructName => ...yourStructInstance { ... }
run takes last returned valuerun StructName => ...; ret state_for_run or StructName >> ...; ret ...yourStructInstance { ... }
if generating Rust’s if-statement`if (true) { yield “something”; }`if true then yield “something”

§How to implement these methods in your struct?

§Note to Methods API

There is no specific type you have to use by using methods signatures defined below.

The yer! macro is very flexible, so you must only use your types in a right way knowing how CEs work inside.

Also check the examples in yer!-page and tests in tests/common.rs file in the repo to better understand how CEs work inside.

§Methods API

  • let!, do!
pub fn bind<T, U>(val: CEStruct<T>, f: &dyn Fn(T) -> CEStruct<U>) -> CEStruct<U>;

F# way:

member _.Bind<'T, 'U>(value: CEType<'T>, f: 'T -> CEType<'U>) : CEType<'U>
  • ret
pub fn ret<T>(val: T) -> CEStruct<T>;

F# way:

member _.Return<'T>(value: 'T) : CEType<'T>
  • ret!
pub fn ret_from<T, U>(val: T) -> U;

F# way:

member _.ReturnFrom<'T>(value: 'T) : <'T>
  • yield
pub fn combine<T, U>(val: T, state: U) -> U;
pub fn ret_yield<T, U>(val: T) -> U;

F# way:

member _.Combine<'T, 'U>(value: 'T, state: 'U) : 'U
member _.Yield<'T>(value: 'T) : CEType<'T>
  • yield!
pub fn combine<T, U>(val: T, state: U) -> U;
pub fn ret_yield_from<T>(val: T) -> T;

F# way:

member _.Combine<'T, 'U>(value: 'T, state: 'U) : 'U
member _.YieldFrom<'T>(value: CEType<'T>) : CEType<'T>
  • run
pub fn run<T, U>(state: T) -> U;

F# way:

member _.Run<'T, 'U> (state: 'T) : 'U

§Why CEs in Rust?

A section for those who don’t know why CEs are so useful.

In Rust you can use the ? operator which is actually just a syntax sugar for situations, where you need to safely unwrap some value. The ? operator is based on the type you return from the function which makes it useless in cases when you need to unwrap a different type. And some packages create their own implementations of Result or Option types which also makes this operator less useful.

Also in Rust you can define your own macros to extend the language possibilities and use it just like CEs but with your own syntax. But creating a big macros can be tricky and difficult. And if you created your own syntax it doesn’t mean that this syntax will be readable for you or anyone else.

CEs are just functions you call in syntax-sugared way. So you can create your own custom control-flow, just like with macros but with standard syntax. For example, in CE-functions you can implement: builder pattern, safe unwrapper of enums (like Option or Result), etc.

Modules§

railway_exec
Module containing crate::railway_exec::RailwayBinder struct-ce and crate::railway_exec::RailwayExec trait.
yer_macro
Module containing the crate::yer macro.

Macros§

yer
yerevan.rs macros for fancy-shmancy syntax for computation expressions.