Path: ...!news.misty.com!weretis.net!feeder9.news.weretis.net!news.quux.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Kaz Kylheku <643-408-1753@kylheku.com> Newsgroups: comp.lang.lisp Subject: Re: lisp-sound v0.2.1 Date: Mon, 17 Feb 2025 16:46:53 -0000 (UTC) Organization: A noiseless patient Spider Lines: 88 Message-ID: <20250217082800.765@kylheku.com> References: <20250210103727.26@kylheku.com> <20250214082349.300@kylheku.com> <20250216165611.690@kylheku.com> Injection-Date: Mon, 17 Feb 2025 17:46:53 +0100 (CET) Injection-Info: dont-email.me; posting-host="060b6cb73c9a391b6876907c925b6664"; logging-data="1298417"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/42LqtKuGC6qt9NQ2tAtDNrvYZUwW3Kwg=" User-Agent: slrn/pre1.0.4-9 (Linux) Cancel-Lock: sha1:UTikxbK2+4ha0moYFBsMtyoaUQ8= Bytes: 4095 On 2025-02-17, zara wrote: > Every time you do make-dictionary it updates its local *dict. You do not Every trime you call make-dictionary it redefines a bunch of defuns that are contained in the function. Their bodies are lambdas, which capture the current lexical dict* variable, but the functions are global. Every make-dictionary call you have ever made now uses those new functions, which refer to the latest dict* variable and not their original one! Effectively, your code: - wipes the dictionary every time the make-dictionary constructor is called. - has all lambdas returned by make-dictionary working with the same dictionary object. This is the last post in which I'm going to explain it, or reply to this topic. >> You are not correct, therefore if you "know" you are correct, there is >> something wrong with how you determine when you know something >> and when you don't. > > See the clisp output. What CLISP output? Your only two "test cases" are commented out by a semicolon? Here is a real CLISP interaction with your code: [1]> (defun make-dictionary () (let ((*dict ())) (defun add (value) (setq *dict (append *dict (list (length *dict) value)))) (defun get-with-index (index) (let ((*index 0)) (loop for el in *dict do (if (= (car el) index) (return (cadr el)) (setq *index (+ 1 *index))) (return ())))) (defun dispatch (msg) (cond ((eq msg 'add) #'add) ((eq msg 'get-with-index) #'get-with-index) (T (print "make-dictionary : Message not understood")))) #'dispatch)) MAKE-DICTIONARY [2]> (defvar d0 (make-dictionary)) D0 [3]> (funcall (funcall d0 'add) 'apple) (0 APPLE) [4]> (funcall (funcall d0 'add) 'banana) (0 APPLE 2 BANANA) [5]> (funcall (funcall d0 'add) 'orange) (0 APPLE 2 BANANA 4 ORANGE) [6]> (defvar d1 (make-dictionary)) ;; make new dict, continue with d0 D1 [7]> (funcall (funcall d0 'add) 'peach) (0 PEACH) Oops! Do you see how dictionary d0 has suddenly developed amnesia? What happened to apple, banana and orange? Do you think that a dictionary abstration should lose its data when someone creates another instance? And if that's the design, why use all these function objects. Why allocate several new lambdas in each make-dictionary call, when there is only one dictionary? Just define a global variable: (defvar *dict* ()) ;; the one and only dict (defun dict-add (index) ...) ;; add to dictionary Maybe read some books/tutorials. (Try not to close them when you think you know something different). -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca