Допустим, у меня есть две переменные, и я хочу установить переменную с более низким значением в nil.Использовать условные места в setf
Возможно ли, чтобы это работало?
(setf a1 5)
(setf a2 6)
(setf
(if (< a1 a2) a1 a2)
nil
)
Допустим, у меня есть две переменные, и я хочу установить переменную с более низким значением в nil.Использовать условные места в setf
Возможно ли, чтобы это работало?
(setf a1 5)
(setf a2 6)
(setf
(if (< a1 a2) a1 a2)
nil
)
Если вы хотите сделать что-то близкое к этому, вы можете использовать (setf (symbol-value var) ...)
:
> (defparameter a1 5)
> (defparameter a2 6)
> (setf (symbol-value (if (< a1 a2) 'a1 'a2)) nil)
> a1
nil
> a2
6
Чтобы получить синтаксис ближе к одному из вашего вопроса, вы можете определить setf-expander
для if
:
(defsetf if (cond then else) (value)
`(progn (setf (symbol-value (if ,cond ,then ,else)) ,value)
,value))
Тогда вы можете написать (setf (if (< a1 a2) 'a1 'a2) nil)
Однако, лучший способ написания кода, вероятно, является сделайте это прямо вперед, используя if
с setf
формы в обеих ветвях:
(if (< a1 a2)
(setf a1 nil)
(setf a2 nil))
Нет, потому что if
форма не является место и, следовательно, не в состоянии setf
.
Хотя это не очень полезно само по себе, вы можете рассматривать это как маленький намек:
(defun new-values (x y)
(if (< x y) (values nil y) (values x nil)))
(setf a1 5)
(setf a2 6)
(setf (values a1 a2) (new-values a1 a2))
Afair, определение SETF для стандартных функций/макросов/специальных операторов не допускается спецификацией CL. – monoid
@monoid Вы частично правы. В разделе 11.1.2.1.2 говорится, что последствия определения набора расширений для символов в пакете COMMON-LISP - _undefined_. –
ОК, это не «не разрешено», это «не стоит» :) – monoid