hash-cons.ss
(module hash-cons mzscheme
  
  (require (lib "contract.ss")
           (prefix private: "private/hash-cons.ss"))
  
  (provide/contract
   [rename -hash-cons hash-cons (any/c any/c . -> . (cons/c any/c any/c))])
  
  ;; hash-cons: X Y -> (cons X Y)
  ;; Like cons, but remembers arguments.  If it can, it will try for
  ;; maximal sharing.
  ;;
  ;; WARNING: don't use the resulting cons pair with mutation!
  (define -hash-cons
    (let ([sema (make-semaphore 1)])
      (lambda (x y)
        (call-with-semaphore
         sema
         (lambda ()
           (private:hash-cons x y)))))))