;; ---------------------------------------------------------------- ;; *Eight* ways to implement the PAIR interface in Racket. ;; Uncomment the definitions to try an implementation. ;; ---------------------------------------------------------------- #lang racket (provide MAKE-PAIR ; constructor: return a pair FIRST ; accessor : first item in a pair SECOND) ; accessor : second item in a pair ;; ---------------------------------------------------------------- ;; ... using pairs. ;; ---------------------------------------------------------------- (define MAKE-PAIR cons) (define FIRST car) (define SECOND cdr) ;; ---------------------------------------------------------------- ;; ... using lists. ;; ---------------------------------------------------------------- ;; (define (MAKE-PAIR a b) (list a b)) ;; (define FIRST first) ;; (define SECOND second) ;; ---------------------------------------------------------------- ;; ... using vectors. ;; ---------------------------------------------------------------- ;; (define (MAKE-PAIR a b) (vector a b)) ;; (define (FIRST aPair) (vector-ref aPair 0)) ;; (define (SECOND aPair) (vector-ref aPair 1)) ;; ---------------------------------------------------------------- ;; ... using hash tables. ;; ---------------------------------------------------------------- ;; (define (MAKE-PAIR a b) (hash 'first a 'second b)) ;; (define (FIRST aPair) (hash-ref aPair 'first)) ;; (define (SECOND aPair) (hash-ref aPair 'second)) ;; ---------------------------------------------------------------- ;; ... using structs. This is Racket's primitive record type. ;; ---------------------------------------------------------------- ;; (struct pair (one two)) ;; (define MAKE-PAIR pair) ;; (define FIRST pair-one) ;; (define SECOND pair-two) ;; ---------------------------------------------------------------- ;; ... using a selector function. This also requires booleans. ;; ---------------------------------------------------------------- ;; (define (MAKE-PAIR a b) (lambda (selector?) ;; (if selector? a b))) ;; (define (FIRST aPair) (aPair #t)) ;; (define (SECOND aPair) (aPair #f)) ;; ---------------------------------------------------------------- ;; ... using a message passing. This also requires symbols. ;; ---------------------------------------------------------------- ;; (define (MAKE-PAIR a b) (lambda (selector) ;; (cond ((eq? selector 'first ) a) ;; ((eq? selector 'second) b)))) ;; (define (FIRST aPair) (aPair 'first)) ;; (define (SECOND aPair) (aPair 'second)) ;; ---------------------------------------------------------------- ;; ... using *only* functions. No other data type required! ;; ---------------------------------------------------------------- ;; (define (MAKE-PAIR a b) (lambda (proc) (proc a b))) ;; (define (FIRST aPair) (aPair (lambda (x y) x))) ;; (define (SECOND aPair) (aPair (lambda (x y) y))) ;; ---------------------------------------------------------------- ;; Using pairs, regardless of implementation. ;; ---------------------------------------------------------------- (define pair1 (MAKE-PAIR 2 3)) (define pair2 (MAKE-PAIR 1 pair1)) (FIRST pair2) (FIRST (SECOND pair2)) (SECOND (SECOND pair2)) ;; ----------------------------------------------------------------