• 0 Posts
  • 1 Comment
Joined 1 year ago
cake
Cake day: October 10th, 2023

help-circle
  • You shouldn’t need funcall in your common lisp code, but the way you defined your function requires it. You have

    (let ((c 0))
      (defun my-counter! ()
        (lambda ()
          (setf c (+ 1 c))
          c)))
    

    defun already defines a function; you don’t need to also wrap the function body in a lambda. This definition allows you to avoid the funcall:

    (let ((c 0))
      (defun my-counter! ()
        (setf c (+ 1 c))
        c))
    

    Though it’s worth knowing that unlike in scheme, common lisp will return the value after a setf. There’s also a convenience macro called incf that increments variables so you can write the whole thing like this:

    (let ((c 0))
      (defun my-counter! ()
        (incf c)))
    

    And your other question: Why the different placing of the let?

    In common lisp, defun, defvar, defparameter, defmacro, … all affect global scope, no matter where they appear. scheme’s define does not affect global scope; its effects are only visible locally. This means that a defun inside of a let body still creates a globally accessible function that closes over the variables defined in the let bindings. Scheme, by contrast, needs to have a define at global level (or at least outside the let) but the function body still needs to close over the let variables.