/ / La forma más elegante / eficiente de definir funciones utilizando las mismas variables: función, common-lisp, redundancia, palabra clave-argumento

La forma más elegante / eficiente de definir funciones utilizando las mismas variables: función, common-lisp, redundancy, keyword-argument

Definí múltiples funciones usando algunas variables, que normalmente se calcularían en más de ellas. Así que uso palabras clave-argumentos, que calculan los valores necesarios de forma predeterminada.

Ejemplo:

(defun f (a b &key (distance (distance a b))) (c a b distance))
(defun g (a b &key (distance (distance a b))) (if (< distance (r a b))
(f a b :distance distance)))
(defun h (a b &key (distance (distance a b))) (d a b distance))
(defun i (a b &key (distance (distance a b))) (g a b :distance distance)
(h a b :distance distance))

Cada función debe poder llamarse sola sin especificar los argumentos de palabra clave.

Pero ahora también tengo que definir el cálculo de los argumentos de palabras clave en cada función.

¿Hay una manera más elegante / eficiente de hacer cosas como esta? (Pensé en la evaluación perezosa y la programación dinámica)

Respuestas

2 para la respuesta № 1

Podrías usar #=:

(defun foo (a b &key #1=(distance (distance a b))) #|...|#)

(defun bar (a b &key #1#) #|... |#)

0 para la respuesta № 2

Probablemente me hubiera caído en una macro.

 (defmacro def-distance-fun (name &body body)
`(defun ,name (a b &key (distance (distance a b))) ,@body))

(def-distance-fun foo
… blah )

Si los nombres de "a" y "b" son variables, puedeobtener un poco más sofisticado con el suministro de las variables "símbolos a la macro, y la macro podría fácilmente basta con incluir enlaces solo a los argumentos de palabras clave que ha nombrado; p.ej.

  (when (member "distance lambda-list)
`(distance (distance ,(first lambda-list) ,(second lambda-list))))