User Tools

Site Tools


ch2_3_manage

Higher order management functions

Here we will list functions that serve for higher order of the language management, in other words functions that expand LISP by acting on the language itself, in some sense.

FUNCALL and APPLY

Both functions apply a function supplied as first argument to parameters, they only differ in the way how the parameters are supplied:

(funcall #'foo a b c)   ; parameters are in the same list
(apply #'foo (list a b c))  ; parameters are in separate list

Note that since the FUNCALL and APPLY are functions, not special operators, the arguments are first evaluated in the FUNCALL/APPLY function-application form. Then they are supplied to the function object foo. The first argument must be function designator, which means either function-object itself, or a symbol which has global function binding:

(funcall #'cons 'a 'b)    ; is ok - function object
 
(funcall 'cons 'a 'b)     ; is ok - symbol CONS names global function
 
(funcall cons 'a 'b)      ; is not ok - CONS evaluated to value, not function

But we can do this

>(setq foo #'cons)        ; function object in the value cell of FOO
#<function CONS>
 
>(funcall foo 'a 'b)      ; symbol FOO then evals to function object
(A . B)

Both actually accept any number of parameters. In APPLY the last argument must be list. The called function will check if it has the right number of parameters. Here is example with +, which also accepts any number of parameters:

(funcall #'+ 1 2 3 4)   ; these three calls do the same
 
(apply #'+ '(1 2 3 4))  ; single list with four elements
 
(apply #'+ 1 2 '(3 4))  ; the loose atoms are consed to the ending list

MAPCAR, MAPLIST, MAPCAN, MAPCON, MAPC, MAPL

These six similar functions apply given function to a list of arguments and produce a list of outputs. First argument must be function object, or symbol representing global function. Then can have any number of arguments, that must be proper lists. Let's have some examples:

>(defun sqr (a) (* a a))     ; define square function
SQR
>(mapcar #'sqr '(1 2 3 4))   ; map to list of numbers
(1 4 9 16)                   ; get list of squares
>(mapcar #'+ '(1 2 3) '(10 20 30))  ; can map multiple lists
(11 22 33)                          

If lists of different leghths are supplied, the output lenght will be given by the shortest input list. The number of supplied lists should match the allowed number of parameters of the applied function.

Mutually, these 6 differ in a way how the input list is treated (2 ways), and how the output list is returned (3 ways). So we have 3 pairs:

  • MAPCAR and MAPLIST return freshly consed list of the results of the individual calls.
  • MAPCAN and MAPCON make sense for applying functions that return lists. The final returned list is consed together from the individual outputs as a single list. This is done by modifying the individual outputs as with NCONC.
  • MAPC and MAPL return just their first list argument, so they do not create any new conses. Only make sense for side effects of the applied function.

In each of the pairs the first one passes the individual elements of the argument list. The second one passes the actual cons cells of the argument list:

>(mapcar 'print '(a b c))  ; MAPCAR
A                          ; prints individual elements ...
B                          ; ... which is the side effect of PRINT
C
(A B C)                    ; returns list of the outputs
>(maplist 'print '(a b c)) ; MAPLIST
(A B C)                    ; prints the remaining list
(B C)                      
(C)
((A B C) (B C) (C))

The MAPCAN and MAPCON connect together the lists the same way as NCONC, so they ignore (drop) dotted ends and can end up with cyclic list - if the last returned list is cyclic.

MACROEXPAND and MACROEXPAND-1

Both functions return the expansion of the macro code for the leading operator of the supplied form. MACROEXPAND-1 expands first level of macro expression, MACROEXPAND expands all levels. They expect one argument, which can be anything, but it only makes sense to use then on quoted expression which has a macro call in the functor position. Both functions return second value, which is T when the input was actually macro form and got expanded, otherwise NIL for non-macro expressions.

>(defmacro add (a b) `(+ ,a ,b))       ; defined simple macro
ADD
 
>(macroexpand '(add 1 2))              ; quoted expression with the macro
(+ 1 2)                                ; this is the expansion
T                                      ; second value
 
>(defmacro adder (c d) `(add ,c ,d))   ; define new macro which uses the previous
ADDER
 
>(macroexpand-1 '(adder 3 4))          
(ADD 3 4)                              ; expands only the first level
T
 
>(macroexpand '(adder 3 4))             
(+3 4)                                 ; expands also the deeper level macro
T
 
>(macroexpand '(add (add 3 4) 2))      
(+ (ADD 3 4) 2)                        ; only expands the leading symbol
T
 
>(macroexpand '(+ 3 4))                ; not a macro expression
(+ 3 4)
NIL                                    ; indicated by the NIL second value

See also Macros.

SET

Primitive SET as function, expects exactly two arguments, first must be symbol. Normally use SETQ, but SET might be helpful in the rare case where we need variability in the symbol argument.

>(set 'a 12)                  ; is same as (SETQ a 12)
12
>(set (cadr '(a b)) 45)       ; first argument evals to symbol B
45
>b                            ; so B was set to 45
45                     

VALUES

Some functions return multiple values, e.g. ROUND, or MACROEXPAND above. Function VALUES allows us to return multiple values, constructed from the arguments supplied. Accepts any number of arguments, even no arguments.

>(values 1 2)
1                 ; returned as separate values
2
>(values)
                  ; no return value                            
>(values 3)
3                 ; trivial single value                        

NAME-PROCESS

Cosmetic function for labeling processes as shown on the LabLISP window, accepts one or two arguments. First must be string - the desired name. Second argument is optional integer specifying the process number, if not supplied, the active process is renamed. This function can be only meaningfully used on the active running process, to give information about reason for waiting. Returns the string name.

..
(move-motor 100)                ; non-blocking call to start moving
(name-process "motor moving")   ; text will appear next to the active process
(wait (motor-moves?))           ; waiting loop for end of physical operation
..                      

KILL

Function kills given process, needs one argument, the process number. Cannot be used on the active running process. Meaningful use is killing process stuck in an infinite loop. Returns NIL always.

>(wait t)              ; infinite loop in process #0
>(kill 0)              ; user entry, process #1
p#01>NIL               ; return of the KILL function in process #1

SELF-KILL

This function kills the active running process, no arguments, returns NIL. Although this might seem meaningless, this function is useful in mechanics for aborting script.

The last three functions are unique for LabLISP multi-process mechanics.

See also the section 1.2 about multi-process behavior in LabLISP.

ch2_3_manage.txt · Last modified: 2024/05/04 11:15 by admin

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki