Skip to content

Commit 40db488

Browse files
committed
New loop return result policy, eliminate BREAK/RETURN
This enforces the concept that a loop will return BLANK! if it is broken with BREAK, and that most loops will return the last body result unless it is void or FALSE?, in which case the result will be coerced to the true (but unusual-looking) result of BAR!. By having a uniform policy, loops become easier to chain. As a simple example of how easy: for-both: function [ 'var [word!] a [block!] b [block!] body [block!] ][ all [ for-each var a body for-each var b body ] ] Supporting BREAK/RETURN would undermine the ability to write such compositions. So instead, users are advised to use THROW and CATCH, which is a generic mechanism for overriding return values, and one could even argue a better looking one: while [x < 10] [break/return "result"] catch [while [x < 10] [throw "result"]]
1 parent 621e393 commit 40db488

34 files changed

+266
-261
lines changed

src/core/c-eval.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,10 @@ reevaluate:;
10791079
SET_BLANK(f->out); // no VALUE_FLAG_UNEVALUATED
10801080
break;
10811081

1082+
case R_BAR:
1083+
SET_BAR(f->out); // no VALUE_FLAG_UNEVALUATED
1084+
break;
1085+
10821086
case R_OUT:
10831087
CLEAR_VAL_FLAG(f->out, VALUE_FLAG_UNEVALUATED);
10841088
break; // checked as NOT_END() after switch()
@@ -1136,6 +1140,15 @@ reevaluate:;
11361140
CLEAR_VAL_FLAG(f->out, VALUE_FLAG_UNEVALUATED);
11371141
break;
11381142

1143+
case R_OUT_VOID_IF_UNWRITTEN_TRUTHIFY:
1144+
if (IS_END(f->out))
1145+
SET_VOID(f->out);
1146+
else if (IS_VOID(f->out) || IS_CONDITIONAL_FALSE(f->out))
1147+
SET_BAR(f->out);
1148+
else
1149+
CLEAR_VAL_FLAG(f->out, VALUE_FLAG_UNEVALUATED);
1150+
break;
1151+
11391152
case R_REDO_CHECKED:
11401153
SET_END(f->out);
11411154
f->special = f->args_head;

src/core/n-control.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ REBNATIVE(none)
314314
DROP_SAFE_ENUMERATOR(&e);
315315

316316
if (voted)
317-
return R_TRUE;
317+
return R_BAR;
318318

319319
return R_VOID; // all opt-outs
320320
}

0 commit comments

Comments
 (0)