setq and assoc problem

Discussion of Common Lisp
Post Reply
phdenis40
Posts: 15
Joined: Sun Mar 06, 2016 5:00 pm

setq and assoc problem

Post by phdenis40 » Wed May 11, 2016 10:46 am

Hello all,

As newbie in Lisp, I'm faced off at an issue linked to the assoc function.
Hereafter, the 2 parts of code involved in my issue:

Code: Select all

 (setq values '((x . 100) (y . 200) (z . 50)))
 (assoc 'y values)
This code is working without any problem (the code is an example extracted from the assoc http://www.lispworks.com/documentation/ ... .htm#assoc)

Code: Select all

 (setq FrAng '(((poisson) fish) ((chat) cat) ((chien) dog)))
 (assoc 'chat FrAng)
But this code is not working and I don't know why, I'm expected to have the 'cat' answer.
Could you please tell me where is located my mistake or give me a clue in order to fix it?
Is the keyword case-sensitivity like CHAT different to chat?
What is the difference between these 2 types of declaration?

By advance, thanks for your help. I assume my problem is obvious for people who know lisp and I'm sorry to bother lisp expert. :?

David Mullen
Posts: 78
Joined: Mon Dec 01, 2014 12:29 pm
Contact:

Re: setq and assoc problem

Post by David Mullen » Wed May 11, 2016 1:39 pm

The two lists are structurally different. The keys, in the latter example, are themselves lists. So you'd need to use a different test function in order to compare the keys effectively:

Code: Select all

(assoc '(chat) FrAng :test 'equal)

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: setq and assoc problem

Post by pjstirling » Wed May 11, 2016 3:03 pm

First some philosophical points:
  • I always use hash-tables instead of ASSOC for this kind of mapping, technically ASSOC can be faster performing for small tables, but for larger tables GETHASH is faster, and if your program is being held back by the performance of this kind of mapping there are other ways to solve it.
  • I consider using SETQ at toplevel to create "global" variables evil (as compared to using DEFVAR or DEFPARAMETER), and I'm not alone, sbcl will complain if you do it.
  • By default (for historical reasons that made sense in the days before colour monitors, yes, it's that old!) the reader upcases all symbols before interning them, which means that the names frang frAng and FRANG will all refer to the same symbol, which would mean that if you THOUGHT you had a separate variable using one of the other spellings then you just clobbered it with that SETQ.
I would have written your code like so:

Code: Select all

(setq fr-ang '((poisson . fish) (chat .  cat) (chien . dog)))                                 
(assoc 'chat fr-ang)
  1. (The reason your code didn't work) Your literal was badly formed for ASSOC: you had an extra set of parens around the form, and you had extras around each of the items you wished to lookup. Some people call lisp Lots of Irritating Silly Parentheses, but the numbers ALWAYS matter, you can't use too many or too few.
  2. I changed the literal to use dotted-pairs (which lets you use CDR instead of SECOND to get the associated value out of the result of ASSOC, and uses less memory)

sylwester
Posts: 133
Joined: Mon Jul 11, 2011 2:53 pm

Re: setq and assoc problem

Post by sylwester » Fri May 13, 2016 1:54 am

pjstirling wrote:...
I consider using SETQ at toplevel to create "global" variables evil (as compared to using DEFVAR or DEFPARAMETER), and I'm not alone, sbcl will complain if you do it.
...
Many implementations won't complain before you actually try to compile it. The implementations are free to choose how it should be treated but most will interpret it as if it was declared special. That means `setq` and `defparameter` are interchangable in those implementations except for the warnings.

Code: Select all

(setq name-without-earmuffs 0)
(defun increase (&optional (step 1))
  (setq name-without-earmuffs (+ step name-without-earmuffs)))
I save this as test.cl. Now lets see what happens in CLISP:

Code: Select all

(load "test.cl") ; no errors
(increase) ; 1

(compile 'increase) ; lots of warnings
; WARNING: in INCREASE : NAME-WITHOUT-EARMUFFS is neither declared nor bound,
;          it will be treated as if it were declared SPECIAL.

(compile-file "test.cl") ; lots of warnings
;; Compiling file test.cl ...
;WARNING: in #:|1 1 (SETQ NAME-WITHOUT-EARMUFFS 10)-1| in line 1 : NAME-WITHOUT-EARMUFFS is neither declared nor bound,
;         it will be treated as if it were declared SPECIAL.
;WARNING: in INCREASE in lines 2..3 : NAME-WITHOUT-EARMUFFS is neither declared nor bound,
;         it will be treated as if it were declared SPECIAL.
;WARNING: in INCREASE in lines 2..3 : NAME-WITHOUT-EARMUFFS is neither declared nor bound,
;         it will be treated as if it were declared SPECIAL.
;; Wrote file test.fas
;The following special variables were not defined:
; NAME-WITHOUT-EARMUFFS
;0 errors, 3 warnings
Just adding one line to the top of the file and perhaps adhering to the naming convention and you don't get these:

Code: Select all

;; the two lines below can be replaced with one defparameter
(declaim (special *name-with-earmuffs*))
(setq *name-with-earmuffs* 0)

(defun increase (&optional (step 1))
  (setq *name-with-earmuffs* (+ step *name-with-earmuffs*)))
Now, since it's special it's obvious you know they're not lexical and thus the warnings don't show up.
However in my example where we are counting number of applications it might be better to use defvar since consecutive loading don't reset the value.
I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p

phdenis40
Posts: 15
Joined: Sun Mar 06, 2016 5:00 pm

Re: setq and assoc problem

Post by phdenis40 » Sat May 14, 2016 10:53 am

Hello all,
Thanks for your help.
One thing which is very disturbing for me it that compare to C language, a function is not typed like void main(int argc, char* argv[]).
Thus, how do you understand a program which is only written without comment.
How do you debug it?
For the debugging part, I'm calling each routine with some data and check if its behavior is the one expected.

Thanks for your help one more time.

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: setq and assoc problem

Post by pjstirling » Sat May 14, 2016 2:53 pm

Generally if I expect a function to have problems with parameters with the wrong types I include some `(UNLESS (TYPEP param expected-type) (ERROR useful-error-message))` Between that, proper function and parameter naming, and if-all-else-fails docstrings it tends not to be a problem, and it's a much better experience programming than C++ where (even with auto) you must specify types redundantly.

Post Reply