`;;; implement own version of not`
`(defun my-not (anything)`
` (if anything`
` nil`
` t))`

`;;; function of two numbers - return the smaller`
`(defun smaller-of-two (first-number second-number)`
` (if (< first-number second-number)`
` first-number`
` second-number))`

`;;; function of three numbers - return the smallest`
`(defun smallest-of-three (first-number second-number third-number)`
` (if (and (< first-number second-number) (< first-number
third-number))`
` first-number`
` (if (< second-number third-number)`
` second-number`
` third-number)))`

`;;; same again, but this version is more readable`
`(defun smallest-of-three (first-number second-number third-number)`
` (smaller-of-two (smaller-of-two first-number smaller-of-two)
third-number))`

`;;; reverse the function fahrenheit-to-celsius`
`(defun celsius-to-fahrenheit ()`
` (format t "~&Please give a value in degrees C: ")`
` (let* ((celsius (read))`
` (fahrenheit (float
(+ (* celsius 9/5) 32))))`
` (format t "~&~a degrees C is ~a degrees
F.~&" celsius fahrenheit)))`

`;;; (and foo bar) transforms into (if foo bar nil)`
`(defun transform-and-with-two-args (form)`
` (let* ((first-subform (second form)) ; the first subform
was the symbol AND`
` (second-subform
(third form)))`
` (list 'if first-subform second-subform nil)))`

`;;; (and foo bar baz) transforms into (if foo (if bar baz nil) nil)`
`(defun transform-and-with-three-args (form)`
` (let* ((first-subform (second form)) ; the first subform
was the symbol AND`
` (second-subform
(third form))`
` (third-subform
(fourth form)))`
` (list 'if`
` first-subform`
` (list 'if
second-subform third-subform nil)`
` nil)))`

`#|`
`When considering transformation of (or foo bar) we have to be a`
`little bit careful.`

`Consider`

` (defun ask-for-help-and-return-t ()`
` (format t "Help!")`
` t)`

` (or (ask-for-help-and-return-t) nil)`

`Transforming (or foo bar) into`
` (if foo`
` foo`
` bar)`
`would lead to double trouble.`

`Hint: use let* ...`
`|#`

`;;; (or foo bar) transforms into`
`#|`
`(let* ((foo-evaluated foo))`
` (if foo-evaluated`
` foo-evaluated`
` bar))`
`|#`
`(defun transform-or-with-two-args (form)`
` (let* ((first-subform (second form))`
` (second-subform
(third form)))`
` (list 'let*`
` (list (list
'first-evaluated first-subform))`
` (list 'if
'first-evaluated 'first-evaluated second-subform))))`

`;;; (or foo bar baz) transforms into`
`#|`
`(let* ((foo-evaluated foo))`
` (if foo-evaluated`
` foo-evaluated`
` (let* ((bar-evaluated bar))`
` (if bar-evaluated`
` bar-evaluated`
` baz))))`
`|#`

`;;; this is getting really revolting. there has to be a better way`
`;;; (and, indeed, there is)`
`(defun transform-or-with-three-args (form)`
` (let* ((first-subform (second form))`
` (second-subform
(third form))`
` (third-subform
(fourth form)))`
` (list 'let*`
` (list (list
'first-evaluated first-subform))`
` (list 'if`
`
'first-evaluated`
`
'first-evaluated`
`
(list 'let*`
`
(list (list 'second-evaluated second-subform))`
`
(list 'if`
`
'second-evaluated`
`
'second-evaluated`
`
third-subform))))))`

If you have tried the exercises, looked at the solutions and still do not understand what's going on, I am available for consultation at the times advertised on my office door. Bring your code with you in BOTH the following forms:

- Logbook containing printout (nothing handwritten please)
- file on floppy

Nick Levine

last modified 2000-10-17

Copyright (C) Nick Levine 1999. All rights reserved.

$Id: //info.ravenbrook.com/user/ndl/lisp/declarative/lectures/solutions/solutions-3.html#2 $

last modified 2000-10-17

Copyright (C) Nick Levine 1999. All rights reserved.

$Id: //info.ravenbrook.com/user/ndl/lisp/declarative/lectures/solutions/solutions-3.html#2 $