2013-05-11 2 views

ответ

9

Если вы хотите сделать что-то близкое к этому, вы можете использовать (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)) 
+0

Afair, определение SETF для стандартных функций/макросов/специальных операторов не допускается спецификацией CL. – monoid

+2

@monoid Вы частично правы. В разделе 11.1.2.1.2 говорится, что последствия определения набора расширений для символов в пакете COMMON-LISP - _undefined_. –

+1

ОК, это не «не разрешено», это «не стоит» :) – monoid

0

Нет, потому что if форма не является место и, следовательно, не в состоянии setf.

0

Хотя это не очень полезно само по себе, вы можете рассматривать это как маленький намек:

(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)) 
Смежные вопросы