# Order of operations concerning set! in this function

**URL:** <https://forum.systemcrafters.net/t/order-of-operations-concerning-set-in-this-function/1439>\
**Category:** Courses\
**Tags:** guile, scheme\
**Created:** [March 3, 2025, 6:17am UTC](https://forum.systemcrafters.net/t/order-of-operations-concerning-set-in-this-function/1439 "2025-03-03T06:17:59Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![drewverlee](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.systemcrafters.net/drewverlee/32/912_2.png) [@drewverlee](https://forum.systemcrafters.net/u/drewverlee)\
**Post date:** [March 3, 2025, 6:17am UTC](https://forum.systemcrafters.net/t/order-of-operations-concerning-set-in-this-function/1439/1 "2025-03-03T06:17:59Z")

</div>

This function below gets called like this: (make-counter 0), and so to me, it looks like we’re setting 0 to something, which feels counterintuitive (tehe).

```auto
(define (make-counter value)
  (lambda (operator)
    (set! value (operator value))))

```

---

<div class="post-metadata">

**Author:** ![cow\_2001](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.systemcrafters.net/cow_2001/32/598_2.png) [@cow\_2001](https://forum.systemcrafters.net/u/cow_2001)\
**Post date:** [March 3, 2025, 7:19am UTC](https://forum.systemcrafters.net/t/order-of-operations-concerning-set-in-this-function/1439/2 "2025-03-03T07:19:23Z")

</div>

If you want to read `value` later on after it is changed, you must pack your value in a data structure like a pair, a box, a record, or a vector, because you are passing it by value into `make-counter`. The variable `value` in the closure is not the same variable as the one you pass into `make-counter`.

```auto
(define (make-counter value)
  (lambda (operator)
    (set! value (operator value))))

(define some-number 0)

(format #t "~s~%" some-number) ;; prints 0

(define some-counter (make-counter some-number))

(some-counter (lambda (x) (+ x 1)))
;; Only changes the variable within the closure, not outside of it.

(format #t "~s~%" some-number) ;; prints 0

;;; In a pair:

(define number-in-a-pair (cons 0 '()))

(format #t "~s~%" (car number-in-a-pair)) ;; prints 0

(define number-in-a-pair-counter (make-counter number-in-a-pair))

(number-in-a-pair-counter (lambda (x)
                         (set-car! x (+ (car x) 1))
                         x))

(format #t "~s~%" (car number-in-a-pair)) ;; prints 1

;;; In a box:

(use-modules (srfi srfi-111))
;; Import boxes library
;; https://srfi.schemers.org/srfi-111/srfi-111.html
;; https://www.gnu.org/software/guile/manual/html_node/SRFI_002d111.html

(define boxed-number (box 0))

(format #t "~s~%" (unbox boxed-number)) ;; prints 0

(define boxed-number-counter (make-counter boxed-number))

(boxed-number-counter (lambda (x)
                        (set-box! x (+ (unbox x) 1))
                        x))

(format #t "~s~%" (unbox boxed-number)) ;; prints 1

;;; What you might want is:

(define (make-a-better-counter value)
  (lambda (operator)
    (set! value (operator value))
    value))

(define another-number 0)

(format #t "~s~%" another-number) ;; Prints 0

(define another-counter (make-a-better-counter another-number))

(format #t "~s~%" (another-counter (lambda (x) (+ x 1)))) ;; Prints 1

(format #t "~s~%" (another-counter (lambda (x) (+ x 1)))) ;; Prints 2

```
