I am new to Common Lisp, especially CLOS. I am using the REPL inside a package called Nyxt.
Nyxt is designed to be an infinitely extensible browser. Hence, the user can change the code and/or create extensions while the program is running. This is live hackability by design. My question is unrelated to the Nyxt package, but since it happened inside the package I thought it would be be better to provide more background info.
I do not understand the behavior of the function find
in this concrete case.
I have this small list of instances representing URLs:
NYXT> small-list
(#<QURI.URI.HTTP:URI-HTTPS https://duckduckgo.com/?q=google+analytics&ia=web>
#<QURI.URI.HTTP:URI-HTTPS https://duckduckgo.com/l/?uddg=https%3A%2F%2Fanalytics.withgoogle.com%2F¬rut=duckduck_in>
#<QURI.URI.HTTP:URI-HTTPS https://en.wikipedia.org/wiki/CAPTCHA>
#<QURI.URI:URI about:blank> #<QURI.URI.HTTP:URI-HTTPS https://ambrevar.xyz/>)
Then, I define as a variable the third element of the list:
NYXT> (defparameter wikipedia-page (third small-list))
WIKIPEDIA-PAGE
NYXT> wikipedia-page
#<QURI.URI.HTTP:URI-HTTPS https://en.wikipedia.org/wiki/CAPTCHA>
Ok, it works as expected if I try to find the wikipedia-page inside the list:
NYXT> (find wikipedia-page small-list :test #'equal)
#<QURI.URI.HTTP:URI-HTTPS https://en.wikipedia.org/wiki/CAPTCHA>
Now, let me bound another instance to a variable:
NYXT> (defparameter blog (last small-list))
BLOG
NYXT> blog
(#<QURI.URI.HTTP:URI-HTTPS https://ambrevar.xyz/>)
The problem is when I try to find it:
NYXT> (find blog small-list :test #'equal)
NIL
Now is the strangest part ever for me, the equality test works:
NYXT> (equal blog (last small-list))
T
Could anyone help me? Why find does not work for the blog
case? Is this related to CLOS and how objects should be compared?
Thanks
Given small-list
as defined in the question, (last small-list)
is the list (#<QURI.URI.HTTP:URI-HTTPS https://ambrevar.xyz/>)
. So, of course (find (last small-list) small-list)
should be expected to return nil
, since small-list
does not contain the element (#<QURI.URI.HTTP:URI-HTTPS https://ambrevar.xyz/>)
(which is a list); rather small-list
contains the element #<QURI.URI.HTTP:URI-HTTPS https://ambrevar.xyz/>.
Remember that last
returns the last cons of a list (or the last n
conses if you provide the optional argument). You could do: (find (car (last small-list)) small-list)
.
Another possibility would be to use the test
and key
keyword arguments: (find (last small-list) small-list :test #'equal :key #'list)
. But, I'm not sure when I would prefer this to the first solution.