rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.99k stars 12.68k forks source link

Remove `while` loops #2233

Closed brson closed 12 years ago

brson commented 12 years ago

Likely much more controversial than removing do, but this topic has come up several times. We do use a lot of while loops.

BrendanEich commented 12 years ago

Can you show some of the while loops in rustc and how they would transform?

I can see losing do, test at the top is safest, but while is pretty useful in C/C++/JS.

/be

brson commented 12 years ago

OK, I went through the code base and picked out some representative functions. Most of them are simply iterating over a range. I think @marijnh has done this sort of exercise as well.

// Before
fn to_str(v: t) -> str {
    let mut i: uint = 0u;
    let mut rs: str = "";
    while i < v.nbits {
        rs +=
            alt tritv_get(v, i) {
              dont_care { "?" }
              ttrue { "1" }
              tfalse { "0" }
            };
        i += 1u;
    }
    ret rs;
}

// After
fn to_str(v: t) -> str {
    let mut i: uint = 0u;
    let mut rs: str = "";
    uint::range(0, v.nbits) {|i|
        rs +=
            alt tritv_get(v, i) {
              dont_care { "?" }
              ttrue { "1" }
              tfalse { "0" }
            };
        i += 1u;
    }
    ret rs;
}

// Before
while find_pre_post_state_fn(fcx, f_decl, f_body) { }

// After
loop {
    if find_pre_post_state_fn(fcx, f_decl, f_body) { break }
}

// Before
let mut i = 0u;
let mut data = [];
let mut offsets = [];
while i < vec::len(ccx.shape_cx.tag_order) {
    let did = ccx.shape_cx.tag_order[i];
    let variants = ty::enum_variants(ccx.tcx, did);
    let item_tyt = ty::lookup_item_type(ccx.tcx, did);
    let ty_param_count = vec::len(*item_tyt.bounds);
    // etc

// After
let mut i = 0u;
let mut data = [];
let mut offsets = [];
for ccx.shape_cx.tag_order.each {||
    let did = ccx.shape_cx.tag_order[i];
    let variants = ty::enum_variants(ccx.tcx, did);
    let item_tyt = ty::lookup_item_type(ccx.tcx, did);
    let ty_param_count = vec::len(*item_tyt.bounds);
    // etc

// Before
let mut cx = cx;
while option::is_none(cx.block_span) {
    alt cx.parent {
      parent_some(b) { cx = b; }
      parent_none { fail; }
    }
}

// After
let mut cx = cx;
loop {
    if option::is_none(cx.block_span) { break }
    alt cx.parent {
      parent_some(b) { cx = b; }
      parent_none { fail; }
    }
}

I'll note that @dherman has expressed skepticism about this idea and I also think that removing while is possibly an absurd thing to do despite my desire to kill keywords.

boggle commented 12 years ago

I feel uneasy about this: (1) people are very much used to while loops (2) is hard to read (see loop, find if, discover it ends with break) (3) loop { if { break } } contains an unnecessary additional negation (loop _un_less cond) and it is known from PL usability research that the amount of negation in boolean formulas directly translates into a higher chance of getting the control flow wrong.

bstrie commented 12 years ago

Also keep in mind how the keyword will sound with the labeled break/continue from #2216. For a loop labeled foo, saying skip foo sounds (sort of) like you're telling it to skip the next iteration of foo.

I submit pass, which has precedence as a keyword from Python (though with a different meaning here).

boggle commented 12 years ago

I think 'pass' is good. A four letter word and not used frequently as a variable name.

bstrie commented 12 years ago

...Sorry, that above comment was intended for 2229.

graydon commented 12 years ago

There is some precedent in Sather for this. It only has one form of loop, infinite, introduced by loop. You break out wherever you want to break out.

My personal preference, though, is to keep while as a convenience form.

catamorphism commented 12 years ago

Is it possible to implement while with a macro that desugars into loop / break, etc.? If yes, then I'm ok with abolishing while. If no, I'd be reluctant to abolish it. Yes, it's true that you can do everything with loop, but it doesn't always seem natural.

bstrie commented 12 years ago

The familiarity factor of while is more than worth the cost of a keyword, I think.

brson commented 12 years ago

I think this is not going to happen. Closing.