In Cargo Shuffle hast du den Datenstapel von Factor und die Umsortierwörter kennengelernt, die ihn umordnen. Diese Übung baut darauf auf: Du definierst Wörter, die mit ihren Eingabewerten rechnen, statt sie nur hin- und herzuschieben.
Ein ! beginnt einen Zeilenkommentar. Factor ignoriert alles vom ! bis zum Zeilenende. Die folgenden Beispiele verwenden ! sowohl, um zu kommentieren, was der Code tut, als auch, um zu zeigen, was er ausgeben würde.
Ein Wort ist Factors Name für eine Funktion. Wenn du ein Wort aufrufst, nimmt es einige Werte vom oberen Ende des Stapels und legt einige Werte wieder zurück.
. nimmt den obersten Wert vom Stapel und gibt ihn aus; die Rechenwörter für Ganzzahlen +, -, * nehmen zwei Zahlen und legen das Ergebnis ab:
2 3 + . ! prints 5
8 3 - . ! prints 5 (8 - 3, not 3 - 8)
2 3 * . ! prints 6
Ein verwandtes Wort, .s, gibt den gesamten Datenstapel aus, ohne etwas zu verbrauchen. Das ist im Listener (Factors interaktive Eingabeaufforderung, in der du Code eintippst und Ergebnisse siehst) praktisch, um zu sehen, was ein Codeschnipsel hinterlässt. Deshalb enden spätere Beispiele manchmal mit .s statt mit .: Sie lassen mehr als einen Wert auf dem Stapel, und .s zeigt sie alle.
Die Rechenwörter leben im Vokabular math. Eine Datei, die sie verwendet, braucht daher math in ihrer USING:-Zeile.
Jedes Wort ist mit einem Stapeleffekt der Form ( inputs -- outputs ) dokumentiert. Er ist der Vertrag des Wortes: Das Wort nimmt die Eingabewerte vom oberen Ende des Stapels und hinterlässt die Ausgabewerte an ihrer Stelle. Die Namen darin sind nur dazu da, dir das Lesen zu erleichtern. Factor verwendet sie nicht. Er verfolgt nur die Reihenfolge, in der die Werte auf dem Stapel liegen.
! + is specified as ( x y -- sum )
! . is specified as ( x -- )
Das obere Ende des Stapels ist der rechte Eingabewert. Bei 8 3 - liegt also 3 oben, der Stapeleffekt ist ( x y -- difference ), und das Ergebnis ist 8 - 3.
Ein abschließendes ? bei den Ausgabewerten ist die Konvention für „ein boolescher Wert“, aber die Lasagne-Übung verwendet nur Zahlen.
Ein Umsortierwort aus Cargo Shuffle kommt weiter unten vor: swap ( x y -- y x ), das die obersten beiden Werte vertauscht, wenn sie für das nächste Wort in der falschen Reihenfolge liegen.
: beginnt eine Wortdefinition, danach folgt der Stapeleffekt, dann der Rumpf, und ; beendet sie.
: square ( x -- x^2 ) dup * ;
4 square . ! => 16
Der Compiler von Factor prüft, ob der Rumpf tatsächlich zum angegebenen Stapeleffekt passt: Ein Wort, das ( x -- y ) angibt, aber null oder zwei Werte auf dem Stapel hinterlässt, lässt sich nicht kompilieren.
CONSTANT: definiert einen Namen für einen festen Wert. Eine Konstante ist selbst ein Wort: Wenn du sie aufrufst, legt sie den Wert auf den Stapel:
CONSTANT: pi 3
pi pi * . ! => 9
CONSTANT: ist Kernsyntax und braucht keine USING:-Zeile. Setze Konstanten an den Anfang der Datei, vor jedes Wort, das sie verwendet.
Der Rumpf eines Wortes kann jedes Wort aufrufen, das bereits im Gültigkeitsbereich liegt, auch solche, die du früher in derselben Datei definiert hast:
: double ( x -- 2x ) 2 * ;
: quadruple ( x -- 4x ) double double ;
5 quadruple . ! => 20
So greift die letzte Aufgabe der Übung auf eine frühere zurück.
Wörter und Konstanten verwenden beide lowercase-kebab-case: Kleinbuchstaben, die durch Bindestriche verbunden sind (zum Beispiel expected-bake-time, preparation-time).
In dieser Übung schreibst du etwas Code, der dir hilft, eine großartige Lasagne aus deinem Lieblingskochbuch zu kochen.
Du hast vier Aufgaben, bei denen es um die Zeit geht, die du mit dem Kochen der Lasagne verbringst.
Definiere die Konstante expected-bake-time, die zurückgeben soll, wie viele Minuten die Lasagne im Ofen backen muss.
Laut Kochbuch muss die Lasagne insgesamt 40 Minuten im Ofen backen.
expected-bake-time .
! => 40
Definiere das Wort preparation-time. Es nimmt die Anzahl der Schichten, die du der Lasagne hinzugefügt hast, vom Stack und lässt die Anzahl der Minuten zurück, die du für die Zubereitung gebraucht hast. Dabei gehst du davon aus, dass die Zubereitung jeder Schicht 2 Minuten dauert.
4 preparation-time .
! => 8
Definiere das Wort remaining-time. Es nimmt die Anzahl der Minuten, die die Lasagne schon im Ofen war, vom Stack und lässt die Anzahl der Minuten zurück, die sie noch darin bleiben muss.
25 remaining-time .
! => 15
Definiere das Wort total-working-time. Es nimmt zwei Argumente vom Stack: zuerst die Anzahl der Schichten in der Lasagne, dann die Anzahl der Minuten, die die Lasagne bereits im Ofen war. Zurück lässt es die gesamte bisher zum Kochen aufgewendete Zeit, also die Zubereitungszeit plus die bereits im Ofen verbrachte Zeit.
3 20 total-working-time .
! => 26
Melde dich bei Exercism an, um Factor mit 47 Konzepte163 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.