Scala w Notatkach #1

W ramach poszerzania horyzontów postanowiłem przyjrzeć się bliżej różnym językom programowania dla JVM. Jest ich trochę - trzeba więc było coś wybrać, coby umysłu nie narażać na zbyt wielkie męki. Zwycięzcami krótkiej rywalizacji są: Scala oraz Groovy. Zaopatrzony w Programming in Scala oraz Groovy in action przystąpiłem do dzieła z solennym postanowieniem, że zrobię na blogu własne notatki prezentujące ciekawe właściwości owych języków.

Pierwsza w kolejce jest Scala.

Czy jest Scala? Wg autora ww książki jest to statycznie typowany obiektowo-funkcyjny język programowania, który "skaluje się" wraz ze wzrostem potrzeb programisty. Brzmi ciekawie i takie jest! Skalowanie to polega m.in. na tym, że w Scali można np. definiować własną składnię, która być może lepiej (zwięźlej) oddaje nasze intencje niż ogólne konstrukcje języka (oczywiście jest to zagadnienie zaawansowane, do którego dojdziemy pewnie dużo później). Ponadto Scala nadaje się zarówno do pisania krótkich skryptów (dzięki bardzo zwięzłej formie, charakterystycznej dla języków skryptowych), jak i dużych aplikacji.

A jak jest z funkcyjnością i obiektowością? Właściwie ciężko stwierdzić, czy Scala jest bardziej obiektowa, czy może bardziej funkcyjna. To co mi się podoba w Scali to nienarzucanie programiście żadnego z tych podejść. Np. ja znając Javę wolę uczyć się Scali po obiektowemu i z czasem odkrywać jej funkcyjną naturę. Miłośnicy Erlanga czy Haskella być może woleliby odwrotną drogę. Piękne jest to, że te dwa światy żyją obok siebie i z każdego możemy wziąć to, co jest w danej sytuacji najwygodniejsze.

Scala jest językiem programowania dla JVM, co oznacza ni mniej ni więcej jak tylko tyle, że wynikowy kod to bytecode, dokładnie taki sam jaki produkują kompilatory Javy. Podobnie też używa się narzędzi do kompilacji i odpalania.

Kompilacja:

Java: javac plik
Scala: scalac plik

Uruchamianie:

Java: java pakiet.Klasa
Scala: scala pakiet.Klasa

Dodatkowo w scali istnieje coś takiego, jak rezydentny kompilator, który przyspiesza kompilację:
Java: nie znam niczego takiego (kto zna?)

Scala: fsc 

Prosty przykład - wypisanie listy argumentów

Plik Application.java:

package com.jcake.scala;
    public class Application {
        public static void main(String[] args) {
            for (String arg : args) {
                System.out.println(arg);
            }
      }
}

Plik Application.scala

package com.jcake.scala
object Application {
        def main(args:Array[String]) : Unit = {
                for (arg <- args) {
                        println(arg)
                }
        }
}

Co się różni - jak na razie niewiele, tzn, nie na tyle dużo, żeby Javowiec się nie połapał o co chodzi:

  • zamiast public class mamy object - object jest w Scali słowem kluczowym oznaczającym, że jest to singleton,
  • brakuje static w metodzie main - w Scali po prostu nie ma czegoś takiego, jak static, jest za to wspomniany singleton, czyli object,
  • brakuje void w metodzie main - w skali nie ma czegoś takiego jak void, jest za to Unit - znaczy to samo, ale jest obiektem,
  • kolejność deklaracji jest zamieniona w stosunku do Javy. W Javie mamy najpierw typ, potem zmienną lub metodę, w Scali najpierw jest zmienna, a potem, po dwukropku typ, - trzeba się przyzwyczaić i już,
  • pętla for jest bardzo podobna (to tylko pozory, ale o tym kiedy indziej),
  • w Scali średnik jest opcjonalny,

Linii wyszło tyle samo więc jak na razie szału nie ma (zresztą nie walczymy o mniej linii, bo to nie Perl...). Popatrzmy jednak na to:

package com.jcake.scala
object Application {
        def main(args:Array[String]) {
                args.foreach(arg => println(arg));
        }
}

Znikła pętla for, zniknął zwracany typ, a program nadal działa. Okazuje się, że:

  • jeśli metoda nie zwraca żadnej interesującej wartości to można :Unit pominąć,
  • jeśli pominiemy zwracany typ wycinamy również "=",
  • pętlę for możemy zamienić na coś bardziej zwięzłego, czyli na domknięcie (ang. closure),
  • tablica w Scali ma znacznie więcej metod niż ta znana z Javy, m. in. foreach, dlatego łatwiej się z nimi pracuje.

To może jeszcze sprawę uprośćmy:

package com.jcake.scala
object Application {
        def main(args:Array[String]) {
                args.foreach(println(_));
        }
}

Co się stało? Usunęliśmy parametr z domknięcia, zastępując go domyślnym parametrem _. Świetnie! Dla mnie (ex perlowca) bomba!

A coś takiego?:

package com.jcake.scala
object Application {
        def main(args:Array[String]) {
                args.foreach { println _ }
        }
}

Tu już jest trochę czarów:

  • Usunęliśmy nawiasy okrągłe z foreach oraz z println,
  • Umieściliśmy domknięcie w nawiasach klamrowych.

Jak widać panuje tu pewna dowolność w stosowaniu nawiasów. Osobiście wolę jednak stosować nawiasy, żeby mniej się potem domyślać podczas czytania kodu.

Przykład może krótki, ale i tak udało się sporo pokazać.

W następnym odcinku: typy i deklarowanie zmiennych oraz metod.

Comments

Opcje przeglądania komentarzy

Wybierz preferowany sposób wyświetlania komentarzy i klinij na "Zapisz ustawienia", aby aktywować zmiany.
jzabiello's picture

Odpowiednik fsc

Odpowiednikiem fsc dla Javy może być Nailgun

sliwa.andrzej's picture

pomijanie nawiasów

Hej,

Co do dowolności w stosowaniu nawiasów, to nie jest tak do końca, jak by mogło z twojego wpisu wynikać. Można pominąć nawiasy tylko w przypadku gdy jest jeden parametr
przekazywany do metody, jak również typ parametru zgadza się z oczekiwanym.

Natomiast kwestia wildcard'a "_" wymaga wiecej uwagi, bo jest on wykorzystywany
zarówno przy importach, jak i domknieciach, jak również przy match'erach gdzie pokazuje swoją siłę w parametrycznym rozpoznawaniu Typów (połączonym np z case classes) w zależności od użytych paremtrów.

Andrzej
andrzejsliwa.com

ant's picture

spoko, spoko, nie wszystko

spoko, spoko, nie wszystko na raz - do tych zagadnień dojdziemy za kilka notatek.

Cudo - scalowanie jot-de-enu ;-)

Wspaniale, że zająłeś się tematem Scali. Mogę więc działać na dwa fronty - tutaj ze Scalą i u siebie z Grailsami, czyli Groovy. Upiekę dwie pieczenie na jednym ogniu! Bosko!

Warto również zajrzeć do Bonera, który ostatni rok spędził przy projekcie ze Scalą - http://jonasboner.com/2008/10/01/real-world-scala-introduction.html.

Słyszy się trochę o Scali i Haskelu, więc widać, że idzie era języków funkcyjnych (których wartości nigdy nie poczułem, więc może przyszła pora!). Zdaje się, że Wiktor Gworek też coś kiedyś pisał o Scali. O mam - http://blog.mocna-kawa.com/category/scala/. Szybko jednak ucichł. Niestety :(

Jacek
Notatnik Projektanta Java EE