& # 8220; Aucun formulaire MAKE-LOAD-FORM & # 8221; erreur avec OpenMCL Common Lisp

StackOverflow https://stackoverflow.com/questions/346695

  •  19-08-2019
  •  | 
  •  

Question

J'essaie d'exécuter le code de traçage de rayons ANSI Common Lisp de Paul Graham sous OS X avec SLIME avec OpenMCL (à présent, appelé CCL). Dans ce code, il est défini une constante dont la valeur est une structure, et lorsque j'appelle slime-compiler-et-charger-fichier ou slime-compiler-defun sur tout fonction qui utilise la constante, je reçois un message d'erreur:

  

Aucune méthode MAKE-LOAD-FORM n'est définie   pour #S (POINT: X 0                                                    : Y 0                                                    : Z 200) [Condition de type   SIMPLE-ERROR]

J'ai trouvé une publication expliquant la complication. et un autre le lamentant, mais quoi faut-il ajouter au code pour négocier cet aspect d'OpenMCL?

Était-ce utile?

La solution

Lorsque STRUCTURE-OBJECT (et certains autres types d’objets) apparaissent sous forme littérale, les objets constants dans le code en cours de traitement par COMPILE-FILE doivent indiquer comment faire en sorte que, lorsque le fichier binaire résultant est chargé, une " équivalent " l'objet est créé. Il existe de nombreuses définitions possibles de " équivalent " : parfois, il est important que les composants de l'objet chargé partagent la structure avec d'autres objets, parfois il est important que l'initialisation se produise d'une certaine manière, et parfois aucune de ces choses n'est importante. Pour déterminer comment recréer l'objet constant, COMPILE-FILE appelle la fonction générique MAKE-LOAD-FORM; Ce comportement doit être décrit dans toute référence ou tutoriel CL. (Une référence ou un didacticiel doit également indiquer que l’implémentation ne peut pas définir les méthodes MAKE-LOAD-FORM par défaut qui s’appliqueraient à toutes les instances de STRUCTURE-CLASS ou STANDARD-CLASS, et devrait également noter que MAKE-LOAD-FORM-SAVING -SLOTS est une fonction pratique à utiliser dans les méthodes MAKE-LOAD-FORM pour les objets dont l'initialisation n'a pas besoin d'être compliquée, par exemple:

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

Notez que cette méthode doit être définie au moment de la compilation pour que COMPILE-FILE puisse l'appeler afin de déterminer comment enregistrer l'objet POINT constant.

Rien de tout cela n'est spécifique à CCL. Ce qui pourrait être est la question de savoir quelles choses sont des objets constants et littéraux et quelles choses ne le sont pas.

Dans un code comme:

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

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

le compilateur est autorisé (mais non obligatoire) à substituer la valeur de A-POINT à la référence dans la fonction RETURN-A-POINT. (Si le compilateur le fait, ce serait signifie qu'il y a un objet POINT littéral / constant dans le code en cours de compilation, et que COMPILE-FILE doit appeler MAKE-LOAD-FORM pour déterminer comment l'objet doit être enregistré et chargé; si le compilateur ne fait pas cette substitution, il n'est pas nécessaire d'appeler MAKE-LOAD-FORM dans cet exemple.)

Qu'une implémentation fasse ou non ce type de substitution dépend de l'implémentation. La spécification ne spécifie pas non plus si la forme de la valeur dans une forme DEFCONSTANT est évaluée au moment de la compilation, au moment du chargement, ou les deux, et note que l'utilisateur doit faire attention (par l'utilisateur) pour s'assurer que l'expression est toujours évaluée la même valeur.

CCL essaie généralement d’évaluer la forme de valeur DEFCONSTANT au moment de la compilation et opte plutôt pour la substitution des valeurs des constantes nommées. dans certains cas, cela signifie que les méthodes MAKE-LOAD-FORM sur les classes des valeurs des constantes doivent être définies. D'autres implémentations peuvent être moins disposées à faire cette substitution pour certains types d'objets. Les deux stratégies sont correctes et le code portable ne peut pas supposer quelles stratégies sont suivies (bien que beaucoup de code soi-disant supposé suppose de telles hypothèses.)

Un traitement différent des éléments définis par DEFCONSTANT semble être la cause la plus probable de ce type d’appel (appels inattendus à MAKE-LOAD-FORM que personne n’a pris la peine de définir). Vous pouvez éviter certains de ces problèmes d’une manière qui devrait être portable en procédant comme suit:

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

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

Cela aura un effet similaire à celui d'autoriser simplement une implémentation qui le souhaite (comme le fait le CCL) à effectuer une substitution constante, mais l'utilisation de LOAD-TIME-VALUE garantira que la valeur constante n'est évaluée qu'à la charge. temps (et que MAKE-LOAD-FORM ne sera pas impliqué.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top