Advanced Functions - PowerPoint PPT Presentation

About This Presentation
Title:

Advanced Functions

Description:

Advanced Functions In CL, functions are often supplied as parameters to other functions This gives us tremendous flexibility in writing functions whose specific ... – PowerPoint PPT presentation

Number of Views:66
Avg rating:3.0/5.0
Slides: 18
Provided by: NKU
Learn more at: https://www.nku.edu
Category:

less

Transcript and Presenter's Notes

Title: Advanced Functions


1
Advanced Functions
  • In CL, functions are often supplied as parameters
    to other functions
  • This gives us tremendous flexibility in writing
    functions whose specific behavior will be
    determined later when someone else (or you)
    supplies a function
  • functions can be passed as parameters
  • functions can be specified as arguments
  • functions can be applied to a given list of data
    to use the results of that application
  • Here, we consider how to do these various things
  • what permits this is that a function in CL is
    treated like any other data type and is pointed
    to by a pointer
  • to denote that something is a function, it is
    preceded by as in evenp or gt or length
  • the basic REPL function eval, can be applied at
    any time
  • similarly, alternative functions exist to apply a
    function to data (mapping functions, funcall,
    apply, etc)

2
Example
  • Consider that you want to write a plotting
    function that, given values x and y, will plot
    the values f(i) for i from x to y
  • This is easy to write if you already know f
  • The problem with this is that plot only works for
    function f

(defun plot (x y) (let (temp) used to
store f(i) (do ((i x ( i 1)))
iterate for i from x to y ((gt i y))
(setf temp (f i)) temp f(i)
(dotimes (a temp) do
f(i) times (format t
)) print an (format
t )))) start a new line afterward
3
Solution Pass the Function
  • Here, we pass the function that we want to apply
    as a parameter
  • To apply the function to a value, i in this case,
    we use funcall

We call plotf passing it functionname and x and
y as in (plotf add_1 5 10) if we have a
function called add_1, or (plotf square 5
10) if we have a function called square
(defun plotf (f x y) (let (temp)
(do ((i x ( i 1))) ((gt i y))
(setf temp (funcall f i))
(dotimes (a temp) (format t ""))
(format t ""))))
4
Another Approach Apply
  • Aside from using funcall, which expects as params
    a function and parameter(s), you can use apply
  • Apply applies a function to a list of parameters
    where the function can be any of
  • a compiled function
  • (apply max (3 5 4 2)) ? 5
  • a lambda-expression
  • (apply (lambda (x y) (if (gt x 0) y ( y -1)))
    (0 3)) ? -3
  • a symbol (which could be stored in a variable or
    provided in the apply statement)
  • (setf f )
  • (apply f (1 2)) ? 3
  • Note since apply expects the parameter(s) to be
    in a list, if the function to be applied is one
    that expects a single atom as a parameter, it
    still must be placed into a list
  • (apply numberp (list x)) is correct
  • (apply numberp x) is incorrect

5
Lambda Functions
  • A lambda function is a nameless function
  • Having a function with no name seems useless
  • how can you use it?
  • There are occasions where you will need a
    function one time to be applied right away
  • you can define a lambda function for this purpose
  • There are numerous functions that apply functions
  • mapcar for instance
  • Lambda functions are written using the following
    notation
  • (lambda (params) body)
  • As in (lambda (x) ( x 1)) ? this function will
    return 1 greater than whatever the argument is
  • you will use the defined lambda function inside
    of another function, such as in apply or mapcar,
    and there are other circumstances as we will see
    later

6
Mapping Revisited
  • Recall the mapping functions
  • They apply a function to a list and return a new
    list
  • mapcar apply the car of the list to the
    function and then cons the result to (mapcar
    function (cdr lis))
  • We specify the function as name or (lambda
    expression)
  • (mapcar numberp lis) ? (list of items where T
    corresponds to those that are numbers and nil to
    those that are not)
  • Here is an example of using mapcar with a lambda
    expression
  • (mapcar (lambda (x) (if (gt x 0) x ( x -1)))
    lis) ? this returns the list of (hopefully
    numbers) after applying absolute value
  • alternatively, we can achieve the same by doing
  • (mapcar abs lis)
  • Now that weve seen the basics of applying
    functions, we reconsider some of the functions
    covered earlier in the semester and see that they
    are far more flexible than we originally thought

7
Functions that Apply Functions
  • Many of the sequence functions can take functions
    as additional parameters
  • Recall count
  • (count a b) counts the number of times a occurs
    in b
  • (count 5 (3 5 7 8 4 6 2)) ? 1
  • count also has a parameter called test which can
    be supplied with a function, if true when applied
    to the parameter, then count counts that
    parameter
  • (count a b test gt) counts the number of
    times that a is greater than each element in b
  • (count 5 (3 5 7 8 4 6 2) test gt) ? 3
  • (count 5 (3 5 7 8 4 6 2) test gt) ? 4
  • Similarly, remove, position, find, delete (the
    destructive version of remove), replace and subst
    can all take test arguments

