Contents

Handling flag values

Introduction

One minor frustration the Icon programmer may encounter is the problem of storing boolean values in a variable. Icon of course has no boolean type, and it doesn’t really make sense to add one, because its conditional tests in if expressions and loops aren’t based on a boolean evaluation (rather, they’re based on whether an expression succeeds or not, which is a very different thing).

So, the following simple code in Java is actually a little awkward to translate into Icon :-

boolean b;
int i;

....

b = (i > 0);

....

if (b) {
   /* i is > 0 */
   ....
   }

Since there is no boolean type in Icon, we have to choose values to represent true and false. It makes sense to choose &null for false, since we can then use the \ and / operators to test the variable for its boolean value. We then have to choose a value for true, which just has to be any non-null value, say the string “yes”. The above java code can then be translated as :-

local b, i

....

b := if i > 0 then "yes" else &null

....

if \b then {
   # i is > 0
   ....
}

&yes

The thing I never really liked about the above technique was the arbitrary nature of the non-null value for representing true. Whatever value is chosen, it won’t match well with &null, and will be impossible to distinguish from a value having a non-flag meaning.

Therefore Object Icon has a value (and type) especially for the purpose of a flag value. This value is &yes, and it is the only value of a builtin type, “yes”. In a way, it is a mirror of &null, which is of course the only value of type “null”. Like &null, &yes doesn’t support any operators (other than / and \), and it is always quite clear that it’s being used as a flag.

The above example works the same, but the assignment to b now looks rather more symmetrical :-

b := if i > 0 then &yes else &null

&no

For the sake of readability, there is also a keyword, &no, which is just a synonym for &null (they are both entirely interchangeable).

Yes and No procedures

The util.Yes procedure takes an expression, and returns &yes or &no depending on whether the expression succeeds or fails. Yes never fails. util.No is just the same, but returns &no instead of &yes on success of the expression, and vice versa.

They are very useful to reduce the clutter caused by if expressions, such as the one assigning to b in the example above. Using Yes, it can be rewritten :-

b := Yes{ i > 0 }

which is much more concise.

Helpful procedures

There are a handful of other utility procedures which make flag handling a little easier. util.flag is a conversion procedure which tries to deduce a &yes or &no value from its parameter. util.need_flag checks if its parameter is &yes or &no and exits with a runtime error otherwise. Finally, util.toggle_flag inverts a flag value. The source for these very simple procedures, as well as Yes and No, can be seen in this file.

Contents