Lisp Programming: Accessors, Recursion, and Functions as Data - Prof. Ira Kalet, Study notes of Biology

An introduction to lisp programming, focusing on accessors, recursion, and functions as data. It covers the definition of accessors for patient records, recursive functions such as fibonacci and factorial, and the use of anonymous functions and local state. The document also discusses various common lisp functions and cliches, as well as examples of using local state and functions as data.

Typology: Study notes

Pre 2010

Uploaded on 03/10/2009

koofers-user-i4d
koofers-user-i4d 🇺🇸

10 documents

1 / 40

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Data abstraction example - patient records
A patient record could be structured as a list consisting of a name, address, telephone
numbers, date of birth, diagnosis, primary physician.
((simone jones)
((1234 boylston street) seattle wa 98102)
((home 206-234-5678) (work 425-432-8765))
(10 11 1978)
(pruritis-of-the-palm)
(angela a aardvark md))
For each item, we define an accessor
(defun name (pt) (first patient))
(defun first-name (pt) (first (name pt)))
(defun family-name (pt) (second (name pt)))
(defun address (pt) (second pt))
(defun street-address (pt) (first (address pt)))
(defun city (pt) (second (address pt)))
...
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28

Partial preview of the text

Download Lisp Programming: Accessors, Recursion, and Functions as Data - Prof. Ira Kalet and more Study notes Biology in PDF only on Docsity!

Data abstraction example - patient records

((simone jones)numbers, date of birth, diagnosis, primary physician. A patient record could be structured as a list consisting of a name, address, telephone (angela a aardvark md))(pruritis-of-the-palm)(10 11 1978)((home 206-234-5678) (work 425-432-8765))((1234 boylston street) seattle wa 98102) ...(defun city (pt) (second (address pt)))(defun street-address (pt) (first (address pt)))(defun address (pt) (second pt))(defun family-name (pt) (second (name pt)))(defun first-name (pt) (first (name pt))) (defun name (pt) (first patient)) For each item, we define an accessor

Accessors can do some work

(defun phone-number (pt &optional type) (let ((numbers (third pt))) (second (if type (assoc type numbers))

(first numbers))))

(defun print-nice-date (day month year)(defun birth-date (pt) (fourth pt)) (format nil "˜A-˜A-˜A" day (month-name month) year))

(defun month-name (m) (elt ’("JAN" "FEB" "MAR" "APR" "MAY" "JUN"

"JUL" "AUG" "SEP" "OCT" "NOV" "DEC")

(1- m)))

(defun formatted-birth-date (pt) (let ((date (birth-date pt)))

(print-nice-date (first date) (second date) (third date))))

Accessors can be used as lookup functions

To search a list of patients (

patient-db

) by patient’s family name, use

