User Tools

Site Tools


ch2_1_defun

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
ch2_1_defun [2021/05/05 23:57] – created adminch2_1_defun [2022/03/31 04:57] (current) admin
Line 1: Line 1:
 **''DEFUN''** **''DEFUN''**
  
-''DEFUN'' form defines a named ordinary function object in global scope. It needs at least one symbol argument, which is not evaluated and will be the name of the function. Defun with no other arguments creates a function that evaluates to nil. For any practical use, we need to supply more arguments. Second argument must then be a list of parameters (symbols) of the function, the symbols are not evaluated and will be used for local binding of parameters once the defined function is called. In fact, no parts of the ''DEFUN'' expression are evaluated during the definition. Third argument is optional description string. If the third argument is not string, it is considered first form of the function body. Any other parameters are to ''DEFUN'' are stored as the function body.  +''DEFUN'' form defines a named ordinary function object in global scope. It needs at least one symbol argument, which is not evaluated and will be the name of the function. Defun with no other arguments creates a function that evaluates to ''NIL''. For any practical use, we need to supply more arguments. Second argument must then be a list of parameters (symbols) of the function, the symbols are not evaluated and will be used for local binding of parameters once the defined function is called. In fact, no parts of the ''DEFUN'' expression are evaluated during the definition. Third argument is optional description string. If the third argument is not string, it is considered first form of the function body. Any other parameters are to ''DEFUN'' are stored as the function body.  
  
 <code lisp> <code lisp>
-(defun adder (a b)  ; function named ADDER, arguments A, B +>(defun adder (a b)  ; function named ADDER, arguments A, B 
-  “replaces plus”   ; optional description string  +   “replaces plus”   ; optional description string  
-  (+ a b))          ; body expression+   (+ a b))          ; body expression 
 +ADDER                ; DEFUN returns the symbol naming the new function   
 </code>  </code> 
  
-In this example we have created function adder. Its body contains single arithmetic function. The newly defined function can be called as any other function. Result of the function adder will be result of the ''+'' function.+In this example we have created function adder. Its body contains single arithmetic function. The newly defined function can be called as any other function. Result of the function ''ADDER'' will be result of the ''+'' function.
  
 <code lisp> <code lisp>
Line 18: Line 19:
 If function body contains more expressions, all are evaluated sequentially (once the function is called), but only the output of the last one is returned from the function (this behavior is due to implicit ''PROGN''). If function body contains more expressions, all are evaluated sequentially (once the function is called), but only the output of the last one is returned from the function (this behavior is due to implicit ''PROGN'').
  
-In LabLisp it is not (yet) possible for user to define function with variable number of parameters. But some of the built-in functions support that (e.g. ''+'' or ''LIST'')and it is planned feature for user defined functions too+=== Optional parameters === 
 + 
 +Since LabLISP version 1.3, it is possible for user to define function with variable number of parameters, using a symbols ''&OPTIONAL'' and ''&REST'' in the list of parameters.   
 + 
 +<code lisp> 
 +(defun foo (a b &optional c d)  ...  ; arguments A, B must be given, C, D are optional  
 +</code>  
 + 
 +Such definition will create function with minimum 2 and maximum 4 parameters. If the the optional parameters are not supplied, when calling ''FOO'', they will have ''NIL'' value. It is possible to define initial value, if we need the optional parameter having some other value in such case:  
 + 
 +<code lisp> 
 +>(defun adder (a b &optional (c 0))  ; arguments A, B are mandatory, C is optional 
 +   (+ a b c))                        ; C defaults to 0, so the + will work 
 +ADDER                 
 +</code> 
 + 
 +Eventually, the initializer can contain additional parameter, which will indicate, whether the user actually supplied the optional argument.  
 + 
 +<code lisp> 
 +>(defun adder (a b &optional (c 0 d))  ; arguments A, B are mandatory, C is optional 
 +   (if d (print "c supplied") (print "c not supplied")) ; D indicates if C was given 
 +   (+ a b c))                        
 +ADDER                 
 +>(adder 1 2) 
 +"c not supplied" 
 +
 +>(adder 1 2 0) 
 +"c supplied" 
 +
 +</code> 
 + 
 +Functions can as well be defined with unlimited number of parameters with the ''&REST'' symbol. 
 + 
 +<code lisp> 
 +>(defun adder (&rest a)      ; parameter A represent any number of arguments 
 +   (apply #'+ a))            ; A is a list  
 +ADDER 
 +>(adder 1 2 3 4 5) 
 +15 
 +</code>  
 + 
 +The function will receive any number of arguments as list A. 
 + 
 +The mandatory, optional and rest paramters can be combinedOrder of the keywords ''&OPTIONAL'' and ''&REST'' must be kept. That means we can have any number of mandatory parameters, then ''&OPTIONAL'' keyword, after any number of optional parameters, with or without initializers, then ''&REST'', which must be followed by exactly one symbol. 
 + 
 +=== Lexical closure === 
 + 
 +Functions have lexical closure. In simple terms, it means that when called, the function body expressions are evaluated in the environment, where the function was defined, and not in the environment where called.  
 + 
 +<code lisp> 
 +>(let ((a 1))                        ; A is local variable 
 +   (defun add-a (b) (+ a b))         ; adds the argument B to the stored A 
 +   (defun set-new-a (x) (setq a x))) ; changes the stored A   
 +SET-NEW-A                            ; LET form returns the result 
 +</code> 
 + 
 +The two functions share the lexical environment ''LET'', that means they both can access the same A symbol. 
 + 
 +<code lisp> 
 +>(add-a 3)             ; calling the new function 
 +4                      ; it adds 3 to the stored A 
 + 
 +>(set-new-a 5)         ; now the stored value is changed 
 +
 + 
 +>(add-a 3) 
 +8                      ; new value A is used (5+3) 
 + 
 +>(let ((a 100)) (add-a 3)) ; local variable A=100 is not used by the function ... 
 +8                          ; ... we still use the 5 
 +</code> 
  
ch2_1_defun.1620280671.txt.gz · Last modified: 2021/05/05 23:57 by admin

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki