• Skip to main content
  • Skip to primary sidebar

Mark Goldenstein

  • Blog
  • Über mich
  • Impressum
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy

jvm

Saturday, 5. January 2013 by Mark Goldenstein 4 Comments

Scala vs Java: weniger Code, mehr Inhalt

Scala ist eine Programmiersprache, die weitgehend unter dem Radar geblieben ist und im Unternehmensumfeld nur sehr langsam Fuß fasst.[1]im Dezember 2012 war sie nur auf Platz 34 des TIOBE Index, mit 0,32% im Vergleich zu Java auf Platz 2 mit 17,57% Zu unrecht wie ich finde, denn zum einen bietet Scala viele Möglichkeiten für einen Produktivitätsgewinn, zum anderen ist die Sprache 100%ig mit bestehenden Java Bibliotheken und Anwendungen kompatibel und läuft ebenfalls in der Java Virtual Machine (JVM).

Was sind also die wichtigsten Vorteile von Scala? Ich habe drei aus meiner Sicht herausragende Features ausgesucht, die ich im Weiteren näher beschreiben werde.

Funktionale Programmierparadigmen

Scala unterstützt alle objektorientierten Features von Java, bietet darüber hinaus aber auch viele Möglichkeiten, die sonst lediglich funktionale Programmiersprachen wie z.B. Lisp erlauben. Dies ermöglicht einen sehr prägnanten Programmierstil und führt direkt zu einer besseren Code-Verständlichkeit und -Qualität.

Experience with Scala shows that it typically takes one half to one third of the lines of code to express the same application as Java yet executes at about the same speed.[2]http://www.scala-lang.org/node/3069

Im Folgenden werde ich dieses Argument verdeutlichen. Zunächst ein Beispiel einer sogenannten for-Comprehension. For comprehensions ähneln den for loops aus Java, sind jedoch ein deutlich mächtigeres Werkzeug. So erlauben sie unter anderem, eine neue Collection durch die Iteration über eine bestehende zu erstellen (ähnlich zu den aus Python bekannten list comprehensions).[3]mehr zu dem Thema hier: http://www.scala-lang.org/node/111

Scala
1
2
3
4
// berechnet alle natürlichen Teiler einer Zahl
def factorsOf(number: Int) = for (i <- 1 to number if number % i == 0) yield i
 
factorsOf(42) // Ergebnis: Vector(1, 2, 3, 6, 7, 14, 21, 42)

Im folgenden Beispiel verwende ich eine Funktion als Filter – es werden nur diejenigen Elemente der Liste gezählt, die die übergebene Bedingung erfüllen: Ein Aufruf von factorsOf auf das Element soll einen Vector der Länge 2 zurückgeben.

Scala
1
2
3
4
5
6
// gibt die Anzahl der Primzahlen in einer Liste zurück
// Primzahlen haben exakt zwei natürliche Teiler: 1 und sich selbst
def countPrimeNumbersIn(list: List[Int]) = list.count(factorsOf(_).size == 2)
 
val range = 1 to 10 // Ergebnis: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
countPrimeNumbersIn(range.toList) // Ergebnis: 4

Programmiere ich hingegen in Java, so würde die gleiche Logik zu folgendem Code führen:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static List<Integer> factorsOf(int number) {
  List<Integer> result = new ArrayList<Integer>();
  for (int i = 1; i <= number; i++) {
    if (number % i == 0)
      result.add(i);
  }
  return result;
}
 
public static int countPrimeNumbersIn(List<Integer> list) {
  int count = 0;
  for (int x : list) {
    if (factorsOf(x).size() == 2)
      count += 1;
  }
  return count;
}
 
public static void main(String[] args) {
  List<Integer> list = new ArrayList<Integer>();
  for (int i = 1; i <= 10; i++) {
    list.add(i);
  }
  countPrimeNumbersIn(list); // Ergebnis: 4
}

Die Methoden factorsOf und countPrimeNumbersIn, die zuvor prägnant in einer Zeile definiert waren, benötigen nun jeweils acht(!) Zeilen. In Java verschwindet die Logik also hinter Code-Bausteinen (boilerplate). Mit wachsender Code-Komplexität wächst auch der Wartungsaufwand der bereits vorhandenen Codebasis, sodass die Reduzierung von Code-Bausteinen mithilfe von Scala nicht nur die Sichtbarkeit der eigentlichen Logik erhöht, sondern auch die Software-Wartung vereinfacht und damit zu weniger Fehlern führt. Algorithmen, die mithilfe von Scalas for-comprehensions und maps programmiert wurden, lassen sich nachweislich etwa 30% schneller verstehen als solche mit Javas iterativen while-Schleifen.[4]http://www.scala-lang.org/node/3069

Scala DSLs