8
-if and -if-not Functions
  • The same functions have variants that end with
    -if and -if-not
  • (count-if function lis)
  • Count the number of elements of lis that, when
    applied to the function, are t
  • (count-if numberp (3 3.3 a \a t)) ? 2
  • (count-if-not evenp (6 3 7 2 9 1)) ? 4
  • 4 of the items are not t when evenp is applied
  • Functions that have -if and -if-not variants
  • member, find, replace, position, delete, subst,
    assoc, rassoc
  • also stable-sort and merge
  • Example lis is a list of various atoms
    (numbers, symbols, characters, t, nil) and we
    want to return the list that constitutes only
    numbers
  • (remove-if-not numberp lis) non-destructive,
    returns new list
  • (delete-if-not numberp lis) destructive
    version, lis is altered
  • Note in this latter version, we would no longer
    want lis because it still may contain non-numbers
  • Notice we do not supply an argument to be
    compared, only a test
  • (count 5 lis) ? counts number of 5s in lis but
    (count-if equal-to-five lis) ? uses a function
    to compare the elements of lis

9
Examples
(remove-if numberp (a b 3 c 3.3 d 1/3 e 11
nil 10)) ? (a b c d e 11 nil) (remove-if-not
numberp (a b 3 c 3.3 d 1/3 e 11 nil 10))
? (3 3.3 1/3 10) Notice that we cannot use
(remove lis test numberp) here this lacks a
parameter the element to be removed (remove-if
(lambda (x) (not (numberp x))) (a b 3 c 3.3
d 1/3 e 11 nil 10)) ? (3 3.3 1/3
10) (count-if (lambda (x) (equal x 5)) (a 5 b
5 c 3 d 55)) (position-if zerop (1 2 4 12 0
16 17)) ? 4 (member-if listp (a b c d)) ?
nil (member-if listp (a (b c) (d e f) g (h)))
?((b c) (d e f) g (h)) The functions supplied in
these examples are predicate functions that use a
list element as a parameter, we dont have the
ability to do something like (count-if gt ())
because we cant specify the value we want to
test gt against yet
10
test, test-not, count and key
  • In addition to adding if or if-not, many of
    these sequence functions can take test and
    test-not parameters
  • The sequence function is applied to the element
    of the sequence if the test result is non-nil
    (for test) or nil (for test-not)
  • (count 3 (3 6 2 1 7 4) test gt) ? 3 (number of
    elements gt 3)
  • The count parameter is used to limit the number
    of elements in a sequence that are examined by
    the function being applied
  • this can also be used with from-end t to work
    backwards
  • (remove 3 (1 2 3 4 3 5 3 6 3) count 2) ? (1 2 4
    5 3 6 3)
  • (remove 3 (1 2 3 4 3 5 3 6 3) count 2 from-end
    t) ? (1 2 3 4 3 5 6)
  • The key parameter allows you to supply another
    function to apply to the parameter prior to
    applying the main function
  • For instance, if your list is really a list of
    lists, you can supply key car so that your test
    applies only to the car of each sublist
  • If lis is ((csc 375) (cit 140) (eng 200) (csc
    402) (mat 385)) then we can count the number of
    csc coursers as
  • (count csc lis key car)

11
Additional Examples
  • Let lis1 be (3 6 2 1 7 4)
  • And lis2 be ((a 3) (b 4) (5 c) (6 d) (7 2) (e 8)
    (3 f))
  • (member 3 lis test gt) ? (2 1 7 4)
  • returns the member of the first item where 3 gt
    item (that is, the first item smaller than 3)
  • (remove 3 (3 6 2 1 7 4) test lt) ? (3 2 1)
  • returns the list where every number in which 3 lt
    is true is removed (so 6, 7 and 4 are removed
    since 3 lt them)
  • (member-if-not numberp lis2 key cadr) ? ((5
    C) (6 D) (7 2) (E 8) (3 F))
  • (remove 3 lis2 key car) ? ((A 3) (B 4) (5 C)
    (6 D) (7 2) (E 8))
  • (remove-if-not oddp lis1) ? (3 1 7)
  • What if I want to remove two of the top-level
    elements from the rear of lis2 where the second
    element gt 4?
  • (remove 4 lis2 test gt from-end t key cadr)
    ? this yields an error
  • cant apply gt to the letter symbols (such as (6
    d)) so instead, lets try this
  • (remove-if (lambda (x) (and (numberp x) (gt x
    4))) lis2 count 2 from-end t key cadr) ? ((A
    3) (B 4) (5 C) (6 D) (7 2) (3 F))

