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

Reintroduce 'do' keyword as sugar for nested match statements #120

Closed
wants to merge 3 commits into from

Conversation

bvssvni
Copy link

@bvssvni bvssvni commented Jun 15, 2014


# Motivation

Flatten code that suffers from 'match pyramids' without loosing the expressiveness of match statements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/loosing/losing/

@steveklabnik
Copy link
Member

I would prefer adding the macro instead. If we're going to give this syntax, it should be actual HKT syntax.

@bachm
Copy link

bachm commented Jun 15, 2014

-1 from me. There is no need to introduce an additional keyword when match pyramids can be entirely avoided with Option and Result methods.

let numbers = File::open(&Path::new("n.txt"))
    .and_then(|file| BufferedReader::new(file).read_line())
    .ok()
    .and_then(|line| from_str::<uint>(line.as_slice().trim()))
    .map(|n| range(0u, n).map(|x| x + 1).collect::<Vec<uint>>())
    .unwrap_or(Vec::<uint>::new());

I do think that Option and Result methods could use some improvements, and that it's currently time consuming to write code such as the above (mainly due to the lack of an IDE informing the user about the exact return types).

@thehydroimpulse
Copy link

-1. I have a proposal for a do! macro once HKTs land which is a much more appropriate abstraction (sugar on-top of bind for monads).

do! {
    let a <- action1();
    let b <- action2();
    action3(a, b);
}

Anything implemented before HKTs (and monads) would most likely just be a hack and a leaky abstraction.

@jfager
Copy link

jfager commented Jun 15, 2014

I'm a big fan of the macro given the limitations of today's Rust, but I'd also prefer saving do for HKT and stealing Haskell's version.

@ghost
Copy link

ghost commented Jun 15, 2014

-1 the exact same visual effect can be achieved by simply not indenting the "pyramid".

@glaebhoerl
Copy link
Contributor

There are some simple but powerful extensions to Rust's expression level which could also help simplify pattern matching code, discussed previously in some other places which I don't want to go back to look for right now.

  1. Early return from any block

Right now you can early return from loops (break) or from the whole function (return). Theoretically however, it makes sense to early return from any outer block, providing a value of the type which the block evaluates to. For the purpose of this illustration I'm going to use the syntax return 's foo here to denote early-return from the block 's with the value foo. For instance:

'x: match thing {
    A => 1,
    B => {
        match thang {
            X => println!("avocados"),
            Y => println!("bananas"),
            _ => return 'x 10
              // read_number() is skipped, outer match evaluates to 10
        }
        read_number();
    }
    _ => 9
}
  1. refutable lets: let..else

Here we can put a refutable pattern on the LHS of a let, and try multiple alternatives to match it, of which the last one must always succeed (which includes things of type !). Examples:

let Some(foo) = try_read_string() else Some("oh well");

let Some(bar) = try_this() else try_that() else try_other() else fail!();

// can be combined with (1)
let Ok(baz) = attempt_operation() else return 'outer_block None;
  1. scoped refutable lets: if let

Here we can make an if block over a refutable let:

if let Some(foo) = try_read_thing() {
    do_something_with(foo);
} else {
    report_error();
}

This may be familiar from C++'s if (Foo* foo = dynamic_cast<Foo*>(bar)) sugar, and if I remember correctly Swift also has a similar feature.

(Again all of the above syntax is for illustration purposes only and likely has ambiguity issues etc., that's not the point here, only the features themselves.)

@dobkeratops
Copy link

alternative, how about adding sugar for nested match, within the match block itself, keep the 'do' keyword free:

match foo {
    Err(e)=> ....,
    Ok(x)=> .....  in  // "in" means this arm expression is matched for following arms
    Err(e)=> .... ,
    Ok(y)=> ..... in
    ...
}
match foo {
    Some(x)=> ..... in
    Some(x)=> ..... in
    Some(x)=> ....
}

match { ...1...  x in ...2...y in ...3...}   desugars as   
match {  ...1... match x {...2... match y {...3...} } }

also add an 'match{}else{}' as in the original RFC to catch a fallthrough default.

i agree with the comments that HKT is preferable, and the 'do' keyword can find better use

@huonw huonw added the postponed label Jul 3, 2014
@huonw
Copy link
Member

huonw commented Jul 3, 2014

Having something along these lines would be really useful: the similar monadic do in Haskell is so nice. However, we're not currently using do for anything so this change is entirely backwards compatible, furthermore, there are reasonable work-arounds for this now (e.g. the sugar methods for Option and Result, which I imagine will be the most common uses of this: #120 (comment)), it should be possible to handle the common cases via a macro, and there are possible future changes like HKT that will influence this design.

Thank you for taking the time to think about these issues, but unfortunately we're going to close as postponed.

@huonw huonw closed this Jul 3, 2014
wycats pushed a commit to wycats/rust-rfcs that referenced this pull request Mar 5, 2019
wycats pushed a commit to wycats/rust-rfcs that referenced this pull request Mar 5, 2019
Refresh and restructure the Ember CLI Guides
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
postponed RFCs that have been postponed and may be revisited at a later time.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants