Operating on Variables

Operators such as += in Java, C, C++, Python, etc operate on variables, not just on their values. In a call-by-value language they can't be written as functions unless variables can be treated to some extent as values. In Scheme we can define syntax to manipulate variables directly, or to turn them into values.

This page focuses on variables. If the goal is simply to allow calling a function to have an effect on the caller (without the caller having to react to a returned value) there is the option of passing a mutable object. If the object one is working with is not inherently mutable, it can be boxed/wrapped in another object.

Java, Python

Java and Python are call-by-value and can't treat variables as values, so only their predefined operators are available.

C

C is call-by-value. But it can treat variables as values: a pointer to v is obtained by &v, with the pointer declared and dereferenced by *. For example:

void inc(int *var) { *var = *var + 1; }

int v = 2;
inc(&v);

C++

In C++ you can declare a function parameter to be call-by-reference:

int inc(int& var) { var = var + 1; }
 
int v = 2;
inc(v);

Scheme

Call by name

Procedures in Scheme are call-by-value, but macros in Scheme are call-by-name. So we use macros to write operations on variables:

(define-syntax ++
  (syntax-rules ()
    ((++ var) (set! var (+ var 1)))))

(define v 2)
(++ v)

Variables as values

We can mimic the C approach if we like. 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. To automate the creation of the function we make a macro &:

;;; (& 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))

Here is how we use it:

(define (++ var)
  (var (+ (var) 1)))

(define v 2)
(++ (& v))