next up previous index
Next: Looping and closures Up: Control structures Previous: Control structures   Index

Booleans and branching

In boolean.diesel:

The bool type is the type of boolean values. There are two constants of bool type, true and false. Boolean values are comparable and hashable, but more importantly they support a number of basic control structures.

extend module Stdlib;
module Bool;
predefined abstract class bool;
extend class bool isa identity_hashable[bool];
predefined object true isa bool;
predefined object false isa bool;
if takes either one closure or two closure arguments, acting like an if-then or an if-then-else statement, as follows:
    if(i < j, {
        - then statements
    }, {
        - else statements
    });

The three-argument if control construct returns the value of the executed closure; i.e., if-then-else can be used as an expression, not just a statement, like the ? : expression in C. The two-argument versions ignore the result of their argument closure.

if_false negates the result of the test.

One way to achieve the effect of an if-then-elseif-then-...-else construct is to use another if call as the body of the else; unfortunately, this tends to indent poorly. The switch construct (which really is more like Lisp cond) indents better but may not run as fast.

The compiler implementation nearly always implements if and if_false as efficiently as you'd expect in C, despite its source-level use of messages and closures.

fun if(:bool, tc:&():`T, fc:&():`T):T;
fun if(t:bool, tc:&():void):void;
fun if_false(t:bool, fc:&():`T, tc:&():`T):T;
fun if_false(t:bool, fc:&():void):void;
Other control structures on booleans include & (and), | (or), not, and => (implies). These control structures' second argument is either a boolean expression or a closure with boolean return type. When the second argument is not a closure, it is always evaluated. To achieve short-circuiting semantics, use closure arguments. For example:
    if(x != 0 & { y / x > 0 }, {
        ...
    });

fun |(:bool, :bool | &():bool):bool;
fun &(:bool, :bool | &():bool):bool;
fun not(:bool):bool;
fun =>(l:bool, r:bool | &():bool):bool;  - not(l) or r
The assert method allows checks to be made in support of defensive programming. If the test expression evaluates to is false, the program quits with an error message. The closure form is provided in case constructing the error message is expensive, and is short-circuited in the (expected) case where the test is true. (There currently is no mechanism to disable assertion checking, selectively or otherwise, other than editing the implementation of assert to be empty, in which case the compiler will merrily remove all calls to assert.)

fun assert(b:bool):void;  - Standard failure message
fun assert(:bool, :string | &():string):void;  - User-specified failure message
The as_integer method returns 0 for false and 1 for true.

fun as_integer(:bool):int;
end module Bool;


next up previous index
Next: Looping and closures Up: Control structures Previous: Control structures   Index

Cecil/Vortex Project