Классы наследования в Схеме - PullRequest
2 голосов
/ 04 марта 2010

Теперь я исследую ООП-часть Схемы. Я могу определить класс в схеме, как это:

(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 )

Могу ли я реализовать наследование классов в Схеме?

Ответы [ 4 ]

6 голосов
/ 04 марта 2010

Ну, я бы не назвал это классом, но это только я. Это просто замыкания и грубая схема.

Сама схема не имеет объектной системы. Тем не менее, Схема способна реализовать систему классов.

Если вы хотите использовать oop-систему, есть несколько написанных для Scheme, которые вы можете попробовать.

Здесь - это ссылка, которая перечисляет несколько, есть, конечно, другие.

3 голосов
/ 05 марта 2010

ООП языки используют наследование для имитации полиморфизма, то есть для создания класса объектов, которые могут отвечать на опубликованный список сообщений. Вы можете иметь полиморфизм в Scheme без явного наследования, потому что это язык с динамической типизацией. Сравните реализацию класса «Animal» в Java и соответствующую реализацию в 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!"

На самом деле нам нужны закрытия, только если нам приходится иметь дело со слишком большим количеством частного государства. Схема предоставляет множество способов симулировать простые «иерархии классов», как указано выше. Вот один метод, с помощью которого мы развиваем крошечное средство «отправки сообщений», которое мы можем использовать в списке объектов:

;; 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, достаточно мощны, чтобы мы не беспокоились о полной объектной системе. Тем не менее, существуют некоторые объектные системы для Схемы. Взгляните на Tiny-CLOS (на основе CLOS ). В книге Лисп в маленьких кусочках обсуждается реализация системы объектов для схемы (на основе Meroon ).

3 голосов
/ 05 марта 2010

Конечно, вы можете реализовать наследование в Схеме, если решите, что хотите развернуть свою собственную систему ООП. Один из способов сделать это - закрыть экземпляр нужного суперкласса, который «создается», когда вы создаете экземпляр производного класса, и в процедуре 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))

Это также позволяет легко переопределять методы, как показано в примере.

Конечно, это довольно утомительно и требует большого количества шаблонов. Вы могли бы сделать его более приятным с помощью макросов, но если вы заинтересованы в том, чтобы на самом деле выполнять ООП в Схеме, а не экспериментировать в качестве учебного упражнения, я повторяю предложение Уила Хартунга использовать одну из многих существующих объектных систем Схема.

0 голосов
/ 23 марта 2010

В PLT Scheme довольно развитая система классов:

http://docs.plt -scheme.org / гид / classes.html

...