Jump to content
Sign in to follow this  
sanchaz

[LISP] Função em Lisp ajuda a perceber

Recommended Posts

rolando2424

Isto já é antigo, mas mais vale tarde que nunca.

O problema deve ser simples de perceber se fizermos as coisas por partes.

Portanto, tendo esta função:

(defun f (&optional (n NIL))
  ((lambda (l)
     (cond ((integerp n)
             (setf l (cons n l)))
       ((null l)
         NIL)
       (t
         ((lambda (el)
            (setf l (cdr l))
            el)
           (car l)))))
    (list n)))

Ela é chamada da seguinte forma:

(funcall #'f 2) ;; isto e equivalente ao (setf g #'f) (funcall g 2) que estavas a fazer

Vamos analisar o que acontece ao código quando trocamos a variável n pelo valor 2.

(defun f (&optional (n NIL))
  ((lambda (l)
     (cond ((integerp 2)          ;; Isto vai ser sempre verdade
             (setf l (cons 2 l))) ;; por isso o programa vai executar sempre esta expressao
       ((null l)
         NIL)
       (t
         ((lambda (el)
            (setf l (cdr l))
            el)
           (car l)))))
    (list 2)))

Portanto, após se substituir os valores, vamos chamar essa função com o argumento (list 2):

(lambda (l)
  (cond ((integerp 2)                 ;; Isto vai ser sempre verdade
          (setf l (cons 2 (list 2)))) ;; por isso o programa vai executar sempre esta expressao
    ((null (list 2))
      NIL)
    (t
      ((lambda (el)
         (setf l (cdr (list 2)))
         el)
        (car (list 2))))))

Portanto a instrução que vai ser executada é:

(setf l (cons 2 (list 2)))

Como deves saber, fazer o cons com uma lista no lugar do cdr dá uma nova lista.

Ou seja, este cons vai devolver (list 2 2), que pode ser representado por '(2 2), e que vai ser colocado na variável l.

Ora como o setf devolve o valor que foi colocado na variável, ele vai devolver '(2 2).

Por sua vez o cond também devolve o valor da última expressão que executou, que foi o '(2 2) devolvido pelo setf.

Logo o lambda devolve '(2 2) que é o valor da última expressão executada (o cond).

Talvez se adicionar uns format aí para o meio seja mais fácil de perceber:

(defun f (&optional (n NIL))
           ((lambda (l)
              (format t "Antes de executar o cond, o valor de l e: ~A~%" l)
              (cond ((integerp n)
                      (setf l (cons n l)))
                ((null l)
                  NIL)
                (t
                  ((lambda (el)
                     (setf l (cdr l))
                     el)
                    (car l))))
              (format t "Depois de executar o cond, o valor de l e: ~A~%" l))
             (list n)))

E a execução:

CL-USER> (funcall #'f 2)

O valor de l e: (2)

O valor de l e: (2 2)

NIL          ; O format devolve NIL quando o primeiro argumento dele e t, por isso o lambda tambem devolve NIL

CL-USER>

Espero que tenha dado para entender.


Não me responsabilizo por qualquer dano ocorrido no seguimento dos meus conselhos. Prontos, a minha pessoa está oficialmente protegida legalmente :D

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.