[racket] Applicable objects

From: David Van Horn (dvanhorn at ccs.neu.edu)
Date: Tue Dec 14 14:16:13 EST 2010

On 12/14/10 11:53 AM, Jim Wise wrote:
> David Van Horn<dvanhorn at ccs.neu.edu>  writes:
>> I learned that every Scala object that defines an apply method can be used
>> as a function.  Cute.  It's nice to see a language emphasize the symmetry
>> between objects and functions.
>
> Note that this is actually bi-directional in Scala -- any object which
> defines an unapply() method can be used in an ml-style pattern matching
> statement as if it were an algebraic type constructor...

I flushed out what Jay said using a match expander.  This is the example 
from the Scala tour:

    http://www.scala-lang.org/node/112

#lang racket
(require test-engine/racket-tests)

(define applicable<%>
   (interface* ()
               ([prop:procedure
                 (λ (obj x) (send obj apply x))])
               apply))

(define-match-expander object
   (λ (stx)
     (syntax-case stx ()
       [(object o x)
        #'(app (λ (x) (send o unapply x))
               (? (λ (x) x) x))])))

(define twice%
   (class* object% (applicable<%>)
     (define/public (apply x)
       (* 2 x))
     ;; Number -> [Opt Number]
     (define/public (unapply z)
       (and (even? z) (quotient z 2)))
     (super-new)))

(check-expect (match ((new twice%) 21)
                 [(object (new twice%) n) n])
               21)

(check-error (match 21
                [(object (new twice%) n) n])
              "match: no matching clause for 21")

(test)


Posted on the users mailing list.