<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>