Introduction to the Java Memory Model

June 10th, 2010

Yesterday, I gave at work a swift introduction to the JMM. Here.

(-1)(-1) = 1

March 27th, 2010

Proposed in Mathematics: A Very Short Introduction. Given the following rules:

A1 Commutative law for addition: \forall a,b\quad a + b = b + a

A2 Associative law for addition: \forall a,b,c\quad a + (b + c) = (a + b) + c

A3 Additive identity: \forall a\quad 0 + a = a

A4 Additive inverse: \forall a,\exists b\quad a + b = 0

A5 Cancellation law for addition: \forall a,b,c\quad if\ a + b = a + c,\ then\ b = c

M1 Commutative law for multiplication: \forall a,b\quad ab = ba

M2 Associative law for multiplication: \forall a,b,c\quad a(bc) = (ab)c

M3 Multiplicative identity: \forall a\quad 1a = a

M4 Multiplicative inverse: \forall a\ne0,\ \exists b\quad ab = 1

M5 Cancellation law for multiplication:

\forall a,b,c\quad if\ a\ne0\ and\ ab = ac,\ then\ b = c

D Distributive law: \forall a,b,c\quad (a + b)c = ac + bc

Let’s prove that (-1)(-1) = 1:

Swapping two variables

February 26th, 2010

Say we need to swap the values of two variables, a and b. This is a classic problem in programming and it can be accomplished in a few ways.

Using a temporary variable

This is the straightforward method; just use a temporary variable to avoid losing one of the variable values:

1
2
3
temp = a
a = b
b = temp

Temporary

Accumulating one of the values

Use one of the variables to temporarily keep track of both variable values:

1
2
3
a = a + b
b = a - b
a = a - b

accumulating

Using Exclusive-OR (XOR)

The exclusive-or binary operator takes two bits and returns 1 only if both values differ, 0 if equal:

A B A XOR B
0 0 0
0 1 1
1 0 1
1 1 0

The bitwise exclusive-or operator (^) will apply the exclusive-or operation on every pair of bits of the inputs.

   01100110
^  01011110
   --------
   00111000

Three interesting properties, given A, B = {0, 1}:

  1. A XOR 0 = A (i.e. A XOR 0 returns A whatever A)
  2. A XOR 1 = ~A (i.e. A XOR 1 returns A flipped)
  3. (A XOR B) XOR B = A

The third property requires further explanation. On the one hand, if B is 0 then, by 1), applying XOR B twice to A returns A itself. On the other, if B is 1 then we are flipping A twice by 2), which winds up returning A itself.

We base our last method of swapping two (integer) variables on those three properties:

1
2
3
4
5
6
swap (A, B)
{
  A = A ^ B;
  B = B ^ A;
  A = B ^ A;
}

XOR

More formally, the computation:

1
2
3
  A = A ^ B;
  B = B ^ A;
  A = B ^ A;

is equivalent to:

1
  B = B ^ (A ^ B) = (A ^ B) ^ B = A

At this point, B has the original value of A, therefore:

1
  A = A ^ (A ^ B) = (B ^ A) ^ A = B

This last method is the most performant among them all.

Question

Now that we have sifted through these three methods of swapping two variables, question: which is the main advantage of the first over the others?

Exercise 1.10

December 29th, 2009

Given the following implementation of the Ackermann’s Function:

1
2
3
4
5
6
(define (A x y)
  (cond ((= y 0) 0)
        ((= x 0) (* 2 y))
        ((= y 1) 2)
        (else (A (- x 1)
                 (A x (- y 1))))))

What are the evaluations of these expressions:

1
(A 1 10)

Value: 1024

1
(A 2 4)

Value: 65536

1
(A 3 3)

Value: 65536

What are the mathematical counterparts of these procedures:

1
(define (f n) (A 0 n))

corresponds to: f(n)=2n


1
2
3
4
5
6
7
8
(define (g n) (A 1 n))

(A 0 (A 1 (- n 1))
(A 0 (A 0 (A 1 (- n 2))))
(A 0 (A 0 (A 0 (A 1 (- n 3)))))
.
.
.

corresponds to:

g(n) = \begin{cases}0 & \mbox{if }n=0 \\ 2^n & \mbox{if }n \ge 1\end{cases}


1
2
3
4
5
6
7
8
9
(define (h n) (A 2 n))

(A 2 n)
(A 1 (A 2 (- n 1)))
(A 1 (A 1 (A 2 (- n 2))))
(A 1 (A 1 (A 1 (A 2 (- n 3)))))
.
.
.

At some step i, the most inner combination in the form (A 2 (- n i)) will evaluate to 2 cause n-i=1. (A 1 x) is 2^x by the definition of g(n), and there will be n evaluations of such combination, resulting in:

2^{2^{2^{\dots}}}

This can be also expressed as a recurrence:

h(n) = \begin{cases}0 & \mbox{if }n=0 \\ 2 & \mbox{if }n=1 \\ 2^{h(n-1)} & \mbox{if }n \ge 2\end{cases}

Exercise 1.9

December 28th, 2009

Evaluate (+ 4 5) using the following procedure definition:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(define (+ a b)
  (if (= a 0)
      b
      (inc (+ (dec a) b))))

(+ 4 5)
(inc (+ (dec 4) 5))
(inc (+ 3 5))
(inc (inc (+ (dec 3) 5)))
(inc (inc (+ 2 5)))
(inc (inc (inc (+ (dec 2) 5))))
(inc (inc (inc (+ 1 5))))
(inc (inc (inc (inc (+ (dec 1) 5)))))
(inc (inc (inc (inc (+ 0 5)))))
(inc (inc (inc (inc 5))))
(inc (inc (inc 6)))
(inc (inc 7))
(inc 8)
9

This is a linear recursive process.

Now, use the following definition instead to evaluate the same combination:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(define (+ a b)
  (if (= a 0)
      b
      (+ (dec a) (inc b))))

(+ 4 5)
(+ (dec 4) (inc 5))
(+ 3 6)
(+ (dec 3) (inc 6))
(+ 2 7)
(+ (dec 2) (inc 7))
(+ 1 8)
(+ (dec 1) (inc 8))
(+ 0 9)
9

This is an linear iterative process.