(defun replace-argument (x) (let (x 1) x))

(defun replace-let ()
  (let (x 1)
    (setq x 2) ;; mutate local x
    x
    )
  )

(defun reassignment-in-a-loop (iterations)
  (let (x 0 y 1)
    (while (< x iterations)
      (setq y (* y 2))
      (setq x (+ x 1))
      )
    y
    )
  )

(assert (= (replace-argument 2) 1))
(assert (= (replace-argument 3) 1))
(assert (= (replace-let) 2))
(assert (= (reassignment-in-a-loop 4) 16))

;; capture upvalue
(assert
  (=
    123
    (let
      (loc0 123)
      ((lambda () loc0))
      )
    )
  )

;; mutate upvalue
(assert
  (=
    321
    (let
      (loc0 123)
      ((lambda () (setq loc0 321)))
      loc0
      )
    )
  )
