Fehler beim Definieren im Racket

8

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

ersetze %Vor%

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

%Vor%

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

%Vor%

Ich weiß also nicht wirklich, was ich tun soll. Vielen Dank im Voraus!

    
SelectricSimian 25.04.2013, 17:45
quelle

4 Antworten

11

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:

%Vor%     
GoZoner 25.04.2013, 18:15
quelle
6

Wie GoZoner erklärt hat, können Sie define nicht in einem Ausdruckskontext verwenden.

Was können Sie stattdessen tun?

Verwenden Sie let :

%Vor%

Oder es würde mit einem "leeren" let und define funktionieren:

%Vor%

Aber das ist ein bisschen albern.

Oder verwenden Sie cond und define :

%Vor%

Dieser letzte Weg - mit cond und define - ist am ehesten dem, was aktueller Racket Style Guide wird empfohlen.

    
Greg Hendershott 25.04.2013 18:29
quelle
4

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.

    
stchang 25.04.2013 19:28
quelle
0

Oder Sie könnten die Ausdrücke umbrechen (beginnen) beispielsweise (beginnen   (Definieren x 10)   (Definieren Sie 100)   (Definieren Sie z 1000))

    
carrotzoe 11.11.2015 05:09
quelle