2013-03-28 10 views
5

Jak mogę na nowo zdefiniować wbudowaną funkcję, podczas gdy zachowując odniesienie do starej funkcji pod inną nazwą?redefiniowanie wbudowanej funkcji

tj SBCL

(unlock-package 'common-lisp) 
(defun old+ (a b) ?????? 
(defun + (a b) (old+ a b)) 

jestem przenoszenie kodu do realizacji LISP, który nie ma typ danych pływaka. Tak więc chciałem przedefiniować operacje matematyczne, aby użyć stałej matematyki całkowitej.

Przypuszczam, że można rozwiązać ten problem z wyszukiwania i zamiany, jak również :)

Odpowiedz

12

Aby odpowiedzieć na konkretne pytanie:

(defconstant +old-plus+ (fdefinition '+)) 
(defun + (&rest args) (apply +old-plus+ args)) 

Zauważ, że jeśli oceniać to ponownie (na przykład poprzez przeładunek plik, w którym znajduje się ten kod), możesz mieć problem: +old-plus+ może zostać po cichu zmieniony na nowy + (może pojawić się błąd lub może pojawić się ostrzeżenie), a utracisz oryginalną definicję +.

Dlatego wydaje się, że lepszym rozwiązaniem byłoby, aby utworzyć nowy pakiet w którym wszystkie symbole są importowane z CL wyjątkiem + która jest zasłonięta, a następnie użyć tego pakietu, zamiast CL (niesprawdzone):

(rename-package "COMMON-LISP" "COMMON-LISP-ORIGINAL") 
(make-package "COMMON-LISP") 
(use-package "COMMON-LISP-ORIGINAL" "COMMON-LISP") 
(shadow "+" "COMMON-LISP") 
(do-external-symbols (s "COMMON-LISP-ORIGINAL") 
    (export (find-symbol (symbol-name s)) "COMMON-LISP")) 
(defun common-lisp::+ (&rest args) (apply #'common-lisp-original:+ args)) 

Teraz powinieneś być w stanie przetworzyć kod.

Pamiętaj, że nie powinieneś ładować powyższego kodu dwukrotnie, ponieważ "konsekwencje są niezdefiniowane", jeśli rename-package do istniejącego .

Powiązane problemy