Blog

Tipps und Tricks für die Scala REPL (nur Trunk)

Arjan Blokzijl

Aktualisiert Oktober 23, 2025
6 Minuten

Der Weg zum Erlernen von Scala führt in der Regel über die REPL. Dies ist eine sehr praktische Methode, um Funktionen, die Sie schreiben, einfach und schnell auszuprobieren, ohne eine ganze IDE-Umgebung einrichten zu müssen. Die neueste stabile Version von Scala ist Scala 2.7.5. Scala 2.8 wird in ein paar Monaten erscheinen, so wie es jetzt aussieht. Diese neue Version wird eine Reihe von Verbesserungen und neuen Funktionen enthalten, und wenn Sie es nicht abwarten können, sollten Sie den Stamm auschecken und verwenden. Ich habe bereits in einem früheren Blog über den Einstieg in Scala berichtet und auch angedeutet, dass Sie dies ausprobieren sollten. In diesem Blog zeige ich Ihnen einige konkretere Beispiele für die und ein paar nette Dinge, die Sie tun können, wenn Sie bereit sind, diesen Schritt zu tun.

Holen Sie sich den Trunk Um den Trunk zu verwenden, können Sie entweder die Quellen auschecken und ihn selbst bauen oder die nächtlichen Builds verwenden. Wahrscheinlich haben Sie eine SCALA_HOME-Umgebungsvariable gesetzt. Zeigen Sie also einfach auf den neu erstellten Build und starten Sie die REPL. Wenn alles gut gegangen ist, sollten Sie etwas wie das Folgende sehen:

Willkommen bei Scala Version 2.8.0.r18341-b20090718103640 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_14).
Geben Sie Ausdrücke ein, damit sie ausgewertet werden.
Geben Sie :help ein, um weitere Informationen zu erhalten.
scala>

Wenn Sie den Stamm verwenden, können Sie als erstes von der neu gestalteten und verbesserten Scala-Sammlungsbibliothek profitieren. Sie wurde in großem Umfang neu gestaltet, größtenteils von Martin Odersky selbst. Sie wurde eingecheckt und befindet sich schon seit einiger Zeit im Stamm, so dass Sie bei der Verwendung des Stammes den Vorteil haben, mit ihr zu arbeiten. Die neue API wird im Scala Improvement Proposal erläutert, einer ausgezeichneten und unverzichtbaren Lektüre für das Verständnis des Designs der Scala-Sammlungen. Verwendung der überarbeiteten REPL Paul Phillips löst nicht nur einen Fehler nach dem anderen im Stamm, er hat auch die Angewohnheit, die REPL regelmäßig aufzumotzen. Ein sehr nettes Feature ist die Code-Vervollständigung, sehr praktisch, wenn Sie nicht die komplette Scala-API im Kopf haben. Definieren Sie zunächst eine Variable und drücken Sie nach der Eingabe der Variable (und möglicherweise des Beginns einer Funktion) die Tabulatortaste:

scala>  val l = Liste(1,2,3)
l: List[Int] = List(1, 2, 3)
scala>  l
AbstractStringBuilder Annotation Appendable Anwendung
Array AssertionStatusDirektiven BigDecimal BigInt
Boolean Byte Zelle CharSequence
Zeichen ZeichenDaten00 ZeichenDaten01 ZeichenDaten02
CharacterData0E CharacterDataLatin1 CharacterDataPrivateUse CharacterDataUndefined
Klasse ClassLoader ClassfileAnnotation Cloneable
Vergleichbarer Compiler ConditionalSpecialCasing Konsole
CountedIterator Abgelehnt Double Either
Enum Aufzählung Equiv Float
Fractional Function GenericRange Unveränderlich
InheritableThreadLocal Integer Integral Iterable
Links Long Math Mutable
Keine NotNull Zahl Numerisch
Objekt Option Geordnete Bestellung
Überschreiben Sie Package PartialFunction PartialOrdering
PartiallyOrdered Predef Process ProcessBuilder
ProzessUmgebung ProzessImpl Produkt Proxy
Bereich RangeToString Lesbarer Antwortgeber
Right Runnable Runtime RuntimePermission
ScalaObject SecurityManager SerialVersionUID Kurz
Herunterfahren Einige StackTraceElement StaticAnnotation
StrictMath String StringBuffer StringBuilder
StringCoding SuppressWarnings Symbol System
SystemClassLoaderAction Terminator Thread ThreadDeath
ThreadGroup ThreadLocal Throwable TypeConstraint
UNIXProzess Unhashable EinzigartigkeitCache Void
Schauspieler Annotation ch klonbar
Kollektion com compat concurrent
dbc veraltetes Inline-Instrument
io java javax jline
l Management mobil nativ
net noinline org Paket
ref reflect remote runtime
scala serialisierbare Einstellungen spezialisiert
sun sunw swing testing
text wirft tools transient
ungeprüft unversiegelt util flüchtig
xml
scala>  l.zip
zip zipAll zipWithIndex

Ziemlich klasse. Aber das ist noch nicht alles: Die trunk REPL enthält jetzt einen Poweruser-Modus:

