CS 451 Programming Paradigms
LISP Higher Order Function Tutorial



badshot 52 % cl

Allegro CL 4.3 [Linux/X86; R1] (8/26/98 12:09)
Copyright (C) 1985-1996, Franz Inc., Berkeley, CA, USA.  All Rights Reserved.
;; Optimization settings: safety 1, space 1, speed 1, debug 2.
;; For a complete description of all compiler switches given the
;; current optimization settings evaluate (EXPLAIN-COMPILER-SETTINGS).

USER(1): ;;;Higher Order Functions


USER(1): ;;; functions as arguments


USER(1): ;;; application of symbols bound to functions to arguments


USER(1): ;;; functions as return-values of other functions


USER(1): ;;; exp:  (filter '(1 2 7 8 9 11) <fn to test evenness> )


USER(1): 

(defun filter (l test)
  (cond
   ( (null l) nil)
   ( (funcall test (car l))  (cons (car l) (filter (cdr l) test)))
   ( t (filter (cdr l) test) ) ) )
FILTER


USER(2): (filter '(1 2 7 8 9 11) #'evenp)
(2 8)                         


USER(3): ;;;  why the #'  ?  Use with funcall and apply but not with eval


USER(3): ;;; variations among different LISPs, scheme.


USER(3): ;;; Allegro allows both sometimes, safer to use (except w/eval) best to understand


USER(3): ;;; suppose you have constructed in some variable the list which


USER(3): ;;; is to be the argument for some function call.  How do you apply them


USER(3): ;;; One way some of you know is eval.  Another is apply.


USER(3): (apply #'car '( (a b c) ) )
A


USER(4): ;;; NOTE you put the argument(s) in a LIST...


USER(4): ;;; eval requires you to construct the executable expression first


USER(4): (eval '(car '(a b c)) )
A         


USER(11): (let ( (lst (list 'car (quote (list 'a 'b 'c)))) ) (eval lst) )
A             


USER(13): ;;; A map function:  (map func l)  get a list of results      


USER(15): 
(defun ourmap (func l)
  (cond
    ((null l) nil)
    (t (cons (funcall func (car l)) (ourmap func (cdr l))))))  
OURMAP


USER(21): (ourmap #'evenp '(1 2 7 8 9 11))
(NIL T NIL T NIL NIL)   


USER(22): ;;; built-in function map's first argument over successive cars of a list


USER(22): ;;; can take multiple arguments


USER(22): (mapcar 'max '(3 9 17) '(2 4 11) '(7 3 2))
(7 9 17)           


USER(23): ;;; real example:  (mapcar #'safe (generate-children state)) -> (nil s3 nil s7)


USER(23): ;;; could use filter: (filter #'safe (generate-children state)) -> (s3 s7)


USER(23): ;;; LAMBDA EXPRESSIONS!!     


USER(23): ;;; NO NAME functions,  ON-THE-FLY construction, functional behavior


USER(23): ;;; without naming or necessarily specifying ahead of run-time


USER(23): ;;; ease of creating functions as return values     


USER(25): (filter '(nil 5 nil 7 6) #'(lambda (p) (not (null p))) )
(5 7 6)      


USER(26):
(defun foo (num)
  (cond
    ((equal num 5) #'(lambda (x) (+ x num)) )
    (t #'(lambda (x) (+ x 0)))))      


USER(29): (eval (list (foo 5) 7))
12         


USER(30): (apply (foo 5) '(7))
12    


USER(31): (funcall (foo 6) 7)
7          


USER(33): ;;;  lambda ALWAYS evaluates to a function, unapplied


USER(33): ;;; must use eval, apply, funcall, <use> or bind to var for one of these later


USER(33): ;;;  What is this pound?  Look back at foo


USER(33): ;;;  Called a CLOSURE (from transitive closure in set theory)


USER(33): ;;; it means find all references to values not in scope of the argument


USER(33): ;;; and bind them together with the function argument--often a lambda


USER(33): ;;;  it is shorthand for (function '<function_name_or_lambda_expr>)


USER(33): (defun incr-by (n) #'(lambda (x) (+ x n)))
INCR-BY 


USER(38): (funcall (incr-by 5) 6)
11    


USER(39): ;;;; NOTE equivalence of let-binding to lambda:


USER(39): (let  (  (a 5) (b 6) ) (+ a b) )
11


USER(40): (funcall #'(lambda (a b) (+ a b)) 5 6)
11         


USER(41): :exit
; Exiting Lisp
badshot 53 %    



[ Back to CS451: The LISP Segment ]