;(ql:quickload "let-plus")
(defpackage :incf-test
  (:use :cl :let-plus))
(in-package :incf-test)

(define-modify-macro incf-mean (value tally)
  (lambda (mean value tally)
    (+ mean (/ (- value mean) tally))))

(define-modify-macro incf-noop (ignored)
  (lambda (old-value ignored)
    old-value))

(let ((x 0))
  (incf-mean x 10 1)) ; -> 10, as expected

;; Use in combination with let+
(let+ ((x 0))
  (incf-mean x 10 1)) ; -> 10, as expected

;; Use in combinaton with let+ and structures

(defstruct mean-accumulator mean tally)

(defun update-mean-accumulator (accum value)
  (let+ (((&structure mean-accumulator- mean tally) accum))
    ;; The next two expressions cause no trouble
    (incf tally)
    (incf-noop tally 1)
    ;; but this one will:
    (incf-mean mean value tally)))

(let ((accum (make-mean-accumulator :mean 0 :tally 0)))
  (update-mean-accumulator accum 10)
  (assert (= (mean-accumulator-mean accum) 10)))



