# (let*

Hello.

``````(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?

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