Scala. Co to za język?
- Scala została sklasyfikowana jako język funkcyjny, obiektowy, wielo-paradygmatyczny (mam nadzieję, że dobrze tłumaczę),
- statycznie i silnie typowany,
- obecna implementacja bazuje na JVM, niedługo można się spodziwać implementacji na .NET,
- tak!, Scala działa na platformie Java, więc ma dostęp do całego ekosystemu bibliotek Javy,
- nietuzinkową postacią jest sam twórca języka Martin Odersky, który jest współautorem obecnego kompilatora Javy oraz jest współprojektantem obecnych typów generycznych w Javie,
- jest to młody język programowania i posiada wiele ciekawych własności, o których to będę pisał w kolejnych postach,
- więcej: Scala na Wikipedii, strona domowa Scali, wywiad z twórcą języka.
OK, wezmę na warsztat prostą czynność: wypisanie elementów z listy.
Kod w Javie byłby następujący:
JAVA:
-
List<Integer> lista = new ArrayList<Integer>() {{
-
add(1); add(2); add(3); add(4);
-
}};
-
-
-
-
-
-
// Można też tak, ale raczej nie bym nie polegał na metodzie toString()
-
System.
out.
println(lista.
toString());
-
-
// lub po prostu:
-
Dla odmiany w Ruby'im zrobilibyśmy to tak:
RUBY:
-
# tutaj akurat mamy tablicę
-
lista = %w(1, 2, 3, 4)
-
-
# żeby ładnie było to definiujmy println
-
println = lambda { |x| puts x }
-
-
lista.each &println
Zobaczmy teraz, jak zrobilibyśmy to w Scali.
SCALA:
-
val lista = List(1, 2, 3, 4)
-
-
lista.foreach((x: Int) => println(x))
Brzydko... idziemy dalej. Scala jest językiem funkcyjnym, który ma mechanizm currying. Opuśćmy deklarację typu i nawiasy.
SCALA:
-
lista.foreach(x => println(x))
Nadal brzydko... idziemy dalej. Co jest argumentem metody foreach? Sygnatura metody jest następująca:
SCALA:
-
def foreach(f: A => Unit): Unit
Na potrzebę chwili traktujmy Unit tak samo jak void. Zatem argumentem foreach jest funkcja, która przyjmuje argument A (jakiś nieustalony typ, patrz: currying) i zwraca Unit. Natomiast println jest zdefiniowany tak:
SCALA:
-
def println(x: Any) = Console.println(x)
czyli bierze jakiś argument (nadal patrz: currying, funkcje wyższego rzędu) i zwraca Unit. Zatem typy się zgadzają. Zapiszmy to krócej:
Już lepiej, ale można jeszcze lepiej :). Scala ma bardzo fajną własność, którą nigdzie wcześniej nie spotkałem. Mianowicie w Scali technicznie nie ma operatorów. Wyrażenie 1 + 2 jest tożsame z wywołaniem metody 1.+(2). Jeśli metoda przyjmuję tylko jeden parametr to można pominąć nawiasy oraz kropkę. Zatem:
Piękny zapis, nieprawdaż?
A czy twój ulubiony język zrobi to lepiej?