Skip to content

Add Scheme-style cond! macro #6333

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

Merged
merged 2 commits into from
May 15, 2013
Merged

Add Scheme-style cond! macro #6333

merged 2 commits into from
May 15, 2013

Conversation

brendanzab
Copy link
Member

Addressing issue #6037, this Scheme-style conditional helps to improve code clarity in instances where the if, else if, and else keywords obscure predicates undesirably.

Here is an example:

let clamped =
    if x > mx { mx }
    else if x < mn { mn }
    else { x };

Using cond!, the above could be written as:

let clamped = cond!(
    (x > mx) { mx }
    (x < mn) { mn }
    _        { x  }
);

The optional default case is denoted by _.

I have altered std::fun_treemap to demonstrate it in use. I am definitely interested in using it for some of the numeric functions, but I will have to wait for it to reach stage0 first.

@brendanzab
Copy link
Member Author

@graydon r?

@graydon
Copy link
Contributor

graydon commented May 8, 2013

nice. Can it use cond! { ... } invocation? and can it possibly dispense with the | markers? Or do these make it not parse right?

@brendanzab
Copy link
Member Author

Ahh yes. I tried without the markers, but I get:

cond.rs:16:8: 16:9 error: Local ambiguity: multiple parsing options: built-in NTs expr ('pred') or 1 other options.
cond.rs:16         _     { io::println(~"bananas"); }
                   ^

How would I switch to using { ... }. That would be awesome. I tried before, but couldn't figure out how to do it.

@brendanzab
Copy link
Member Author

@graydon should we close this until those things can be fixed? Or are you happy with having this in the interim?

@brendanzab
Copy link
Member Author

@graydon ok, I have a possible interim fix for the bad parsing without using the |s.

macro_rules! cond(
    ($(($pred:expr) $body:block)+ _ $default:block) => (
        $(if $pred $body )else+
        else $default
    );
    ($(($pred:expr) $body:block)+) => (
        $(if $pred $body )else+
    );
)

fn main() {
    let x = 1;
    cond!(
        (x < 0) { io::println(~"woops");   }
        (true ) { io::println(~"hullo");   }
        _       { io::println(~"bananas"); }
    )

    cond!(
        (x < 0) { io::println(~"woops");   }
        (true ) { io::println(~"hullo");   }
    )
}

It's not the greatest solution, but it is a backwards compatible fix that could serve us until the macro parser can be improved (or rewritten) to enable:

cond! {
    x < 0 { io::println(~"woops");   }
    true  { io::println(~"hullo");   }
    _     { io::println(~"bananas"); }
}

I definitely think the above syntax is what we should aim for, if macros could ever allow it.

This is temporary. Once the macro parser has improved or been re-written these can be removed.
bors added a commit that referenced this pull request May 15, 2013
Addressing issue #6037, this Scheme-style conditional helps to improve code clarity in instances where the `if`, `else if`, and `else` keywords obscure predicates undesirably.

Here is an example:

~~~rust
let clamped =
    if x > mx { mx }
    else if x < mn { mn }
    else { x };
~~~

Using `cond!`, the above could be written as:

~~~rust
let clamped = cond!(
    (x > mx) { mx }
    (x < mn) { mn }
    _        { x  }
);
~~~

The optional default case is denoted by `_`.

I have altered `std::fun_treemap` to demonstrate it in use. I am definitely interested in using it for some of the numeric functions, but I will have to wait for it to reach `stage0` first.
@bors bors closed this May 15, 2013
@bors bors merged commit 7e4a176 into rust-lang:incoming May 15, 2013
@brendanzab brendanzab deleted the cond-macro branch May 15, 2013 02:06
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 6, 2020
Added lint str_to_string

*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: un-deprecate [`str_to_string`] and [`string_to_string`] and introduce them as `restriction` lints again.
Fixes rust-lang#5610
Added new lint:- str_to_string
r? `@flip1995`
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

Successfully merging this pull request may close these issues.

4 participants