How do I call another function in lisp;

2019-09-21 19:31发布

问题:

My program is supposed to convert a given temperature from Fahrenheit to Centigrade or the other way around. It takes in a list containing a number and a letter. The letter is the temperature and the letter is the unit we are in. Then I call the appropriate function either F-to-C or C-to-F. How do I call the functions with the given list that was first checked in my temperature-conversion function. Here is my code.

 (defun temperature-conversion (lst)
  (cond
  ((member 'F lst) (F-to-C))
  ((member 'C lst) (C-to-F))
  (t (print "You didn't enter a valid unit for conversion"))
  )
)
(defun F-to-C ()
;;(print "hello")
 (print (temperature-conversion(lst)))
)   
(defun C-to-F ()
(print "goodbye"))  
;;(print (temperature-conversion '(900 f)))
(setf data1 '(900 f))

回答1:

You have infinite recursion: temperature-conversion calls F-to-C which calls temperature-conversion again.

I would do this:

(defun c2f (c) (+ 32 (/ (* 9 c) 5)))
(defun f2c (f) (/ (* 5 (- f 32)) 9))
(defun temperature-conversion (spec)
  (ecase (second spec)
    (C (c2f (first spec)))
    (F (f2c (first spec)))))
(temperature-conversion '(32 f))
==> 0
(temperature-conversion '(100 c))
==> 212
(temperature-conversion '(100))

*** - The value of (SECOND SPEC) must be one of C, F
      The value is: NIL
The following restarts are available:
ABORT          :R1      Abort main loop


回答2:

I think this example is generally used to demonstrate how functions are first-class values.

With a little modification to sds's answer, you can have an ECASE statement that selects the appropriate function, which is then used by a surrounding FUNCALL.

(defun temperature-conversion (spec)
  (destructuring-bind (temperature unit) spec
    (funcall
      (ecase unit (C #'c2f) (F #'f2c))
      temperature)))

I added a DESTRUCTURING-BIND in case you don't know yet what it is.



标签: lisp