Erlang (programming language)/Tutorials/guards: Difference between revisions

From Citizendium
Jump to navigation Jump to search
imported>Eric Evers
(New page: =Erlang Guards= ===Guard structures=== Legal guards in Erlang are boolean functions placed after the key word, "when" and before the arrow, "->". Guards may appear as part of a function...)
 
imported>Eric Evers
Line 99: Line 99:
  length(Z) > N  
  length(Z) > N  


  A > B
  A > B       greater than
  A < B
  A < B       less than
  A == B
  A == B     equal to
  A =< B
  A =< B     equal to or greater than (notice non-standard notation)
  A >= B
  A >= B     greater than or equal to (notice non-standard notation)
  A /= B
  A /= B     not equal
  A =:= B    exactly equal
  A =:= B    exactly equal
  A =/= B    exactly not equal
  A =/= B    exactly not equal

Revision as of 20:08, 19 April 2008

Erlang Guards

Guard structures

Legal guards in Erlang are boolean functions placed after the key word, "when" and before the arrow, "->". Guards may appear as part of a function definition, 'receive' 'if', 'case' and 'try/catch' expressions.

We can use a guard in a function definition
Example program: guardian.erl

-module(guardian).
-compile(export_all).
   
the_answer_is(N) when N == 42 -> true;
the_answer_is(N) -> false.
   
% ============================================= >% 
%
% Example output:
%
% c(guardian).
% ok
%
% guardian:the_answer_is(42).
% true
%
% guardian:the_answer_is(21).
% false

and Fun definition

 F = fun(N) when N == 42 -> true;
              (N) -> false
        end.

receive expression

 receive
   {answer, N} when N == 42 -> true;
   {answer, N} -> false
 end.

if expression

 if 
   N == 42 -> true;
   true -> false
 end.

case expression

 case L of
   {answer, N} when N == 42 -> true;
   _ -> false
 end.

and try/catch

 try find(L) of
    {answer, N} when N == 42 -> true;
    _ -> false
 catch
    {notanumber, R} when is_list(R) -> alist;
    {notanumber, R} when is_float(R) -> afloat
    _ -> noidea
 end.

You will notice that in these examples it would be clearer to remove the guard and modify the pattern matching instead.

Literate programming note: Anonymous match variables that start with an underscore like "_" are not generally recommended. Rather, it is nice to use some descriptive variable name like "_AnyNode". On the otherhand, for tutorial code like this, a descriptive variable is more distracting than helpful.

 case L of
   {node, N} when N == 42 -> true;
   _AnyNode -> false
 end.

Guard functions

There are several built-in-functions (BIFs) which may be used in a guard.

is_alive/0                     
is_boolean/1                    
is_builtin/3                    
is_constant/1                   
is_float/1                      
is_function/2      is_function( Z, Arity)               
is_function/1                  
is_integer/1                    
is_list/1                       
is_number/1                     
is_pid/1                        
is_port/1                      
is_process_alive/1               
is_record/3                    
is_record/2                     
is_reference/1                 
is_tuple/1      
              
length(Z) > N 
A > B       greater than
A < B       less than
A == B      equal to
A =< B      equal to or greater than (notice non-standard notation)
A >= B      greater than or equal to (notice non-standard notation)
A /= B      not equal
A =:= B     exactly equal
A =/= B     exactly not equal

Note: all erlang data types have a natural sort order.

atom < reference < port < pid < tuple < list ...

Guards can be compound expressions.

the_answer_is(N) when N == 42, is_integer(N) -> true;