scala>  :Hilfe
Alle Befehle können abgekürzt werden - zum Beispiel :h oder :he anstelle von :help.
:help gibt diese Hilfemeldung aus.
:jar fügen Sie ein jar zum Klassenpfad hinzu.
:load gefolgt von einem Dateinamen lädt eine Scala-Datei.
:power aktivieren Sie den Poweruser-Modus.
:quit verlässt den Interpreter.
:replay setzt die Ausführung zurück und gibt alle vorherigen Befehle wieder.
:silent deaktivieren/aktivieren Sie den automatischen Druck der Ergebnisse.
scala>  :power
** Power User Modus aktiviert - BEEP BOOP **
** Neue Vals! Versuchen Sie den Interpreter.  **
** Neue Definitionen! Versuchen Sie mkType("T", "String") ** 
** Neue cmds! :Hilfe, um sie zu entdecken ** 
:help gibt diese Hilfemeldung aus.
:jar fügen Sie ein jar zum Klassenpfad hinzu.
:load gefolgt von einem Dateinamen lädt eine Scala-Datei.
:power aktivieren Sie den Poweruser-Modus.
:quit verlässt den Interpreter.
:replay setzt die Ausführung zurück und gibt alle vorherigen Befehle wieder.
:silent deaktivieren/aktivieren Sie den automatischen Druck der Ergebnisse.
:dump zeigt einen Überblick über den internen Zustand des Interpreters.
:tree zeigt ASTs für bestimmte Bezeichner an.

Lassen Sie uns das einmal ausprobieren. Mit mkType können wir einen Typ-Alias definieren, genau wie in Haskell:

scala>  mkType("IntList", "Liste[Int]")
definierter Typ alias IntList
res3: scala.tools.nsc.InterpreterResults.Result = Erfolg
scala>  val il: IntList = Liste("1", "2", "3")
:5: Fehler: Typ-Fehlanpassung;
  gefunden : java.lang.String("1")
  erforderlich: Int
  val il: IntList = Liste("1", "2", "3")
scala>  val il:IntList = Liste(1,2,3,4)
il: IntList = Liste(1, 2, 3, 4)
scala>  il.foldLeft(0)(_+_)
res5: Int = 10

Funktioniert einwandfrei. Als Nächstes zeigt der Befehl :tree einige AST für Klassen und Funktionen an, die Sie definiert haben, falls Sie daran interessiert sind:

scala>  def sum(a: Int)(b: Int)(c: Int) = a + b + c
Summe: (a: Int)(b: Int)(c: Int)Int
scala>  :Baumsumme
def sum(a: Int)(b: Int)(c: Int) = a.$plus(b).$plus(c) (DefDef)

Und nicht zuletzt können wir die neuen, innovativen Funktionen von Scala nutzen. So bietet Scala beispielsweise eine begrenzte Unterstützung für die Anwendung von Tail-Call-Optimierungen zur Kompilierungszeit. Die Feststellung, ob der Compiler diese Optimierung tatsächlich durchführt, kann jedoch eine knifflige Angelegenheit sein. Wenn Sie dies nutzen, aber nicht sicher sind, ob eine Funktion, die Sie geschrieben haben, tatsächlich vom Compiler optimiert wird, können Sie jetzt die @tailrec-Annotation verwenden. Zum Beispiel (das Beispiel stammt aus dem Buch Programming in Scala) ist die unten gezeigte boom-Funktion wegen der increment-Funktion am Ende nicht tail-rekursiv. Die Funktion bang hingegen schon. [scala] import scala.annotation.tailrec class Tails { @tailrec def boom(x: Int): Int = { if (x == 0) throw new Exception("boom!") else boom(x-1)+ 1 } @tailrec def bang(x: Int): Int = { if (x == 0) throw new Exception("bang!") else bang(x-1) [/scala] } } Wenn Sie die @tailrec-Annotation für beide verwenden, gibt der Compiler den folgenden Fehler aus:

:8: Fehler: konnte die mit @tailrec annotierte Methode nicht optimieren
  @tailrec def boom(x: Int): Int = {
  ^
:13: Fehler: konnte die mit @tailrec annotierte Methode nicht optimieren
  @tailrec def bang(x: Int): Int = {

Auf den ersten Blick etwas verwirrend, da wir für beide Methoden Kompilierungsfehler erhalten, während wir ziemlich sicher waren, dass die Methode bang schwanzrekursiv sein sollte. Dies lässt sich jedoch durch die Tatsache erklären, dass die Methode bang in einer Klasse als public und nicht final definiert ist. Das bedeutet, dass sie in einer Unterklasse überschrieben werden könnte, wodurch die Optimierung des Tail-Calls verhindert wird. Feinheiten wie diese machen diese Annotation wirklich sehr nützlich. Wenn wir die Klasse in ein Objekt umwandeln (für das Methoden nicht überschrieben werden können) und die @tailrec-Annotation aus der Boom-Methode entfernen, lässt sich alles problemlos kompilieren.Für weitere Erkundungen von Tail Calls und Trampolinen in Scala ist der Blog von Rich Dougherty eine gute Anlaufstelle. Schauen Sie sich auch die Klasse TailRec von Scala an, die im Stamm verfügbar ist. Ich habe noch nicht alle neuen Funktionen in Scala 2.8.0 behandelt, aber einen grundlegenden Überblick finden Sie hier. Schauen Sie es sich an und genießen Sie es.

Verfasst von

Arjan Blokzijl

Contact

Let’s discuss how we can support your journey.