* Kaz Kylheku <
20250210103727.26@kylheku.com> :
Wrote on Mon, 10 Feb 2025 18:57:30 -0000 (UTC):
On 2025-02-10, zara <johan@freecol.be> wrote:
Hi,
just wanted to post the start of lisp-sound, there's a neat trick inside using
actors without CLOS, see the file dictionary.lisp for an example.
>
If you want to discuss some piece of code here, it is best to just post
it here, in-line with your article.
>
The code is here :
http://sf.net/projects/lisp-sound
>
It's not 1999; nobody downloads tarballs from sourceforge to look
at your code.
wget still works if you tack on &viasf=1 to the query part of the
download url.
in this case to master.dl.sourceforge.net/project/lisp-sound/lisp-sound-0.2.1.tar.gz
I'm currently looking at all lisp audio software, I tried checking this
out.
[to the OP]
The code doenst work, I think it tries to use flavours type dispatch and
fails on several accounts, it is not common lisp code.
1. First I added a package file
package.lisp: (defpackage "LISP-SOUND" (:use "CL"))
2. and added `(in-package "LISP-SOUND")' forms at the top of all files in
the directory.
3. I removed the naked (load "file") forms in some files
4. I wrote a defsystem
```
(mk:defsystem :lisp-sound
:source-extension "lisp"
:components ((:file "package")
(:module "base"
:components
((:file "channel")
(:file "dictionary")
(:file "fs-filter")
(:file "utilities")
(:file "16bitsample" :depends-on ("channel"))
(:file "32bit-multiple-sample" :depends-on ("dictionary"))
(:file "32bitsample" :depends-on ("channel"))
(:file "fs" :depends-on ("fs-filter"))
(:file "wavsample" :depends-on ("32bitsample"))))
(:module "mixer"
:components
((:file "mix")))
(:module "sample-enlarger"
:components
(:file "32bit-matrix"))))
To try to compile it.
Compilation fails, first for syntactic reasons. The parens are not
balanced in many files.
there are logic errors, typos, and common lisp errors.
One example: It tries to use this idiom in dictionary.lisp (after fixing
typos and paren mismatches)
```
(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 (error "make-dictionary : Message not understood ~A" msg))))
#'dispatch))
;(setq $dictionary (make-dictionary))
;(print (funcall (funcall $dictionary 'add) 255))
```
But this will flat out fail. You cannot use the a nested defun to deine
the #'add closure here because defun is global. If you try to (defun
add) again in another file it will overwrite this definition and you
will get an infinite loop.
Instead make-dictionary should use flet labels or labels to do lexical
binding correctly, say like this:
```
(defun make-dictionary ()
(let ((*dict ()))
(labels ((add (value)
(setq *dict (append *dict (list (length *dict) value))))
(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 ()))))
(dispatch (msg)
(cond ((eq msg 'add) #'add)
((eq msg 'get-with-index) #'get-with-index)
(T (error "make-dictionary: Message not understood ~A" msg)))))
#'dispatch)))
```
All the code using this pattern has to be updated. I stopped at this
point for now.
A git repo of the code (even in sf) would also be helpful in
communicating the changes back to you.