loop through multiple variables

Quite often we want to do the same thing to many variables.
An easy way to do this in Nyquist is to put the variables into a list,
for example if we have a lot of slider inputs such as this:

;control in0 "Control 1 " real "" 0 0 100
;control in1 "Control 2 " real "" 0 0 100
;control in2 "Control 3 " real "" 0 0 100
;control in3 "Control 4 " real "" 0 0 100
;control in4 "Control 5 " real "" 0 0 100
;control in5 "Control 6 " real "" 0 0 100
;control in6 "Control 7 " real "" 0 0 100
;control in7 "Control 8 " real "" 0 0 100
;control in8 "Control 9 " real "" 0 0 100
;control in9 "Control 10 " real "" 0 0 100

we can put the variables into a list like this:

(setf inlist (in0 in1 in2 in3 in4 in5 in6 in7 in8 in9)

The function can then be applied to each variable in turn using mapc
For example, with a function called “process”

(mapc 'process inlist)

An example of how this could be put together, this outputs to the debug window the control inputs as a %.

;control in0 "Control 1 " real "" 0 0 100
;control in1 "Control 2 " real "" 0 0 100
;control in2 "Control 3 " real "" 0 0 100
;control in3 "Control 4 " real "" 0 0 100
;control in4 "Control 5 " real "" 0 0 100
;control in5 "Control 6 " real "" 0 0 100
;control in6 "Control 7 " real "" 0 0 100
;control in7 "Control 8 " real "" 0 0 100
;control in8 "Control 9 " real "" 0 0 100
;control in9 "Control 10 " real "" 0 0 100

;; Function that does processing...
(defun process (var)
   (print (* var 0.01)))

(setf inlist (in0 in1 in2 in3 in4 in5 in6 in7 in8 in9))

(mapc 'process inlist)

But what if we have a much larger number of variables? It becomes rather cumbersome to write out
(setf inlist (in0 in1 in2 … in99)

It’s very easy to create the sequence of names as stings, simply by reading a number into the variable name prefix with the format function and putting this into a loop structure:

(setf inlist (list))
(dotimes (count 100)
   (setf inlist
      (cons (format nil "in~a" count) inlist)))
(print (reverse inlist))

However, this only produces a list of strings, not a list of variables (and a ‘string’ is just a fixed value, not a variable)
What we really want is to get a list of the values in each of the variables.

We can do this by “reading” each of the strings (using the read function). However, the ‘read’ function reads ‘input streams’ rather than reading ‘strings’, so we need to use the function make-string-input-stream to create a stream from our strings.

(read (make-string-input-stream string))

So putting that together with our format function:

(setq var (read (make-string-input-stream (format nil "in~a" count))))

as we only need this temporarily it is probably better to assign it within a Let block

(let
      ((var (read (make-string-input-stream (format nil "in~a" count)))))
)

We can now evaluate each of these using eval which will give the value of each of the named variables:

(dotimes (count 10)
   (let
      ((var (read (make-string-input-stream (format nil "in~a" count)))))
      (setf inlist (cons (eval var) inlist))))

Not forgetting that we need to initialise the list before adding new values to it,
and also that our list will be in reverse order, so it needs to be reversed back,
we end up with our (slightly silly) example:

;control in0 "Control 1 " real "" 0 0 100
;control in1 "Control 2 " real "" 0 0 100
;control in2 "Control 3 " real "" 0 0 100
;control in3 "Control 4 " real "" 0 0 100
;control in4 "Control 5 " real "" 0 0 100
;control in5 "Control 6 " real "" 0 0 100
;control in6 "Control 7 " real "" 0 0 100
;control in7 "Control 8 " real "" 0 0 100
;control in8 "Control 9 " real "" 0 0 100
;control in9 "Control 10 " real "" 0 0 100

;; Function that does processing
(defun process (var)
   (print (* var 0.01)))



(setf inlist (list)) ; initialise empty list

;; Loop through variable names and add values to the list
(dotimes (count 10)
   (let
      ((var (read (make-string-input-stream (format nil "in~a" count)))))
      (setf inlist (cons (eval var) inlist))))

(setq inlist (reverse inlist))
(mapc 'process inlist)