Previous section: True and False

Dylan reference manual -- Conditionals

Conditionals

The following syntax forms are used to perform conditional execution.
if   ( test ) consequent
   [elseif ( elseif-test )elseif-consequent]*
   [else alternate]
	end [if ]  =>  values	[Special Form]
if evaluates test. If test evaluates to a true value, consequent is evaluated.

If test evaluates to #f (the only false value), and any elseif clauses were supplied, the first elseif-test is evaluated. If thatelseif-test evaluates to a true value, its elseif-consequent is evaluated. If it evaluates to #f, the next elseif-test is evaluated, and so on.

Finally, if test and each elseif-test evaluates to #f, and alternate was supplied, the alternate is evaluated. If alternate was not supplied, #f is returned.

The consequent , elseif-consequent, and alternate sections of an if statement are all implicit bodies (may contain any number of expressions, separated by semicolons). The values of the last expression in the appropriate consequent , elseif-consequent, or alternate form (whichever is evaluated) are returned.

? define method test (thing :: <object>)
    if (thing)
      #t
    else
      #f
    end if
  end method;
test
? test ("hello")
#t
? test (#t)
#t
? test (#f)
#f
? define method show-and-tell (thing :: <object>);
     if (thing)
       print (thing);
       #t
     else
       #f
     end if
  end method;
show-and-tell
? show-and-tell("hello")
hello
#t
unless ( test )	[Macro]
	body 
	end [unless]
=>  values
unless evaluates test. body is an implicit body. If test evaluates to a true value, then none of the expressions in the body are evaluated and #f is returned. If test evaluates to #f, then all the expressions in the body are evaluated and the values of the last expression are returned.

If there are no expressions in the body, then #f is returned.

unless(detect-gas? (nose))
    light(match)
end unless

case              	[Macro]
	test1  => body1  ;
	...
	testn  => bodyn  ;
	[otherwise => otherwise-body ] [;]
	end [case]
=>  values
case evaluates the tests in order.

If a test returns true, the corresponding body is evaluated, and the last expression in the body is returned. If there is no body in the test that succeeds, then the first value of the test is returned. Subsequent tests are not evaluated.

If no test is true, then case returns #f.

As a special case, the keyword otherwise may appear as a test. This test always succeeds if there are no other successful tests.

case
   player1.money <= 0
     => end-game(player1);
   player2.money <= 0
     => end-game(player2);
   otherwise
     => move(player1);
        move(player2);
end case;
select ( target-form  [by test ] )	[Macro]
	match1a   , ...   match-1n   =>  body1;
	...
	matchma   ,  ...   match-mn   =>  bodym;
	[otherwise =>   otherwise-body ] [;]
	end [select]
=>  values
Each match-list must be a sequence of expressions separated by commas, or the keyword otherwise. The bodies are implicit bodies (may be any number of expressions separated by semicolons). When the select form is entered, the target-form is evaluated, generating a target value. The clauses are tested in order, using the following procedure:

* If there is no matching clause, an error is signaled.

As a special case, the keyword otherwise may appear instead of a match-list. This clause will be considered a match if no other match is found. Because an otherwise clause matches when no other clause matches, a select form that includes an otherwise clause will never signal an error for failure to match. Since testing stops when the first match is found, it is irrelevant whether the test function would also have returned true if called on later match-list elements of the same clause or on match-list elements of later clauses.

select ( career-choice(student) )
   art:, music:, drama:
     => "Don't quit your day job";
   literature:, history:, linguistics:
     => "That really is fascinating";
   science:, math:, engineering:
     => "Say, can you fix my VCR?";
   otherwise => "I wish you luck";
end select;
Dylan's select with a test of instance? is similar in effect to a Common Lisp typecase statement.
select ( my-object by instance? )
  <window>, <view>, <rectangle> => "a graphical object";
  <number>, <string>, <list> => "a computational object";
  otherwise => "I don't know";
end select
form1 | form2  =>  values	[Macro]
| ("or") evaluates the forms from left to right. If form1 returns true as its first value, that value is returned and form2 is not evaluated. If form1 returns #f as its first value, form2 is evaluated and its values are returned.
form1  &  form2   =>  values	[Macro]
& ("and") evaluates the forms from left to right. If form1 returns #f as its first value, #f is returned and form2 is not evaluated. If form1 returns true as its first value, form2 is evaluated and its values are returned.

Next section: Iteration Constructs