:
op, union, member, subset, length, mod amongst others.  
The difference between   procedures and functions in Darwin is entirely conceptual.
The exact same syntax is used for defining both and, actually,  procedures
do return a value. Recall our procedure SetAverage from
§
.  
> SetAverage := proc( s : set )
>   local total;
>   description 'This procedure takes a set as an argument and
>                calculates the average value in the set';
>   total := 0:
>   for i from 1 to length(s) do
>     total := total + s[i];
>   od;
>   lprint('The average is ', total/length(s));
> end:
The procedure SetAverage returns the value NULL.
> x := SetAverage({1,2,3}):
> if (x=NULL) then print('It is NULL'); fi;
It is NULL
Let us re-write SetAverage to be a function.> NewSetAverage := proc( s : set(real) ) > local total; > description 'This procedure takes a set of real values as an > argument and calculates the average value in the set'; > total := 0: > for i from 1 to length(s) do > total := total + s[i]; > od; > ave := total/length(s); > ave; > end:Now the last statement executed when NewSetAverage is invoked is the bottom-most (trivial) statement ave;. The result of this expression is simply the value assigned to this variable. We say that the value of the entire function NewSetAverage is assigned the value of ave and it is this value which Darwin returns to the point where the function was called.
> x := NewSetAverage({3, 5}):            # the value of function new_SetAverage 
> print(x);                              #   is assigned to variable x
4