0

I just stumbled across this phenomenon while trying to implement a simple function that is counting the number of letters in a list.

This is the code:

(defun countit (liste) 
  (let* ((*dict*  '((a 0)(b 0) (c 0) (d 0) (e 0) (f 0) (g 0) (h 0) (i 0) 
                    (j 0) (k 0) (l 0) (m 0) (n 0) (o 0) (p 0) (q 0)(r 0)
                    (s 0) (t 0) (u 0) (v 0) (w 0) (x 0) (y 0) (z 0))))
    (dolist (i liste *dict*)
      (incf (second (assoc i *dict*))))))

Interestingly if I run this functon several times the *dict* keeps the numbers from the last call. So running (countit '(a a)) and then again (countit '(a a)) yields (a 4) as a result which I don't quite get why because I'm defining a local environment with let for every function call, right?

Can someone explain to me why this is happening and how I can do it better without changing it too much?

sds
  • 58,617
  • 29
  • 161
  • 278
Kuroskai
  • 27
  • 1
  • 7
  • Minor note: using "earmuffs" around `dict` conveys the wrong message that this is a globally special variable. Please see [Style Guide](http://lisp-lang.org/style-guide/) and use Emacs to properly format your code. – sds Dec 11 '17 at 14:19
  • @sds funnily, in effect it *is* behaving as such. – Will Ness Dec 11 '17 at 14:21
  • Because you're using the *quoted* list in the definition, which persists inside the definition and gets reused on each new invocation. Changing it to a list created with `list` will cause it to be made anew on each invocation so no old results will be remembered. – Will Ness Dec 11 '17 at 14:24
  • @WillNess: it is not behaving globally _special_, but just _global_. – Svante Dec 11 '17 at 14:48
  • @Svante there's no chance for it to show any difference, here, isn't it. :) – Will Ness Dec 11 '17 at 14:55
  • 1
    There is. If one writes `(let ((*dict* ...)) (declare (special *dict*)) (countit ...))`, it will behave as a global rather than a special. – Dan Robertson Dec 11 '17 at 14:58
  • alright, thank you! – Kuroskai Dec 11 '17 at 21:51
  • If you do want to count the frequency of all symbols in a list (single-letter symbols, really), you could just do something like this: https://gist.github.com/agam/03e01aa5a307fc5548e590de0f3661cc – agam Dec 12 '17 at 07:35

0 Answers0