Nein, damit ist nicht der Breitbandanschluss gemeint, sondern DSL steht für Domain Specific Languages. Dieses Scala Feature ermöglicht es Software-Entwicklern eigene Sprachkonstrukte zu definieren, die sich nahtlos in die Programmiersprache eingliedern. Das vereinfacht die Enwicklung und verschafft auch Nicht-Programmierern die Möglichkeit, den Code zu verstehen. Im Folgenden ist ein Beispiel, wie Tests mithilfe der populären Library ScalaTest definiert werden können. Auffallend ist die sich selbst erklärende Syntax sowie die Prägnanz der Testfälle: Es sind keine Code-Bausteine nötig.

Scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class GoogleSearchSpec extends FlatSpec with ShouldMatchers with HtmlUnit {
 
  "The blog app home page" should "have the correct title" in {
    go to (host + "index.html")
    title should be ("Awesome Blog")
  }
  "The search page" should "have ten results" in {
    click on "searchbox"
    textField("searchbox").value = "Scala"
    submit()
    findAll(className("result")).size should be (10)
    capture to "search.png"
  }
}

In Java hingegen sind durch die Programmiersprache klare Grenzen gesetzt, solche Konstrukte lassen sich da nicht realisieren. Im Gegensatz zu den entsprechenden Testfällen in JUnit kommen die ScalaTest-Fälle mit deutlich weniger Code aus. Auf den direkten Vergleich mit JUnit werde ich in diesem Fall verzichten, denn dann wäre dieser Post mit Bildschirm füllenden Code-Bausteinen überladen.

Traits: Interfaces on Steroids

Oberflächlich gesehen entsprechen Scalas Traits den Interfaces aus Java; mit einem wichtigen Unterschied: Traits können Methoden nicht nur deklarieren, sondern auch bereits implementierte Methoden beinhalten.

“Das ist ja nichts Anderes als eine abstrakte Klasse!”, wird sich der mit Java erfahrene Leser nun vielleicht denken. Das stimmt so allerdings nicht. Während eine Klasse in Java lediglich von einer einzigen anderen (abstrakten) Klasse erben kann, können Klassen in Scala beliebig viele Traits einbinden. Das ist praktisch, weil dadurch die Implementierungen von mehrfach verwendeten Methoden an einem einzigen Ort (dem Trait) auftauchen, und nicht über verschiedene Klassen redundant verteilt werden müssen. Beispiel:

Scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// eine Klasse, die einen Bruch darstellt und Operatoren
// zum Vergleich mit anderen Brüchen bereitstellt
class Rational(n: Int, d: Int) {
  // numer ist der Zähler, denom der Nenner
  // ...
  def < (that: Rational) =
    this.numer * that.denom > that.numer * this.denom
  def > (that: Rational) = that < this
  def <= (that: Rational) = (this < that) || (this == that)
  def >= (that: Rational) = (this > that) || (this == that)
}
 
// Vereinfachung mithilfe des Ordered Traits: die Methoden
// "<", ">", "<=" und ">=" werden vom Trait implementiert
class Rational(n: Int, d: Int) extends Ordered[Rational] {
  // ...
  def compare(that: Rational) =
    (this.numer * that.denom) - (that.numer * this.denom)
}

In Java hingegen ist es nicht möglich in einem Interface Methoden zu implementieren.

Heute setzen bereits Twitter, Foursquare und LinkedIn auf Scala. Nach Daten von indeed.com, ist die Nachfrage nach Scala-Entwicklern seit 2010 rapide gestiegen. Es lohnt sich also diese Programmiersprache im Auge zu behalten.

Notes   [ + ]

1. ↑ im Dezember 2012 war sie nur auf Platz 34 des TIOBE Index, mit 0,32% im Vergleich zu Java auf Platz 2 mit 17,57%
2, 4. ↑ http://www.scala-lang.org/node/3069
3. ↑ mehr zu dem Thema hier: http://www.scala-lang.org/node/111

Filed Under: German Tagged With: java, jvm, scala

Primary Sidebar

Categories

  • English
  • German

Recent Posts

  • Spotify and others use an unfair formula to pay artists
  • Building a Websocket client to btcwallet using Scala and akka
  • Complex Event Processing: Language-level integration into Scala
  • 2nd Next Generation Forum Roundup
  • Präsentation 2.0 – es muss nicht immer PowerPoint sein

Recent Comments

  • Mark Goldenstein on Building a Websocket client to btcwallet using Scala and akka
  • Julio on Building a Websocket client to btcwallet using Scala and akka
  • Mark Goldenstein on Building a Websocket client to btcwallet using Scala and akka
  • Julio on Building a Websocket client to btcwallet using Scala and akka
  • Julio on Building a Websocket client to btcwallet using Scala and akka

Copyright © 2021 · Executive Pro on Genesis Framework · WordPress · Log in