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).
(define (make-counter value)
(lambda (operator)
(set! value (operator value))))
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).
(define (make-counter value)
(lambda (operator)
(set! value (operator value))))
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
.
(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