Ich habe Racket vor ein paar Tagen entdeckt, und ich versuche, mich damit vertraut zu machen, indem ich ein kleines Skript schreibe, das Bilder erzeugt, die Quellcode mit #lang slideshow
darstellen.
Ich weiß, dass es bei der Programmierung in einem funktionalen Paradigma praktisch ist, fast alle Variablen mit let
zu erstellen, aber ich finde, dass es zu viele Ebenen der Verschachtelung gibt und dass Racket's eine überkomplizierte API hat, die überflüssige Klammern benötigt. Ich bin mir sicher, dass damit Mehrdeutigkeiten beseitigt werden, wenn let
auf leistungsfähigere Weise verwendet wird, aber für meine Zwecke ist es nur ein Ärgernis. Folglich erstelle ich alle meine Variablen mit define
und schreibe Blöcke mit begin
, wenn es nötig ist (wie im Körper einer if
-Anweisung).
Das Problem ist, dass ich immer wieder scheinbar sehr mysteriöse Fehler bekommen habe. Ich bin mir sicher, ich mache nur einen dummen Anfängerfehler, bin neu in der Sprache, aber ich kann wirklich nicht die Quelle der Beschwerde finden.
Hier ist der anstößige Code:
%Vor% obwohl das, was wir sub-code
definieren, ziemlich irrelevant erscheint. Wenn ich es durch
Ich erhalte den gleichen Fehler. DrRacket sagt, dass define
in einem Ausdruck Kontext verwendet wird. Ich verstehe, was dieser Fehler normalerweise bedeuten würde - IE, dass es erhöhen würde, wenn Sie Code wie (print (define x 10))
schreiben, aber ich kann nicht sehen, was es hier auslösen würde.
Wenn es hilft, steht define
am Anfang eines begin
-Blocks, innerhalb einer if
-Anweisung
Die spezifische Fehlermeldung, die DrRacket druckt, ist
%Vor% Ich dachte, dass define
in begin
blocks nicht erlaubt ist, aber ich habe die Dokumente und eines der Beispiele für begin
ist
Ich weiß also nicht wirklich, was ich tun soll. Vielen Dank im Voraus!
Definitionen sind in einem 'body'-Kontext erlaubt, wie in lambda
und let
unter anderen. Die Folge- und Alternativsätze von if
sind keine Körperkontexte; Sie sind Ausdruckkontexte und deshalb sind Definitionen nicht erlaubt.
begin
ist speziell - begin
in einem Body-Kontext erlaubt Definitionen, aber begin
in einem Ausdruck Kontext verbietet Definitionen. Ihr Fall fällt auf den späteren.
Zum Beispiel:
%Vor% Syntaktische Schlüsselwörter, die Ausdrücke benötigen: if, cond, case, and, or, when, unless, do, begin
. Überprüfe die formale Syntax in jedem Scheme-Bericht (r {4,5,6,7} rs); Suchen Sie nach <body>
, <sequence>
, <command>
und <expression>
.
Wenn Sie einen body-Kontext in einem Ausdruck benötigen, können Sie auch ein let
syntaktisches Formular wie folgt umschließen:
Wie GoZoner erklärt hat, können Sie define
nicht in einem Ausdruckskontext verwenden.
Was können Sie stattdessen tun?
Verwenden Sie let
:
Oder es würde mit einem "leeren" let
und define
funktionieren:
Aber das ist ein bisschen albern.
Oder verwenden Sie cond
und define
:
Dieser letzte Weg - mit cond
und define
- ist am ehesten dem, was aktueller Racket Style Guide wird empfohlen.
Hier finden Sie weitere Details aus der Racket-Dokumentation.
Die verschiedenen Kontexte sind erforderlich, da Makros unterschiedlich expandieren müssen, je nachdem, welche Sprachen erlaubt sind.
Wie andere bereits gesagt haben, sind Definitionen in Ausdruckskontexten ("expr ..." in den Dokumenten) nicht erlaubt, aber in anderen Kontexten sind sie in Ordnung.
In anderen doc-Einträgen bedeutet "body ..." einen internen Definitionskontext ( Leitfaden , reference ), zum Beispiel in Lambda-Bodies, und" form ... "zeigt alle Nicht-Ausdruck-Kontexte an, wie in den Dokumenten für begin.
Tags und Links functional-programming expression scheme lisp racket