2008-12-06 10 views
7

Próbuję uruchomić kod śledzenia ray zANSI Common Lisp Paula Grahama na OS X za pomocą SLIME z OpenMCL (dobrze, teraz nazywa się CCL). W tym kodzie istnieje stała zdefiniowana, której wartość jest strukturą, a kiedy wywołuję szlam-kompiluje-i-ładuje plik lub szlam-kompilator-defun na dowolnej funkcji, która używa stałej, pojawia się błąd wiadomośćBłąd "No MAKE-LOAD-FORM" z OpenMCL Common Lisp

żadna metoda make-LOAD-forma jest zdefiniowany # s (punkt X 0 : Y 0 : z 200) [warunki typu prosty BŁĄD]

Znalazłem a post wyjaśniając komplikację i lamentować, ale co trzeba dodać do kodu, aby wynegocjować ten aspekt OpenMCL?

Odpowiedz

8

Gdy OBIEKTY STRUKTURY (i niektóre inne typy obiektów) pojawiają się jako obiekty stałe, w kodzie przetwarzanym przez PLIKI KOMPILENCYJNE, to KOMPILACJA-PLIK musi wiedzieć, jak to zorganizować, gdy zostanie załadowany wynikowy plik binarny, tworzony jest "równoważny" obiekt. Istnieje wiele możliwych definicji "równoważnych": czasami ważne jest, aby komponenty wczytanego obiektu współdzieliły strukturę z innymi obiektami, czasami ważne jest, aby inicjalizacja odbywała się w określony sposób, a czasami żadna z tych rzeczy nie jest ważna. Aby określić sposób odtworzenia stałego obiektu, funkcja COMPILE-FILE wywołuje funkcję ogólną MAKE-LOAD-FORM; to zachowanie powinno być opisane w dowolnym odwołaniu lub samouczku CL. (Referencja lub samouczek powinny również pamiętać, że implementacja nie może zdefiniować domyślnych metod MAKE-LOAD-FORM, które miałyby zastosowanie do wszystkich instancji klasy STRUCTURE-CLASS lub STANDARD-CLASS, a także zwrócić uwagę na to, że OSZCZĘDNOŚĆ FORMATU MAKE-SAMOWEGO -SLOTS to wygodna funkcja do zastosowania w metodach MAKE-load-formularz dla obiektów, których inicjalizacji nie musi być skomplikowane, np:

(defmethod make-load-form ((p point) &optional env) 
    (declare (ignore env)) 
    (make-load-form-saving-slots p)) 

Zauważ, że ta metoda musi być określony w czasie kompilacji, więc ten KOMPILOWY PLIK może go wywołać w celu ustalenia, jak zapisać stały obiekt POINT:

Żadne z nich nie jest specyficzne dla CCL. Możliwe, że chodzi o to, które rzeczy są stałe, dosłowne, a które nie.

W kodzie jak:

(defconstant a-point (make-point :x 0 :y 0 :z 200)) 

(defun return-a-point() a-point) 

kompilator pozwoliło (ale nie wymagane), aby zastąpić wartość zaznaczonym odniesienia do niej w powrotną-A-punkt. (Jeśli kompilator tak zrobi, oznaczałoby to, że w kompilowanym kodzie istnieje literalny/stały obiekt POINT, a COMPILE-FILE musiałby wywołać MAKE-LOAD-FORM, aby określić sposób zapisywania i ładowania obiektu; kompilator nie dokonuje tej zamiany, a następnie MAKE-LOAD-FORM nie musi być wywoływana w tym przykładzie.)

To, czy implementacja dokonuje tego rodzaju zamiany, zależy od implementacji. Specyfikacja nie określa również, czy formularz wartości w formularzu DEFCONSTANT jest oceniany podczas kompilacji, czasu ładowania lub obu, i zauważa, że ​​należy zachować ostrożność (przez użytkownika), aby zapewnić, że wyrażenie zawsze będzie ta sama wartość.

CCL na ogół próbuje oszacować formę wartości DEFCONSTANT podczas kompilacji i jest dość agresywny w zastępowaniu wartości nazwanych stałych odwołaniami do nich; w niektórych przypadkach oznacza to, że należy zdefiniować metody MAKE-LOAD-FORM na klasach wartości stałych.Inne implementacje mogą być mniej skłonne do dokonania tego zastąpienia dla niektórych typów obiektów. Obie strategie są poprawne, a przenośny kod nie może zakładać, które strategie są przestrzegane (chociaż dużo przenośny kod na pewno robi takie założenia).

Różne traktowanie rzeczy zdefiniowanych przez DEFCONSTANT wydaje się być najbardziej prawdopodobną przyczyną tego rodzaju rzeczy (nieoczekiwane wywołania MAKE-LOAD-FORM, których nikt nie chce zdefiniować). Można uniknąć niektórych z tych kwestii w sposób, który powinien być przenośne, wykonując:

(defconstant a-point (make-point :x 0 :y 0 :z 200)) 

(defun return-a-point() (load-time-value (symbol-value 'a-point))) 

To będzie miało podobny efekt po prostu pozwalając na realizację, która chce zrobić (jak robi CCL) zrobić stałą podstawienie , ale użycie wartości LOAD-TIME-VALUE zapewni, że stała wartość jest oceniana tylko w czasie ładowania (i że MAKE-LOAD-FORM nie będzie zaangażowany).

+0

Domyślam się, że chciałeś zadzwonić do ' RETURN-A-POINT' w twoim formularzu 'DEFCONSTANT'? –