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

Booleans and branching

In boolean.cecil:

    abstract object bool isa hashable[bool]; - hashable implies comparable
    concrete representation true isa bool;
    concrete representation false isa bool;
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:

signature if(bool, tc:&():`T, fc:&():`T):T;
method if_false(t@:bool, fc:&():`T, tc:&():`T):T;
method if(t@:bool, tc:&():void):void;
method if_false(t@:bool, fc:&():void):void;
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. 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 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.

signature |(bool, bool):bool;
signature |(bool, &():bool):bool;
signature &(bool, bool):bool;
signature &(bool, &():bool):bool;
signature not(bool):bool;
method =>(l@:bool, r@:bool):bool;
method =>(l@:bool, r@:&():bool):bool;
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 }, {
        ...
    });

method assert(b@:bool):void;
method assert(b@:bool, msg@:string):void;
method assert(b@:bool, msg_closure@:&():string):void;
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.

signature as_integer(bool):int;
method hash(b@:bool, range:int):int;
method if(@:true, tc:&():`T, fc:&():`T):T;
method |(@:true, @:bool):bool;
method |(@:true, @:&():bool):bool;
method &(@:true, r@:bool):bool;
method &(@:true, r@:&():bool):bool;
method not(@:true):bool;
method as_integer(@:true):int;
method print_string(@:true):string;
method if(@:false, tc:&():`T, fc:&():`T):T;
method |(@:false, r@:bool):bool;
method |(@:false, r@:&():bool):bool;
method &(@:false, @:bool):bool;
method &(@:false, @:&():bool):bool;
method not(@:false):bool;
method as_integer(@:false):int;
method print_string(@:false):string;
The as_integer method returns 0 for false and 1 for true.


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

Cecil/Vortex Project