Newer
Older
til / common_lisp / named_list_let_over_lambda_functions.html

<h4>Named Functions From A List of Let Over Lambda Functions</h4>
<p><b>Sunday, Nov 18, 2023</b></p>

<p>
  <u>Let Over Lambda</u> presents a LoL that returns a list of lambda functions
  for a counter variable.  Somewhere around pg 32, maybe.
</p>

<pre>
(let ((counter 0))
  (values
     (lamda () (incf counter))
     (lamda () (decf counter))))
</pre>

<p>
That got me wondering how to access the values returned.  I first
tried <code>(setf a ( ... ))</code> but it only gave me the first
value, <pre>(incf counter)</pre>
</p>

<p>
  I tried <code>multiple-bind-values</code> but read that the variables assigned
  the functions were only accessible within the  <code>multiple-bind-values</code>
  binding.  (Source ?? )
</p>

<p>
I finally settled on:
</p>

<pre>
(setf a (multiple-value-list
  (let ((counter 0))
     (values
        (lambda () (incf counter))
        (lambda () (decf counter))
        (lambda () counter)))))
</pre>

<p>Then, assign each to value from the list to a variable, like this: </p>

<pre>
(defun increase-count ()
   (funcall (car a)))

(defun decrease-count ()
   (funcall (nth 1 a)))

(defun get-count ()
   (funcall (nth 2 a)))
</pre>

<p>
LoL, states that the let over lamda is essentially an object, no different from
a an object returned by a class.  And it is true.  If I rewrite <pre>(set a
    (...))</pre> as a function like this:
</p>

<pre>
(defun counter-class (multiple-value-list
  (let ((counter 0))
     (values
        (lambda () (incf counter))
        (lambda () (decf counter))
        (lambda () counter)))))
</pre>

<p>
Then I can define two player count objects: player1 and player2
</p>

<pre>
(defun player1 () (counter-class))

(defun player2 () (counter-class))
</pre>

<p>
Now, to call each function within respective players object, I can write this:
</p>

<pre>
(funcall (car player1))     ; to increase player 1
(funcall (nth 1 player1))   ; to decrease count for player 1
(funcall (nth 2 player1))   ; to return the current value of count for player1
</pre>

<p>And of course I could do the same for player 2</p>

<p>But this is kind of ugly so I could create functions for each player</p>

<pre>
(defun player1.incf ()
   (funcall (car player1)))

(defun player1.decf ()
   (funcall (nth 1 player1)))

(defun player1.get ()
   (funcall (nth 2 player1)))
</pre>

<p>I would have to do the same for player2, which would be kind of tedious.</p>

<p>According to Graham and Hoyte, copying code begs to be made into a macro.
  Which I will return to later once I have a better understanding of how to
  write macros.
</p>