Typesafe and argument safe division in common lisp

2019-08-10 07:14发布

问题:

Long story short I need to defun ts_div and allow it to be a typesafe and "argument safe" version of the regular /

Basically, I want it to accept a list with any number of numbers in it (even none), and be able to call it like this:

(ts_div (123 321 23))

or:

(ts_div somelist)

Desired result: if there are more than two items in the list, the first will be divided by the second, and the rest is ignored. If the second number is 0, it should return the value of the first number instead. If the list is empty, it should return 0.

Any suggestions on how to achieve this?

Sidenote: I did some testing trying to make the addition-variant of it. Basically, sum up whatever numbers are passed to it in a list context, but as expected it complains about the first item in the list not being a function, and I've been unable to figure out how this is mitigated.

回答1:

Hm. Something along the lines of

(defun ts-div (list)
   (check-type list list)
   (destructuring-bind (&optional (first 0 got-first) (second 0 got-second) &rest ignored) list
       (declare (ignore ignored))
       (if got-second 
           (if (zerop second) first (/ first second)) 
           (if got-first first 0))))

might work, I think.

CL-USER> (ts-div '())
0
CL-USER> (ts-div '(1))
1
CL-USER> (ts-div '(1 0))
1
CL-USER> (ts-div '(1 2))
1/2
CL-USER> (ts-div '(1 2 123))
1/2