12
Sorting
  • CL has a built-in sort function which must be
    supplied the sequence to sort and a function to
    apply (the test used in sorting such as gt)
  • Form (sort sequence function)
  • (sort (5 3 6 2 9 8 1 7) gt) ? (9 8 7 6 5 3 2 1)
  • What if I have a list of lists like lis2
    previously where each sublist contains an atom
    and a number in that order?
  • (sort ((c 5) (b 3) (d 4) (a 6) (e 1) (f 2)) gt
    key cadr) ? ((A 6) (C 5) (D 4) (B 3) (F 2) (E
    1))
  • Note sort is destructive, so that (sort lis1
    lt) from the previous slide will return (1 2 3 4
    6 7) and lis1 will now be (1 2 3 4 6 7)
  • Stable-sort is a variation of sort that is
    guaranteed to not reorder elements that are equal
    (this could happen for instance if we had a list
    like ((c 5) (d 4) (a 5) (b 2) (e 4)) depending on
    how sort is implemented

13
Sequence Predicates
  • Just as sequences have these functions that take
    a function as an argument, there are also
    sequence predicate functions
  • Each of these takes a function and a sequence and
    applies the function to each list element until
    either the predicate has been determined
    (short-circuiting causes it to stop at this
    point) or it has reached the end of the sequence
  • The sequence predicates are
  • every all elements of the sequence must pass
    the test to return t, else nil
  • some at least 1 element must pass to return t,
    else nil
  • notany all elements must fail the test to
    return t, else nil
  • notevery at least 1 element must fail to return
    t, else nil
  • (every plusp lis)
  • returns t only if every element of lis is a
    positive number, nil otherwise (or error if not
    element element of lis can be applied to plusp)
  • (if (notany minusp lis) (mapcar sqrt lis)
    (format t error in taking square root))
  • if notany returns t then mapcar proceeds,
    otherwise we send an output message

14
Applying Functions To Multiple Items
  • The predicate functions, mapcar, and others can
    apply to multiple sequences when supplied with a
    function that takes multiple arguments
  • Consider that a is the list (1 2 3) and b is the
    list (2 4 6)
  • (every gt b a) ? compares 2 to 1, 4 to 2, 6 to 3
    and returns t
  • (some a b) ? nil since no pair is equal (1,
    2 2, 4 3, 6)
  • (mapcar a b) ? (3 6 9)
  • (mapcar (remove 'evenp a) (remove 4 b)) ? (3
    8)
  • Notice here that we run the risk of having lists
    of two different lengths which will work, but may
    not be what we expect
  • We also run the risk of a and/or b containing
    non-numbers
  • (if (and (every numberp (append a b)) (
    (length a) (length b))) (mapcar a b))
  • This fixes both of the previous problems

15
Map and Map-Into
  • These are variations of the mapping functions
  • Map is just like mapcar but takes an additional
    parameter of the type of sequence to create
  • (map list (1 2 3 4) (2 4 6 8)) ? (3 6 9
    12)
  • Notice how map, like other sequence operations,
    can take data of one form (a vector here) and
    translate it into another (a list)
  • (map string char-upper (\a \b \! \3 \c))
    ? AB!3C
  • Map-into is destructive in that it performs the
    mapping, but rather than returning a new
    sequence, it places the result into a given
    sequence
  • (map-into a b c) is the same as the vector
    operation a b c assuming that a, b and c are
    all vectors storing numbers
  • Assume a may store some non-numbers and we want a
    pair-wise addition of a and b, here we remove all
    non-numbers from a and reduce the size of b to be
    equally lengthed
  • (map vector (remove-if-not numberp c)
    (remove-if numberp d from-end t count (-
    (length c) (count-if-not numberp c) 1))
  • if c is (1 a b 3 c 4 5) and b is (1 2 3 4 5 6 7),
    then this returns the vector (2 5 7 9) 1 1,
    3 2, 4 3, 5 4 (we removed 3 letters from c
    so we removed the last 3 numbers from b)

16
Reduce
  • Form (reduce function list) ? atom
  • This applies the function to the first x
    arguments in list depending on what the function
    does (typically 2 arguments) and then applies the
    result to the next argument, etc through the
    remainder of the list
  • It returns the single item that the function is
    supposed to return, a number for an arithmetic
    operator, t/nil for a boolean function, etc
  • Examples
  • (reduce (1 2 3 4 5)) ? 15
  • (reduce (1 2 3 4 5)) ? 120
  • (reduce equal (2 2 t t t) ? t
  • (reduce max (3 5 4 2 1) ? 5
  • And of course, we can combine functions
  • (reduce (remove 0 lis)) eliminate 0s first
  • (reduce (remove-if-not numberp lis))
    eliminate non numbers first
  • (reduce max (remove 100 lis test gt))
  • eliminate any numbers gt 100 first

17
Other Function Functions
  • flet allows you to define/declare a function
    locally inside a function
  • labels is the same as flet except that the
    functions can be recursive
  • macrolet is the same as flet but for macros
    (which we cover next)

(defun foo (x y) (flet ((square (x) (
x x)) (cube (x) ( x x x)))
(if (gt (cube x) (square y)) (cube y) (square
x)))) (defun foo2 (x y) (flet (( (x
y) (do ((i 0 ( i 1))) (( i (length x)))
(setf (nth i x)
( (nth i x) (nth i y)))) x)) (
x y)))
Write a Comment
User Comments (0)
About PowerShow.com