]> git.leonardobizzoni.com Git - ObjectOriented-Prolog-Lisp/commitdiff
Documentazione creazione dei metodi
authorLeonardoBizzoni <leo2002714@gmail.com>
Wed, 10 Jan 2024 14:38:11 +0000 (15:38 +0100)
committerLeonardoBizzoni <leo2002714@gmail.com>
Wed, 10 Jan 2024 14:38:11 +0000 (15:38 +0100)
Lisp/README.org
Lisp/ool.lisp

index 6fd05ab3c37441a805a2168389e007f8547973c9..50f8ccd6ddc1baa62366ce55fe60907ebb2157d8 100644 (file)
@@ -280,7 +280,27 @@ di 2 classi, il che tornerà utile nel controllo dei tipi.
 #+end_src
 
 *** Creazione di metodi
-
+Predicato utilizzato per define i metodi di una classe.
+La definizione di un metodo viene effettuata tramite la creazione di una
+funzione "metodo" il cui nome corrisponde al nome del metodo da creare,
+prende degli argomenti in ingresso capitanati dall'istanza su cui chiamare
+il metodo.
+Nel corpo di questa funzione inizialmente vengono svolti dei controlli
+per verificare che il primo argomento sia effettivamente un'istanza di una
+classe che implementi il metodo chiamato e successivamente viene chiamto
+il vero corpo del metodo (/definito precedentemente/).
+
+Il problema principale da superare è il fatto che più classi possono
+implementare un metodo con lo stesso nome e con argomenti diversi.
+Per risolvere questo problema permettiamo alla funzione "metodo" di
+ricevere un numero variabile di argomenti tramite la keyword /&rest/.
+Recuperiamo il corpo del metodo da eseguire dall'istanza /this,/ creiamo
+ed eseguiamo a runtime una lambda con argomenti l'istanza e gli argomenti
+definiti all'interno del metodo nella lista rappresentante l'istanza ed il
+corpo della lambda è il corpo del metodo da eseguire.
+
+In questo modo possiamo ricevere un numero variabile di argomenti ed
+eseguire codice in base all'istanza che viene data alla funzione.
 
 #+begin_src lisp :tangle ool.lisp
 (defun define-methods (methods)
@@ -297,7 +317,7 @@ di 2 classi, il che tornerà utile nel controllo dei tipi.
             (unless (get-method (getf this :methods) (first method))
               (error "~A non ha un metodo ~A"
                      (getf this :classname) (first method)))
-            (apply (get-method-body this (first method))
+            (apply (build-method-body this (first method))
                    (append (list this) args)))))
    methods))
 
@@ -307,7 +327,7 @@ di 2 classi, il che tornerà utile nel controllo dei tipi.
        ((eq (caar methods) name) (car methods))
         (t (get-method (cdr methods) name))))
 
-(defun get-method-body (this method-name)
+(defun build-method-body (this method-name)
   (eval
    (append
     (list 'lambda
index 381de6f52847a83d34fc3ce35672ce29cbe9b8e7..45377ca67257902326d0a2bbbfdbb8e58506134f 100644 (file)
        ((eq (caar fields) field-name) (cadar fields))
        (t (field-helper (cdr fields) field-name))))
 
+(defun field* (instance &rest fields)
+  (if (null fields)
+      (error "La lista di fields non può essere vuota")
+      (field*-helper instance fields)))
+
+(defun field*-helper (instance fields)
+  (if (null (cdr fields))
+      (field instance (car fields))
+      (field*-helper (field instance (car fields)) (cdr fields))))
+
 (defparameter *classes-specs* (make-hash-table))
 
 (defun add-class-spec (name class-spec)
             (unless (get-method (getf this :methods) (first method))
               (error "~A non ha un metodo ~A"
                      (getf this :classname) (first method)))
-            (apply (get-method-body this (first method))
+            (apply (build-method-body this (first method))
                    (append (list this) args)))))
    methods))
 
        ((eq (caar methods) name) (car methods))
         (t (get-method (cdr methods) name))))
 
-(defun get-method-body (this method-name)
+(defun build-method-body (this method-name)
   (eval
    (append
     (list 'lambda