Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: LennaHammer on Apr 8th, 2012  |  syntax: Scheme  |  size: 8.31 KB  |  hits: 51  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. ;#lang r5rs
  2. ;(define error display)
  3. ;;;一种Scheme语言中基于消息传递的面向对象机制 上 -- 语言机制 - Closure
  4. ;;;面向对象的机制的实现方式很都多种,常见的比如基于向量和隐藏this指针的。
  5. ;;;这里是基于程序语言中的闭包特性来实现的,尝试了面向对象机制中的一些常见情况。
  6. ;;;参考1 OCaml http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-objects.html
  7. ;;;参考2 SICP http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-17.html
  8. ;;;参考3 R5RS http://www.schemers.org/Documents/Standards/R5RS/HTML/
  9. ;;;查找对象方法的时间复杂度依赖所用实现的case语句的实现方式,若有优化则为O(1)。
  10.  
  11.  
  12. ;;;========================= 定义部分 ============================
  13.  
  14. ;;;function send
  15. ;;;向对象发送消息
  16. ;;;type = closure * symbol * object list -> object
  17. ;;;example. (send pair 'set-car! 1) == (set-car! pair 1)
  18. (define (send object method . arguments)
  19.   (cond ((object method)
  20.          =>(lambda (x) (apply x arguments)))
  21.         (else (error "method missing"))))
  22. ;;;function interface
  23. ;;;检验对象是否实现方法,注意方法名一致不能保证方法的语义正确
  24. ;;;type = symbol list -> (closure -> boolean)
  25. ;;;example. sequence? == (interface 'car 'cdr)
  26. (define (interface . methods)
  27.   (lambda (object)
  28.     (let loop ((methods methods))
  29.       (cond ((null? methods) #t)
  30.             ((not (object (car methods))) #f)
  31.             (else (loop (cdr methods)))))))
  32. ;;;functon coerce
  33. ;;;将对象绑定的若干方法表示为列表,用于调用泛型函数使用
  34. ;;;type = symbol list -> procedure list
  35. ;;;example. (coerce 'car 'cdr)
  36. (define (coerce . methods)
  37.   (map (lambda (method)
  38.          (lambda (object . arguments) (apply send object method arguments)))
  39.        methods))
  40. ;;;function method
  41. ;;;从对象链中查找方法
  42. ;;;type = symbol * closure list -> (procedure | false)
  43. ;;;example. ((method 'car pair)) == (send pair 'car)
  44. (define (method symbol . objects)
  45.   (let loop ((protos objects))
  46.     (cond ((null? protos) #f)
  47.           (((car protos) symbol) => (lambda (x) x))
  48.           (else (loop (cdr protos))))))
  49. ;;;macro object
  50. ;;;创建对象
  51. ;;;syntax = (object (prototypes ...) ((method (arguments ...) body ...) ...))
  52. ;;;example. (send (object () ((one () 1)))) 'one) == 1
  53. (define-syntax object
  54.   (syntax-rules ()
  55.     ((_  (prototypes ...) ((method-name (arguments ...) body ...) ...))
  56.      (lambda (m)
  57.        (case m
  58.          ((method-name) (lambda (arguments ...) body ...)) ...
  59.          (else (apply method m (list prototypes ...))))))))
  60. ;;;macro thunk
  61. ;;;用于延迟绑定
  62. ;;;syntax = (thunk object)
  63. ;;;example. (thunk 0)
  64. (define-syntax thunk
  65.   (syntax-rules () ((_ x) (lambda () x))))
  66. ;;;;macro object2
  67. ;;;上述“macro object”的 rich 版本
  68. ;;;syntax = (object2 self (prototype-news ...) ((slot value) ...) ((method (arguments ...) body ...) ...) init ...)
  69. ;;;example. <404>
  70. (define-syntax object2;define
  71.   (syntax-rules ()
  72.     ((_ self (prototype-news ...) ((slot value) ...) ((method (arguments ...) body ...) ...) init ...)
  73.      (letrec ((slot value) ...
  74.               (self
  75.                (lambda (m)
  76.                  (case m
  77.                    ((method) (lambda (arguments ...) body ...)) ...
  78.                    (else (let loop ((protos (list (prototype-news (lambda () self)) ...)))
  79.                            (cond ((null? protos) #f)
  80.                                  (((car protos) m) => (lambda (x) x))
  81.                                  (else (loop (cdr protos))))))))))
  82.        init ... self))))
  83. ;;;object top-object2
  84. ;;;用于继承树的根节点
  85. (define (top-object2 this)
  86.   (object2 self () () ((init () (this)))))
  87. ;;;function new
  88. ;;;用来构造一个对象
  89. (define (new class . arguments)
  90.   (define self (apply send (class (thunk self)) 'init arguments))
  91.   self)
  92. ;;;========================= 示例部分 ============================
  93.  
  94. ;;;* 示例一 Pair::mcons
  95. ;;;该示例用来演示如何创建一个对象
  96. ;;;定义A
  97. (define (mcons0 x y)
  98.   (lambda (m)
  99.     (case m
  100.       ((car) (lambda () x))
  101.       ((cdr) (lambda () y))
  102.       ((set-car) (lambda (z) (set! x z)))
  103.       ((set-cdr) (lambda (z) (set! x z)))
  104.       ((->pair) (lambda ()(cons x y)))
  105.       (else #f))))
  106. ;;;定义B
  107. (define (mcons x y)
  108.   (object ()
  109.           ((car () x)
  110.            (cdr () y)
  111.            (set-car (z) (set! x z))  
  112.            (set-cdr (z) (set! y z))
  113.            (->pair () (cons x y)))))
  114. ;;;泛型
  115. (define (mcar mpair)
  116.   ((mpair 'car)))
  117. (define (mcdr mpair)
  118.   ((mpair 'cdr)))
  119. (define (set-mcar mpair obj)
  120.   ((mpair 'set-car) obj))
  121. (define (set-mcdr mpair obj)
  122.   ((mpair 'set-cdr) obj))
  123. (define (mpair->pair mpair)
  124.   ((mpair '->pair)))
  125. ;;;使用
  126. (let example-1 ()
  127.   (define x (mcons 1 2))
  128.   (display (mcdr x))
  129.   (newline))
  130.  
  131. ;;;* 示例二 sequence
  132. ;;;该示例用来演示接口和泛型的使用
  133. (define sequence? (interface 'car 'cdr))
  134. (define (mlist . objects)
  135.   (if (null? objects) '()
  136.       (mcons (car objects) (apply mlist (cdr objects)))))
  137. (define (for-each0 p lst)
  138.   (cond ((null? lst) '())
  139.         (else (p (car lst)) (for-each p (cdr lst)))))
  140. (define (mfor-each p lst)
  141.   (cond ((null? lst) '())
  142.         (else (p (mcar lst)) (mfor-each p (mcdr lst)))))
  143. (define (generic-for-each prod lst car cdr)
  144.   (cond ((null? lst) '())
  145.         (else (prod (mcar lst)) (generic-for-each prod (mcdr lst) car cdr))))
  146. (define (mrange start end step)
  147.   (letrec ((self (object()
  148.                         ((car () start)
  149.                          (cdr () (let ((x (+ (send self 'car) step)))
  150.                                    (if (cond ((> step 0) (<= start x end))
  151.                                              ((< step 0) (>= start x end))
  152.                                              (else (error "mrange")))
  153.                                        (mrange x end step) '())))))))
  154.     self))
  155. (let example-2 ()
  156.   (define x (mlist 1 2 3 4 5))
  157.   (mfor-each display x)
  158.   (display (sequence? x))
  159.   ;(mfor-each display (mrange 0 10 2))
  160.   ;(generic-for-each display (mrange 0 10 2) mcar mcdr)
  161.   (apply generic-for-each display (mrange 0 -10 -3) (coerce 'car 'cdr))
  162.   (newline))
  163.  
  164. ;;;* 示例三 slots
  165. ;;;该示例用来演示构造器和私有成员
  166. (define (box x)
  167.   (letrec ((value '())
  168.            (self (object()
  169.                         ((ref () value)
  170.                          (set! (x) (set! value x))
  171.                          (add! (x) (send self 'set! (+ x (send self 'ref))))))))
  172.     (set! value x)
  173.     self))
  174. (let example-3 ()
  175.   (define x (box 1))
  176.   (display (send x 'ref))
  177.   (send x 'set! 2)
  178.   (display (send x 'ref))
  179.   (send x 'add! 2)
  180.   (display (send x 'ref))
  181.   (newline))
  182.  
  183. ;;;* 示例四 inheritance
  184. ;;;该示例用来演示扩充一个类
  185. (define (mlist2 . objects)
  186.   (define super (apply mlist objects))
  187.   (define self
  188.     (object (super)
  189.             ((for-each (prod) (apply generic-for-each prod self (coerce 'car 'cdr))))))
  190.   self)
  191. (let example-4 ()
  192.   (define x (mlist2 1 2 3 4 5))
  193.   (mfor-each display x)
  194.   (send x 'for-each display)
  195.   (newline))
  196.  
  197. ;;;* 实例五 virtual/override
  198. ;;;该示例用来演示模板方法模式
  199. (let example-5 ()
  200.   (define (hello name)
  201.     (letrec((self
  202.              (object ()
  203.                      ((name () (name))
  204.                       (say () (for-each display (list "hello " (send self 'name) "!\n")))))))
  205.       self))
  206.   (send (hello (lambda () "world0")) 'say)
  207.   (define (hello-world)
  208.     (define super (hello (lambda () (send self 'name))))
  209.     (define self (object (super) ((name () "world1"))))
  210.     self)
  211.   (send (hello-world) 'say)
  212.   (define (hello2 this)
  213.     (object ()
  214.             ((name () "<null>")
  215.              (say () (for-each display (list "hello " (send (this) 'name) "!\n"))))))
  216.   (define (hello-world2)
  217.     (define self
  218.       (object
  219.        ((hello2 (thunk self)))
  220.        ((name () "world2"))))
  221.     self)
  222.   (send (hello-world2) 'say)
  223.   (define (hello-world3)
  224.     (define self
  225.       (object2 self (top-object2 hello2) ()
  226.                ((name () "world3"))))
  227.     self)
  228.   (send (hello-world3) 'say)
  229.   (define (hello-world4 this)
  230.     (define self
  231.       (object2 self (top-object2 hello2) ()
  232.                ((name () "world4"))))
  233.     self)
  234.   (send (new hello-world4) 'say)
  235.   (newline))
  236.  
  237. ;;;待续 一种Scheme语言中基于消息传递的面向对象机制 下 -- 使用模式