(findthe (previously defined) family-name function:

’kalet

patient-db

:key

#’family-name)

Of course this finds only the first such occurrence.

Later we will write a

name also.patient lookup function that returns all occurrences, and selects by first

Recursion

If find

(^) were not part of Common Lisp, we could write it. If

(^) thing

(^) is in the list,

(^) junk

, the

function returns it. Otherwise it returns

(^) nil

.

(defun my-find (thing junk) (cond ((null junk) nil)

(t (my-find thing (rest junk)))))((eql thing (first junk)) thing)

(defun my-find (thing junkHow could it be generalized? How could this be improved?

&key (test #’eql)

(key #’identity))

(cond ((null junk) nil)

((funcall test thing

(funcall key (first junk)))

(t (my-find thing (rest junk)(first junk))

:test test :key key))))

A template for recursive functions

All recursive functions follow the same general form:

3. Recursively handle the rest2. Handle the “base” or simple case1. Check if you are done

(defun

<fn-name>

(arg

arg2)

(cond

((null

arg2)

<some

result>)

((

arg

(first

arg2))

<simple

result>)

(t

<recursive

expression>)))

Recursive and iterative processes

(defun my-reverse (s) (if s (append (my-reverse (rest s))

(list (first s)))))

(defun another-reverse (s);;;----------------------------------------

(reverse-iter s

nil))

(defun reverse-iter (s accum) (if (null s) accum (reverse-iter (rest s)

(cons (first s) accum))))

The Factorial Function in C

In (^) C (^) you need a “main” to use it interactively.

{ main() #include <stdio.h> printf("n! = %d\n" factorial(n))scanf("%d", &n)int n;

{ long factorial(int n)/* for any small integer n, returns n! */} for (i = 1; ip = 1;int i, p;

<= n; ++i)

p = p *

i;

return p;

The Factorial Function - a java version

Here is how the factorial function would look in

(^) java

(^) (taken from “Java in a Nutshell”, by

/**David Flanagan, with end of line comments omitted):

This program computes factorial of a number

public class Factorial { public static void main(String[] args) { double result =int input = Integer.parseInt(args[0]);

(^) factorial(input);

System.out.println(result);

public static double factorial(int x) {} if (x < 0) return 0.0;

while(x >double fact = 1.0;

fact = fact *

(^) x;

x = x -

return fact;}

Transforming procedure for DNA replication

senting bases, An example of a procedure to map a DNA strand (represented by a list of symbols repre-

A, T, G, C

(defun dna-copy (input) (if (null input) nil (cons (dna-comp (first input))

(dna-copy (rest input)))))

The (^) dna-comp

(^) function just changes A to T and G to C, and vice versa.

(defun dna-comp (x) (cond ((eql x ’g) ’c)

(t (error "your dna is screwy"))))((eql x ’t) ’a)((eql x ’a) ’t)((eql x ’c) ’g)

DNA replication example

dna-copy

takes a

single

strand and makes a complementary strand by

> (dna-copytransforming each element and assembling a new list as it goes.

’(g

g c

a t t

t a a

g a c

c))

(C C

G T A

A A T

T C T

G G)

We can get the same effect with the

mapcar

function.

> (mapcar

#’dna-comp

’(g

g c

a t t

t a a

g a c

c))

(C C

G T A

A A T

T C T

G G)

mapcar

can be faked

If

mapcar

were not part of Common Lisp, you could write your own version.

(defun

fake-mapcar

(fn

s)

(if

(null

s) nil

(cons

(funcall

fn

(first

s))

(fake-mapcar

fn (rest

s)))))

As you find that other “clich ´

es” are needed but not built in, you should

begin with.define them and then use your defined function, just as if it were there to

More examples of cliches

Sometimes you would like to apply a predicate like

(^) and

(^) or (^) or , to another predicate func-

won’t work because (apply #’and (mapcar #’numberp my-list))tion on a list of items, e.g. to to check if every element of a list is a number, but

(^) and

(^) is a macro, not a function.

(defun check-if-all-numbers (list)Instead you could just use recursion to handle this. (if (null list) t (and (numberp (first list))

(check-if-all-numbers (rest list)))))

This pattern occurs so often that several functions were added to Common Lisp:

(^) every

some

, notany

, and

(^) notevery

. Just as with

(^) mapcar

(^) you could define your own version

(defun my-every (fn list)if it were not included. (if (null list) t (and (funcall fn (first list))

(my-every fn (rest list)))))

Using local state

The something from the local environment. Anonymous functions are just right when you want the function to use

find-patient

function matches for both first and last name from the

(defun find-patient (first-namepatient database:

patient-list)family-name

(first (remove-if-not #’(lambda (x)

(and (eql first-name

(first-name x))

(eql family-name

(family-name x))))

patient-list))))

More on using local state

The

mapcar

function maps a function over a list of data. Imagine a function

mapfun

that does just the opposite, mapping a piece of data over a list of

> (mapfunfunctions.

’(a

b c)

(list

#’length

#’reverse

#’first

#’rest

#’listp))

(3 (C

B A)

A (B C)

T)

(defun It can be defined as follows (using mapcar):

mapfun

(item

fns)

(mapcar

#’(lambda

(x)

(funcall

x

item))

fns))

Here too, the anonymous function is essential since it uses local state.