(let*

Hello.
Please read this code.

(Defun  do-that-clap (step)
  (let*
    ((envelope (exp-dec 0.005 0.007 0.1))
    (clap (force-srate 44100 (scale-srate (mult  envelope (noise)) (/ step 150.0)))))
      (pan (mult 0.5 clap) (real-random 0.1 0.9))))

(set-sound-srate *sound-srate*)
(setf s (abs-env (simrep (num 12) (stretch (/ (power 2 (random 2))   12.0)   
  (at  num  (do-that-clap (real-random 5.0 25.0))))) ))
(setf l (aref s 0))
(setf r (aref s 1))
(seqrep (measure 10) (vector l r))

I have a question to ask. it concerns the function (let*.
The textbook indicates: (let* (binding…) expr…) [LISP]
My question is the following one: in this code, the “binding” is this code?

 ((envelope (exp-dec 0.005 0.007 0.1))

The “expression” is this code?

 (clap (force-srate 44100 (scale-srate (mult  envelope (noise)) (/ step 150.0)) ))

Thank you for this precision.

If we format the code a little better, it becomes clearer:

(Defun  do-that-clap (step)
  (let* ((envelope (exp-dec 0.005 0.007 0.1))
         (clap (force-srate 44100 (scale-srate (mult  envelope (noise)) (/ step 150.0)))))
    (pan (mult 0.5 clap) (real-random 0.1 0.9))))

We can now see that there are two bindings:
The code says;
let envelope = (exp-dec 0.005 0.007 0.1)”
and
let clap = (force-srate 44100 (scale-srate (mult envelope (noise)) (/ step 150.0)))”

The asterisk after “let” says that the bindings must be made in sequential order. This is important in this case - we must assign a value to “envelope” first because we then use “envelope” in the second binding.

The body code has one expression:

(pan (mult 0.5 clap) (real-random 0.1 0.9))

Thank you.
The textbook Lisp indicates: (let* (binding…) expr…) [LISP] The variable bindings each of which is either: 1) a symbol 2) a list whose car is a symbol and whose cadr is an initialization expression

If
_ " envelope " and “clap” are lists
_ The list of the binding " envelope " is

(exp-dec 0.005 0.007 0.1)

_ the list of the binding “clap” is

 (force-srate 44100 (scale-srate (mult  envelope (noise)) (/ step 150.0)))

_ “…The ‘car’ function returns the first element of the expression (XLISP)”
Then

 (car envelope) ; returns exp-dec

and

(car clap) ; returns force-srate 44100

Is it right?

On the other hand, I do not understand ‘cadr’.
_“… “cadr” function returns - the result of the last car function (XLISP)”
I does not understand the given example. The example indicates that the list is a list at 2 levels.

Beforehand thank you for your help.

They’re not lists they are symbols.

Hello.
Please read this code (Convert ASCII string of 1’s and 0’s to polyphonic sound - forum Windows):

(setq data1 (list 0 0 1 1 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 0))
(setq intvl 5)
(setq root 60)

(abs-env
 (simrep (i 4)
  (let*
   ((vol        (* 8 (nth (+ 1 (* i 5)) data1)))
    (vol (+ vol (* 4 (nth (+ 2 (* i 5)) data1))))
    (vol (+ vol (* 2 (nth (+ 3 (* i 5)) data1))))
    (vol (/ (+ vol   (nth (+ 4 (* i 5)) data1)) 48.0)))
     (mult vol (osc (+ root (* intvl (nth (* i 5) data1))))))))

This function let* seems to me to have several bindings.
vol = (* 8 (nth (+ 1 (* i 5)) data1))
vol= (+ vol (* 4 (nth (+ 2 (* i 5)) data1)))
vol = (+ vol (* 2 (nth (+ 3 (* i 5)) data1)))
and vol = (/ (+ vol ( nth (+ 4 (* i 5)) data1 )) 48.0)

My question is the following one: is there 4 bindings who are called all “vol”?
Either. Is there one binding (“vol”) which has 4 differents values?

Thank you for your answer.

As I mentioned previously, LET* sets each of the binding in sequential order.

“vol” is the same symbol in each line.

The first binding sets “vol” to (* 8 (nth (+ 1 (* i 5)) data1))
the next line adds (* 4 (nth (+ 2 (* i 5)) data1))
the next line adds (* 2 (nth (+ 3 (* i 5)) data1))
and the final line adds (nth (+ 4 (* i 5)) data1) and then divides the answer by 48.0.

Another way to write the same thing would be:

(abs-env
  (simrep (i 4)
    (let ((vol (/ (+ (* 8 (nth (+ 1 (* i 5)) data1))
                     (* 4 (nth (+ 2 (* i 5)) data1))
                     (* 2 (nth (+ 3 (* i 5)) data1))
                     (nth (+ 4 (* i 5)) data1))
                  48.0)))
      (mult vol (osc (+ root (* intvl (nth (* i 5) data1))))))))

Thank you.
I try to understand “nth”.
(nth expr list-expr) [XLISP]
The first binding is = (* 8 (nth (+ 1 (* i 5)) data1))
expr = (+ 1 (* i 5))
list-expr = data1
It is right?

(+ 1 (*i 5)) = 1 + (i x 5)
It seems to me that “i” = 4 [(simrep (i 4)]
We could thus write:
expr = 1 + 4 x 5 = 21
It is right?

There is a problem. “list-expr” (data1) is a list which has only 20 terms .The function (nth) cannot returns a value of the list.
There is thus a problem in my calculations.
Do you see it?

Beforehand thank you for this piece of information.

Does this help? XLISP nth

In the code

(simrep (i 4) ....

“i” takes the values, 0, 1, 2, 3
See: Nyquist Functions