Feedback & Questions

Feedback on recursion assignment

  • bst-member? or bst-member-p: my bad!
  • Note search times in BT and BST
  • Depth-first versus breadth-first: completeness, memory efficiency

Lisp

;; bad style
(defun a-badly-formatted-function (x y z)
  (progn
    (setq x (+ x x))
    (setq y (* y y))
    (mod
      (+ z z)
      (+ x y)
      )
    )
  )

;; the right way
(defun a-pretty-function (x y z)
  "Function definitions need docstrings."
  (declare (integer x y z))
  (let ((x2 (+ x x))
        (y2 (* y y)))
    (mod (* z z) (+ x2 y2))))

When using paths, we need to distinguish between the empty path and failure to find a path. Failure is usually represented by nil so we choose to represent the empty path as a list containing just :here.

(deftype bt () '(or node null))

(defstruct node
  (value nil :type fixnum)
  (left nil :type bt)
  (right nil :type bt))

(defun test-path-sum ()
  (and (equalp nil (path-sum 1 nil))
       (equalp '() (path-sum 5 (make-node :value 10
                                          :left (make-node :value 6))))
       (equalp '(:here) (path-sum 5 (make-node :value 5)))
       (equalp '(:right :here)
               (path-sum 3 (make-node :value 1
                                      :right (make-node :value 2))))
       (equalp '(:left :here)
               (path-sum 7 (make-node :value 2
                                      :right (make-node :value 6)
                                      :left (make-node :value 5))))
       (equalp '(:right :left :here)
               (path-sum 11 (make-node :value 3
                                       :left (make-node :value 2
                                                        :right (make-node :value 6)
                                                        :left (make-node :value 5)))))))

(defun path-sum (n bt &optional (path '(:here)))
  "Find a path through the BT the values of which sum to N. Return NIL if no such
path exists. The path will consist of :left and :right and be terminated by
:here. This allows us to distinguish between a successful empty path and
failure."
  (and (node-p bt)
       (let ((d (- n (node-value bt))))
         (cond ((zerop d) path)
               (t (or (path-sum d (node-left  bt) (cons :left  path))
                      (path-sum d (node-right bt) (cons :right path))))))))

(defun test-path-max-sum ()
  (and (equalp '(:here :left)
               (path-max-sum (make-node :value 1
                                        :left (make-node :value 5)
                                        :right (make-node :value 2))))
       (equalp '(:here ) (path-max-sum (make-node :value 1)))
       (equalp nil (path-max-sum nil))
       (equalp '(:here :left :right)
               (path-max-sum
                (make-node :value 5
                           :left (make-node :value 7
                                            :right (make-node :value 10)
                                            :left (make-node :value 3))
                           :right (make-node :value 2))))))

(defun path-max-sum (bt)
  (path-max-sum-2 bt '(:here) 0 nil 0))

(defun path-max-sum-2 (bt path sum maxpath maxsum)
  (cond ((null bt) (if (> sum maxsum)
                       (values (reverse (rest path)) sum)
                       (values maxpath maxsum)))
        ((node-p bt) (multiple-value-bind (lmaxpath lmax)
                         (path-max-sum-2 (node-left bt)
                                         (cons :left path)
                                         (+ sum (node-value bt))
                                         maxpath
                                         maxsum)
                       (path-max-sum-2 (node-right bt)
                                       (cons :right path)
                                       (+ sum (node-value bt))
                                       lmaxpath
                                       lmax)))))

Be careful when copy/pasting from a LLM in your browser. You can copy invisible characters such as "Non-Breaking Spaces" (NBSPs) which will confuse your Lisp interpreter. Also be careful of non-breaking hyphens. LLMs use them a lot.

I have to smile when I see an LLM get angry with a student.

I've asked twice now: post your actual code.
I can't keep guessing from error messages alone.

But it's also nice to see an LLM encourage you and reinforce its point.

You’ve got this — and since you asked three times,
let’s make this crystal clear and beautifully aligned
with the recursive structure you’ve been mastering.
Great question — and it shows you’re really thinking
about the structure of the problem rather than just
coding your way through it. Let’s unpack it in a way
that feels natural and intuitive.
Ahh, Student — if every test returns NIL, that’s a huge clue.
Let’s walk through it in a way that fits your recursive‑thinking groove.
Student, I love how you’re trying to build this recursively
— but no, that version doesn’t work.

Writing comments in Lisp. The number of semicolons indicates the style of the comment:

Semicolons Meaning Typical Use
; End-of-line comment After code
;; Inline comment Explaining a block
;;; Section header Organizing files
;;;; File-level header Big banners or metadata

Writing style in reports: I, we, "the repo"?

Lisp scripts and executables.

In Lisp, indentation doesn't define scope — parentheses do.

Student Feedback

What students appreciated:

  • The in-class exercises, which help to be more engaged with the class material
  • The content of the course, as well as the fun assignments
  • Questions to random students, interactive classes- helps with engagement
  • The feedback being rich and helpful
  • Showing and explaining everything you are doing on the screen
  • Classes being more focused on the practical side (e.g. which tools to use)
  • Recursion exercises during class were fun, as well as the project, notably due to the more extensive preparation in class, making students able to work more independently (without extensive use of AI). (One student suggested the possibility of having the Lisp assignment before the bdd assignment)
  • Using AI so freely is constructive, as we will have to use it in the future, and it is therefore important to learn how to use it correctly

What to improve:

  • Expectations and requirements for the assignments could be clearer, one student mentioned the possibility of setting up check-in meetings for every teams, or using more office hours if possible. Students would also appreciate a rubric on graded projects (e.g. “if all functions work, do we get a 10 or are we graded on something else ?”)
  • The assignments feel a little bit disconnected from one another
  • Assignments feel a little too heavy, even though their usefulness is undeniable
  • ⁠Use of AI could be better explained (“I find myself relying on intuition to find the boundaries”)

etc

Author: Breanndán Ó Nualláin <o@uva.nl>

Date: 2026-04-16 Thu 09:59