News for hackers. Stuff that matters.
Re:A Road to Lisp: Which Lisp by dieggsy on Friday July 17, 2026 @11:26AM (#48948552)
CL also has pretty much arbitrarily extensible syntax:

- https://sr.ht/~dieggsy/whisper/

- https://dieggsy.com/json-literals.html

And could also be used to build languages, supporting more modern programming paradigms (though yes, I believe Racket does make this easier):

- https://coalton-lang.github.io/

I also might have written the Common Lisp example using reduce as well, which is in the standard library, but that's preference. Nice to have the option though:

  (defun calculate (instructions)
    (reduce
     (lambda (result op-value)
       (destructuring-bind (operation value) op-value
         (case operation
           (:add (+ result value))
           (:subtract (- result value))
           (:multiply (* result value)))))
     instructions
     :initial-value 0))

  (calculate '((:add 5) (:multiply 3) (:subtract 4))) ;; => 11
Re:A Road to Lisp: Which Lisp by BoingBoomTschak on Friday July 17, 2026 @11:44AM (#48948732)
I'd have used

  (funcall (ecase operation (:add '+) (:subtract '-) (:multiply '*)) result value)
instead, looks funkier =)
Re:A Road to Lisp: Which Lisp by dieggsy on Friday July 17, 2026 @11:46AM (#48948754)
Oh yeah, way more fun :) I just kinda saw CL in the Clojure and was trying to make it look like that.
Re:A Road to Lisp: Which Lisp by kazinator on Saturday July 18, 2026 @07:37PM (#48963534)
Did you know CL allows keywords to be function names?

  [1]> (setf (symbol-function :add) (function +))
  #<SYSTEM-FUNCTION +>
  [2]> (setf (symbol-function :subtract) (function -))
  #<SYSTEM-FUNCTION ->
  [3]> (setf (symbol-function :multiply) (function *))
  #<SYSTEM-FUNCTION *>
  [4]> (setf (symbol-function :divide) (function /))
  #<SYSTEM-FUNCTION />
  [5]> (reduce (lambda (x y) (funcall (car y) x (cadr y))) '((:add 5) (:multiply 3) (:subtract 4)) :initial-value 0)
  11
This is actually a small benefit of the two namespaces. Keywords can't be variables because they evaluate to themselves, but that is not relevant to the operator position that does not resolve variables.
Re:A Road to Lisp: Which Lisp by BoingBoomTschak on Sunday July 19, 2026 @01:10PM (#48969847)
Huh, I guess I "knew" since keywords are just regular symbols in the KEYWORD package in this situation, but it never occurred to me to do something that cursed. Very cool!

But this made me realize there's no way in CL (even with PROGV shenanigans) to temporarily bind the function value of a symbol, unlike the variable one through a simple LET =(

So this turns in this horrible (and incorrect, since this doesn't restore the previous FDEFINITIONs) thing when you want to use this hack "properly":

  (defun calculate (instructions)
    (setf (symbol-function :add)      #'+
          (symbol-function :subtract) #'-
          (symbol-function :multiply) #'*)
    (unwind-protect
         (reduce
          (lambda (result op-value)
            (funcall (car op-value) result (cadr op-value)))
          instructions
          :initial-value 0)
      (fmakunbound :add)
      (fmakunbound :subtract)
      (fmakunbound :multiply)))
Re:A Road to Lisp: Which Lisp by kazinator on Monday July 20, 2026 @01:28AM (#48974657)
There are no dynamically scoped function bindings in Common Lisp.

Pascal Costanza somehow implemented such a thing. See 2003 paper "Dynamically Scoped Functions as the Essence of AOP", a precursor to work on AspectL and ContextL.

https://dl.acm.org/doi/pdf/10.1145/944579.944587

Dynamically scoped functions are wrappers which indirect to lambdas bound to a special variable; i.e. this is boostrapped out of dynamic variable scope.

Re:A Road to Lisp: Which Lisp by pooyamo on Saturday July 18, 2026 @04:11AM (#48956134)
The LOOP solution could be written using DOLIST or DO forms too (likewise built-in):

  (defun calculate (instructions)
    (let ((result 0))
      (dolist (e instructions result)
        (destructuring-bind (operator operand) e
          (setf result
                (case operator
                  (add      (+ result operand))
                  (multiply (* result operand))
                  (subtract (- result operand))))))))
  
  (defun calculate (instructions)
    (do ((result 0))
        ((null instructions) result)
      (destructuring-bind (operator operand) (pop instructions)
        (setf result
              (case operator
                (add      (+ result operand))
                (multiply (* result operand))
                (subtract (- result operand)))))))