Frage

Ich habe SICP (Struktur und Interpretation von Computerprogrammen) durchgelesen und war sehr begeistert, diese wunderbare besondere Form zu entdecken: "Make-Environment", die sie in Kombination mit Evaly als Möglichkeit zum Schreiben modularer Code (Auszug) demonstrieren, Aus Abschnitt 4.3 auf "Paketen"):

(define scientific-library
  (make-environment
   ...
   (define (square-root x)
    ...)))

Sie zeigen dann, wie es funktioniert

((eval 'square-root scientific-library) 4)

In ihrem Beispiel zeigen sie dann weiter, um zu demonstrieren exakt Die Verwendung, die ich möchte - eine elegante, minimalistische Art, den "oo" -Stil im Schema zu machen ... sie "Nachteile" zusammen einen "Typ", was tatsächlich die spezielle Form "Make -Environment" zurückgegeben wurde (spezielle Form " dh der vtable) und ein arg ("der Staat") ...

Ich war so aufgeregt, weil das ist exakt Was ich gesucht habe, um einen polymorphen Versand "nach Symbol" im Schema zu machen, ohne viele explizite Code oder Makros schreiben zu müssen.

dh ich möchte ein "Objekt" erstellen, das beispielsweise: zwei Funktionen, die ich in verschiedenen Kontexten aufrufe ... aber ich möchte sie nicht mit "Auto" und "CDR" beziehen, ich möchte beides erklären und auswerten sie durch ihre symbolischen Namen.

Wie auch immer, als ich das las, konnte ich es kaum erwarten, nach Hause zu kommen und es zu versuchen.

Stellen Sie sich meine Enttäuschung vor, als ich im PLT -Schema und im Chez -Schema Folgendes erlebte:

> (make-environment (define x 3))
Error: invalid context for definition (define x 3).
> (make-environment)
Error: variable make-environment is not bound.

Was ist mit "Make-Environment" passiert, wie in SICP verwiesen? Es schien alles so elegant und genau das, was ich will, aber es scheint in keiner modernen Schema -Dolmetscher unterstützt zu werden?

Was ist die Begründung? Ist es einfach so, dass "Make-Environment" einen anderen Namen hat?

Weitere Informationen später gefunden

Ich habe mich bei der Online -Version angesehen:

http://mitpress.mit.edu/sicp/full-text/book/book-zh-28.html#%_sec_4.3

Ich las, war die erste Ausgabe von SICP. Die zweite Ausgabe scheint die Diskussion auf Paketen durch einen Abschnitt über nicht deterministische Programmierungen und den "Amp" -Operator ersetzt zu haben.

War es hilfreich?

Lösung

Nachdem ich mehr herumgegraben hatte, entdeckte ich das Informativer Thread auf Newsnet:

"Die R5RS-Eval- und Umgebungsspezifizierer sind ein Kompromiss zwischen denen, die erstklassige Umgebungen zutiefst nicht mögen und eine eingeschränkte Bewertung wünschen, und denen, die Eval nicht ohne zweites Argument, das eine Umgebung ist, nicht akzeptieren/verstehen können."

Fand auch diese "Workaround":

(define-syntax make-environment 
  (syntax-rules () 
    ((_ definition ...) 
     (let ((environment (scheme-report-environment 5))) 
       (eval '(begin definition 
                     ...) 
             environment) 
       environment)))) 


(define arctic 
  (make-environment 
    (define animal 'polarbaer))) 

(genommen von Dies)

Am Ende habe ich jedoch einen "Nachrichtenübergang" -Stil wie der erste vorgeschlagene Mann übernommen - ich kehre einen Alist von Funktionen zurück und habe eine generische "Senden" -Methode, um eine bestimmte Funktion mit Namen aufzurufen ... dh so etwas wie dieser

(define multiply
  (list
    (cons 'differentiate (...))
    (cons 'evaluate (lambda (args) (apply * args)))))

(define lookup
  (lambda (name dict)
    (cdr (assoc name dict))))

; Lookup the method on the object and invoke it
(define send
  (lambda (method arg args)
    ((lookup method arg) args))

((send 'evaluate multiply) args)

Ich habe weiter gelesen und bin mir bewusst, dass es alles gibt, wenn ich wirklich einen vollständigen OO -Stil annehmen wollte - aber ich denke, dass auch oben etwas übertrieben ist.

Andere Tipps

Das Schema hat aus Leistungsgründen keine erstklassigen Umgebungen. Als Schema erstellt wurde, war es aufgrund von raffinierten Dingen wie erstklassigen Funktionen, Kontinuationen usw. nicht die schnellste Sprache. Das Hinzufügen erstklassiger Umgebungen hätte die Leistung noch weiter verkrüppelt. Es war also ein Kompromiss, der in den frühen Tagen durchgeführt wurde.

Sie haben es so geschrieben, weil das MIT-Schema tatsächlich erstklassige Umgebungen hat und vermutlich die Autoren planten, ihre Klasse zu unterrichten (da das Buch am MIT geschrieben wurde).

Kasse http://groups.csail.mit.edu/mac/projects/scheme/

Ich habe jedoch festgestellt, dass das MIT -Schema, obwohl es immer noch etwas aktiv entwickelt wurde, viele der Merkmale fehlt, die ein wirklich modernes Schema haben würde, wie eine Fremdfunktions- oder GUI -Unterstützung. Sie möchten es wahrscheinlich nicht für ein ernstes Softwareentwicklungsprojekt verwenden, zumindest nicht für sich.

Würde ein klassischer Dispatcher funktionieren? Ich denke, das ähnelt dem, wonach Sie suchen.

(define (scientific-library f)
  (define (scientific-square-root x) (some-scientific-square-root x))
  (cond ((eq? f 'square-root) scientific-square-root)
        (else (error "no such function" f))))
(define (fast-library f)
  (define (fast-square-root x) (some-fast-square-root x))
  (cond ((eq? f 'square-root) fast-square-root)
        (else (error "no such function" f))))

((scientific-library 'square-root) 23)
((fast-library 'square-root) 23)

Sie können sogar die Beispiele für wissenschaftliche und schnelle Bibliotheken zu einer großen Versandmethode kombinieren:

(define (library l f)
  (define (scientific-library f)
    ...)
  (define (fast-library f)
    ...)
  (cond ((eq? l 'scientific) (scientific-library f))
        ((eq? l 'fast) (fast-library f))
        (else (error "no such library" l))))
(library 'fast 'square-root)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top