   plus:  (p)  -> new Point2d @x + p.x, @y + p.y
   minus: (p)  -> new Point2d @x - p.x, @y - p.y
   times: (f)  -> new Point2d @x * f, @y * f
-  toString:   -> "(#{@x}, #{@y})"
   equals: (p) -> @constructor == p.constructor and @x == p.x and @y == p.y
+
+  memo @, 'toString', -> "(#{@x}, #{@y})"
+  memo @, 'hashCode', -> hashCode @toString()
 
 
 # ----

class PointAtInfinity
  constructor: (@x, @y) ->
  isInfinite: -> true
  toString:   -> "inf(#{@x}, #{@y})"
  equals: (p) -> @constructor == p.constructor and @x == p.x and @y == p.y


# ----


# ----

# A method to be used in class bodies in order to create a method with a
# memoized result.

memo = (klass, name, f) ->
  klass::[name] = -> x = f.call(this); (@[name] = -> x)()

# ----

# The class `Point2d` represents points in the x,y-plane and provides just the
# bare minimum of operations we need here.
class Point2d
