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 ]