This page provides Scheme definitions for some operations on variables familiar from other languages.
If your favourite language provides a variable operation you don't see here, let me know.
We use the following to implement the operations:
(define-syntax define-simple-syntax
(syntax-rules ()
((_ (name arg ...) body ...)
(define-syntax name (syntax-rules () ((name arg ...) (begin body ...)))))))
Replace a variable's value with a modified version.
The following works for any operation (so is already more powerful than what can be done in Java, C, C++, Python, etc):
; (set!! op v a ...) ; set v to (op v a ...) and return v (define-simple-syntax (set!! op v a ...) (set! v (op v a ...)) v) ; Example (define x 2) (set!! + x 3) ; x is now 5 (define l '(1 2 3)) (set!! reverse l) ; l is now '(3 2 1)
The following define the well-known arithmetic versions from Java, C, C++, Python, etc. Notice our versions allow multiple arguments.
(define-simple-syntax (+= a ...) (set!! + a ...)) (define-simple-syntax (-= a ...) (set!! - a ...)) (define-simple-syntax (*= a ...) (set!! * a ...)) (define-simple-syntax (/= a ...) (set!! / a ...)) (define-simple-syntax (++ a) (+= a 1)) (define-simple-syntax (-- a) (-= a 1)) ; Example (define x 2) (+= x 3) ; x is now 5 (+= x 4 9) ; x is now 18 (-- x) ; x is no 17
Post-increment/decrement versions of ++ and --
could also be defined.
In C (but not Java nor Python) one can take the address of a variable, usually to pass it to a function for call-by-reference. The address is used to get or set the value of its associated variable.
We model the address of a variable as an overloaded procedure that when called with no argument returns the value and when called with an argument sets the variable to the argument.
;;; (& var) => a procedure p with
;;; (p): return value of var [i.e. var]
;;; (p val): update var to be val [i.e. (set! var val)]
(define-simple-syntax (& var)
(let ((p (lambda args (if (null? args) var (set! var (car args))))))
p))
; Example
(define (swap x y) (let ((temp (x))) (x (y)) (y (temp))))
(define x 2)
(define y 3)
(swap (& x) (& y)) ; x is now 3, y is now 2