| Deutsch English Français Italiano |
|
<m2ldu5vhbp.fsf_-_@freecol.be> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!feeds.phibee-telecom.net!3.eu.feeder.erje.net!feeder.erje.net!usenet.goja.nl.eu.org!dotsrc.org!filter.dotsrc.org!news.dotsrc.org!not-for-mail From: zara <johan@freecol.be> Newsgroups: comp.lang.lisp Subject: Actor object System in LISP without CLOS (dictionary example) - was Re: lisp-sound v0.2.1 References: <m2h652z7r6.fsf@freecol.be> <20250210103727.26@kylheku.com> <m25xlcbpf0.fsf@freecol.be> <20250214082349.300@kylheku.com> <m2tt8wv3gm.fsf@freecol.be> <m3zfimwwad.fsf@leonis4.robolove.meer.net> <m2pljiv7p9.fsf@freecol.be> <87ldu596hy.fsf@gmail.com> Date: Sun, 16 Feb 2025 20:07:54 +0100 Message-ID: <m2ldu5vhbp.fsf_-_@freecol.be> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3.50 (darwin) Cancel-Lock: sha1:mNpms4D1eJAZSXs9TNeDo9rU6j8= MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Lines: 160 Organization: SunSITE.dk - Supporting Open source NNTP-Posting-Host: 29143bec.news.sunsite.dk X-Trace: 1739732875 news.sunsite.dk 713 automn.willow@gmail.com/109.137.154.133:53668 X-Complaints-To: staff@sunsite.dk Bytes: 6610 Hi, tpeplt <tpeplt@gmail.com> writes: > zara <johan@freecol.be> writes: > >> >>> * zara <m2tt8wv3gm.fsf@freecol.be> : >>> Wrote on Fri, 14 Feb 2025 18:30:33 +0100: >>> >>>> >>>> You didn't run it, but it does not just compile in clisp (2019), >>>> it works. SFY. >>> >>> No it is still wrong and it will also fail with Clisp (if clisp does >>> ansi). it'll fail if you load another file with the same functionn >>> names. >> >> I ran clisp on NetBSD 10.0 and changed "add" to 'add (See the >> dictionary.lisp file below and run it if you please) : >> > > Some points to consider: > > 1. ‘add’ returns the entire dictionary every time an entry is added. > If you anticipate that the dictionary could become large, then this > could become an awkward return value. Consider having ‘add’ return only > the latest entry to the dictionary: > > (add (value) > (let ((entry (list (length *dict) value))) > (setq *dict (append *dict entry)) > entry)) > Yes, good point. Stack smashing is definitely a bad idea. > 2. If this change is made, then you might want to add a function to > ‘dispatch’ that displays the contents of ‘*dict’ if some other code is > not behaving as you expect. So, > > (show () > *dict) > > Of course, later you could modify this, if wanted, to have, say, a loop > that displays formatted entries or arguments to ‘show’ that specify the > number of entries to display or the start and end of a range that you > want, and so on. > > With this change, you will need to add an entry for ‘show’ to > ‘dispatch’. > This is an opttion. > 3. The following expression shows two problems: > > (print (funcall (funcall dictionary 'add) 255)) > > a. the (print ()) is not needed since the ‘add’ function will return > a value, which is then redundantly printed. > > (funcall (funcall dictionary 'add) 255) > > b. This shows that ‘dispatch’ is expected to return a function > object, which it does for ‘add’ and ‘get-with-index’ messages. > But for any other (invalid) message, it does not return a function > object, which causes the outer (funcall <what ‘dispatch’ returns>) > to trigger the debugger with a message unrelated to your message: > > "make-dictionary: Message not understood" > > You can fix this by two routes: > > i. Use Lisp’s ‘error’ function, as suggested by previous posts. > This will still trigger the debugger, but your error message > will be displayed rather than a message by invalid argument > to ‘funcall’. > > ii. Write another function, say ‘mistake’, that ‘dispatch’ can > return and the outer ‘funcall’ can call > > (mistake (arg) > (format nil "dispatch: Message not understood: ~S" arg)) > > Then a typo in an expression > > (funcall (funcall dictionary 'ade) 255) > > will return the message in ‘mistake’. > This is a generic function add-on. > 4. Does your dictionary only grow or do anticipate that some entries > might be removed, that is, do you want to add a ‘del’ function that > corresponds to your ‘add’ function? This will need to search the > dictionary for an entry, and splice together two lists, the list before > the entry and the list after it. > > As Kaz Kylheku suggested earlier, Lisp provides the hash table type > with numerous operations defined. See the following URL in the > Common Lisp Hyperspec: > > https://www.lispworks.com/documentation/HyperSpec/Body/18_.htm > OK. > 5. If you still decide not to use a hash table, here is another version > of ‘get-with-index’ that eliminates list indexing and use’s the > ‘loop’ macro’s destructuring: > > (get-with-index (index) > (loop > for (key val) on *dict by #'cddr > when (= key index) > return val)) > > Here is a version of ‘make-dictionary’ that makes some of the changes, > above, including the recommendation to use ‘labels’ instead of multiple > ‘defuns’. > > (defun make-dictionary () > "Create a ‘dispatch’ function that can manipulate its dictionary." > (let ((*dict ())) > (labels ((add (value) > (let ((entry (list (length *dict) value))) > (setq *dict (append *dict entry)) > entry)) > > (show () > *dict) > > (get-with-index (index) > (loop > for (key val) on *dict by #'cddr > when (= key index) > return val)) > > (dispatch (msg) > (case msg > (add #'add) > (get-with-index #'get-with-index) > (show #'show) > (T (error > "dispatch: Message not understood: ~S" msg))))) > #'dispatch))) You might also want to multiply the index parameter with 2. Just encore wanted to say that you now have an actor object, which was the meaning of the dictionary example and can use it without CLOS. Thanks for the clues. zara -- My software & art company : http://ko-fi.com/brandywine9