Scheme中的继承类

问题描述 投票:0回答:4

现在我研究OOP——Scheme的一部分。我可以像这样在Scheme中定义类:

(define (create-queue)
  (let ((mpty #t) 
        (the-list '()))

    (define (enque value)
      (set! the-list (append the-list (list value)))
      (set! mpty #f)
      the-list)

    (define (deque)
      (set! the-list (cdr the-list))
      (if (= (length the-list) 0) 
      (set! mpty #t))
      the-list)

    (define (isEmpty)
      mpty)

    (define (ptl)
      the-list)

    (define (dispatch method)
      (cond ((eq? method 'enque) enque)
        ((eq? method 'deque) deque)
        ((eq? method 'isEmpty) isEmpty)
        ((eq? method 'print) ptl)))

    dispatch))

(示例来自 css.freetonik.com

我可以在Scheme中实现类继承吗?

inheritance lisp scheme
4个回答
6
投票

嗯,我不会称其为类,但这就是我。这只是闭包和原始方案。

Scheme本身没有对象系统。然而,Scheme 能够实现等级系统。

如果你想使用 oop 系统,有几个为Scheme编写的系统你可以尝试。

这里是一个列出了几个的链接,当然还有其他。


4
投票

OOP 语言使用继承来模拟多态性,即创建一个可以响应已发布的消息列表的对象类。在没有显式继承的情况下,Scheme 可以具有多态性,因为它是一种动态类型语言。比较 Java 中“Animal”类的实现和它在 Scheme 中的相应实现:

// Animal interface and implementations in Java

interface Animal {
    void cry (); // The only message to which an Animal object will respond.
}

class Cat implements Animal {
    void cry () {
        System.out.println ("meow!");
    }
}

class Cow implements Animal {
    void cry () {
        System.out.println ("baee!");
    }
}

// Usage

Animal a = new Cat ();
Animal b = new Cow ();
a.cry (); => "meow!"
b.cry (); => "baee!"

现在Scheme中使用闭包的相应实现:

;; A factory of Animals.
(define (animal type)
  (case type
    ((cat) (cat))
    ((cow) (cow))))

;; Corresponds to class Cat in Java.
(define (cat)
  (lambda (msg)
    (case msg
      ((cry) "meow!"))))

;; Corresponds to class Cow in Java.
(define (cow)
  (lambda (msg)
    (case msg
      ((cry) "baee!"))))

;; Sample usage

(define a (animal 'cat))
(define b (animal 'cow))
(a 'cry) => "meow!"
(b 'cry) => "baee!"

事实上,只有当我们必须处理太多私有状态时,我们才需要闭包。 Scheme 提供了许多方法来模拟上面的简单“类层次结构”。这是我们开发一个小型“消息调度”工具的一种方法,我们可以在对象列表上使用它:

;; Generic message dispatch.
(define (send type message objects)
    ((cdr (assq message (cdr (assq type objects))))))

;; A list of animals.
(define animals (list (cons 'cat (list (cons 'cry (lambda () "meow!"))))
                   (cons 'cow (list (cons 'cry (lambda () "blaee!"))))))

;; Send a specific message to a specific animal:
(send 'cat 'cry animals) => "meow!"
(send 'cow 'cry animals) => "blaee!"

Scheme 提供的功能抽象机制足够强大,让我们不用担心完整的对象系统。尽管如此,Scheme 仍然有一些对象系统。看看Tiny-CLOS(基于CLOS)。 Lisp in Small Pieces一书讨论了Scheme对象系统的实现(基于Meroon)。


3
投票

如果您决定确实想要推出自己的 OOP 系统,那么您当然可以在Scheme 中实现继承。这样做的一种方法是关闭所需超类的实例,该实例是在创建派生类的实例时“构造”的,并在

dispatch
过程中有一个额外的子句,类似于

(define (make-superclass-instance) 
  (define (method-a)
    (display "a!"))

  (define (method-b)
    (display "b!"))

  (define (dispatch message)
    (case message
      ((a) (method-a))
      ((b) (method-b))
      (else (error "nonexistent method"))))

  dispatch)

  (define (make-class-instance)
    (let ((super (make-superclass-instance)))
      (define (method-c)
        (display "c!"))

      (define (method-a)
        (display "overridden a!"))

      (define (dispatch message)
        (case message
          ((c) (method-c))
          ((a) (method-a))
          (else (super message))))

      dispatch))

这还允许轻松重写方法,如示例所示。

当然,这非常乏味,并且涉及大量样板文件。你可以用宏让它变得更愉快,但如果你有兴趣在Scheme中实际进行OOP而不是作为学习练习进行实验,我支持Will Hartung的建议,使用Scheme的许多现有对象系统之一。


0
投票

PLT计划中有一个相当完善的班级系统:

http://docs.plt-scheme.org/guide/classes.html

© www.soinside.com 2019 - 2024. All rights reserved.