Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chaining operations with ? #13

Open
nkoturovic opened this issue Jun 1, 2021 · 3 comments
Open

Chaining operations with ? #13

nkoturovic opened this issue Jun 1, 2021 · 3 comments

Comments

@nkoturovic
Copy link

nkoturovic commented Jun 1, 2021

Proposal

Note: I'm new to Nim and not sure how to implement it nor is it even possible

Suppose we have function safeDiv

func safeDiv(x : int, y: int): Result[int, string] =
  return case y:
    of 0: err("Division by zero")
    else: ok(x div y)

Currently we have to write:

func calc(): Result[int, string] =
  result = (?(?8.safeDiv(2))).safeDiv(0)).safeDiv(1)

Since Nim supports UFCS, it would be a lot nicer to write something like:

func calc(): Result[int, string] =
  result = 8.safeDiv(2)?.safeDiv(0)?.safeDiv(1)?

Currently there are various ways to chain operations, which are similar but not quite the same:

  • Functor like map function
  • Various getter methods
  • etc ...

Motivation: Rust

Here is similar example written in rust with postfix question mark operator ?.
Rust does not fully support UFCS like Nim, for example for primitive type i32 we would write something like

trait SafeOps: Sized {
    fn safe_div(self, other: Self) -> Result<Self, String>;
}

impl SafeOps for i32 {
    fn safe_div(self, other: Self) -> Result<Self, String> {
        if other == 0 { Err(String::from("Division by zero")) }
        else { Ok(self / other) }
    }
}

fn calc() -> Result<i32, String> {
    8.safe_div(2)?.safe_div(0)?.safe_div(1)
}

fn main() {
    println!("{:?}", calc());
}

Further considerations

  • Doing similar for Option type in standard library
  • Generalizing Option and Result to some kind of Monads maybe somehow or not
@arnetheduck
Copy link
Owner

Generalizing Option and Result to some kind of Monads maybe somehow or not

type Opt[T] = Result[T, void] is something we use in a few places, with good results - it's possible to add a few helpers to make it an almost seamless replacement.

@markspanbroek
Copy link

@nkoturovic You may want to take a look at questionable, it adds a .? operator for chaining function calls.

@nkoturovic
Copy link
Author

@nkoturovic You may want to take a look at questionable, it adds a .? operator for chaining function calls.

Thanks for suggestion. I'm going to take a look for sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants