scala
DESCRIPTION
ScalaTRANSCRIPT
WstępO językuPrzykłady
BIWAK Scali
czyli Scala w domu i zagrodzie
Krzysztof GojKoło Naukowe Informatyków BIT
3 grudnia 2008
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala – flame
Lepsza Java
Haskell dla ludzi
Ruby, który nie muli
Procesy Erlanga na JVM
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala – flame
Lepsza Java
Haskell dla ludzi
Ruby, który nie muli
Procesy Erlanga na JVM
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala – flame
Lepsza Java
Haskell dla ludzi
Ruby, który nie muli
Procesy Erlanga na JVM
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala – flame
Lepsza Java
Haskell dla ludzi
Ruby, który nie muli
Procesy Erlanga na JVM
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala
Nazwa i logo
Obiektowo-funkcyjny język programowania wysokiegopoziomu i ogólnego przeznaczenia.
Zgodność z Javą, wersja na .NET
Elastyczna składnia pozwala na tworzenie DSL-i
Stworzona przez Martina Oderskiego (EPFL)
http://www.scala-lang.org
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala
Nazwa i logo
Obiektowo-funkcyjny język programowania wysokiegopoziomu i ogólnego przeznaczenia.
Zgodność z Javą, wersja na .NET
Elastyczna składnia pozwala na tworzenie DSL-i
Stworzona przez Martina Oderskiego (EPFL)
http://www.scala-lang.org
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala
Nazwa i logo
Obiektowo-funkcyjny język programowania wysokiegopoziomu i ogólnego przeznaczenia.
Zgodność z Javą, wersja na .NET
Elastyczna składnia pozwala na tworzenie DSL-i
Stworzona przez Martina Oderskiego (EPFL)
http://www.scala-lang.org
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala
Nazwa i logo
Obiektowo-funkcyjny język programowania wysokiegopoziomu i ogólnego przeznaczenia.
Zgodność z Javą, wersja na .NET
Elastyczna składnia pozwala na tworzenie DSL-i
Stworzona przez Martina Oderskiego (EPFL)
http://www.scala-lang.org
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala
Nazwa i logo
Obiektowo-funkcyjny język programowania wysokiegopoziomu i ogólnego przeznaczenia.
Zgodność z Javą, wersja na .NET
Elastyczna składnia pozwala na tworzenie DSL-i
Stworzona przez Martina Oderskiego (EPFL)
http://www.scala-lang.org
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
Czym jest Scala
Nazwa i logo
Obiektowo-funkcyjny język programowania wysokiegopoziomu i ogólnego przeznaczenia.
Zgodność z Javą, wersja na .NET
Elastyczna składnia pozwala na tworzenie DSL-i
Stworzona przez Martina Oderskiego (EPFL)
http://www.scala-lang.org
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” w shellu
Najprościej Scalę zmusić do mówienia pisząc w shellu.
shell
goj@abulafia ∼ % scalaWelcome to Scala version 2.7.1.final [...]Type in expressions to have them evaluated.Type :help for more information.
scala> println("Hello, World!")Hello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” w shellu
Najprościej Scalę zmusić do mówienia pisząc w shellu.
shell
goj@abulafia ∼ % scalaWelcome to Scala version 2.7.1.final [...]Type in expressions to have them evaluated.Type :help for more information.
scala> println("Hello, World!")Hello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” w shellu
Najprościej Scalę zmusić do mówienia pisząc w shellu.
shell
goj@abulafia ∼ % scalaWelcome to Scala version 2.7.1.final [...]Type in expressions to have them evaluated.Type :help for more information.
scala> println("Hello, World!")Hello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” w shellu
Najprościej Scalę zmusić do mówienia pisząc w shellu.
shell
goj@abulafia ∼ % scalaWelcome to Scala version 2.7.1.final [...]Type in expressions to have them evaluated.Type :help for more information.
scala> println("Hello, World!")Hello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” w shellu
Najprościej Scalę zmusić do mówienia pisząc w shellu.
shell
goj@abulafia ∼ % scalaWelcome to Scala version 2.7.1.final [...]Type in expressions to have them evaluated.Type :help for more information.
scala> println("Hello, World!")Hello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” w shellu
Najprościej Scalę zmusić do mówienia pisząc w shellu.
shell
goj@abulafia ∼ % scalaWelcome to Scala version 2.7.1.final [...]Type in expressions to have them evaluated.Type :help for more information.
scala> println("Hello, World!")Hello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako osobny program
najczęściej pisze się tak. . .
hello.scalaobject HelloWorld extends Application {println("Hello, world!")
}
shellgoj@abulafia ∼ % scalac hello.scalagoj@abulafia ∼ % lsHello.class Hello$.class hello.scalagoj@abulafia ∼ % scala -cp . HelloHello, World!goj@abulafia ∼ % java -cp .:$SCALA_HOME/lib/scala-library.jar HelloHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako skrypt
. . . można też pisać skrypty
script.sh#!/bin/shexec scala "$0" "$¨!#
object HelloWorld {def main(args: Array[String]) {println("Hello, World!")}}HelloWorld.main(args)
shellgoj@abulafia ∼ % chmod +x script.shgoj@abulafia ∼ % ./script.shHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako skrypt
. . . można też pisać skrypty
script.sh#!/bin/shexec scala "$0" "$¨!#
object HelloWorld {def main(args: Array[String]) {println("Hello, World!")}}HelloWorld.main(args)
shellgoj@abulafia ∼ % chmod +x script.shgoj@abulafia ∼ % ./script.shHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako skrypt
. . . można też pisać skrypty
script.sh#!/bin/shexec scala "$0" "$¨!#
object HelloWorld {def main(args: Array[String]) {println("Hello, World!")}}HelloWorld.main(args)
shellgoj@abulafia ∼ % chmod +x script.shgoj@abulafia ∼ % ./script.shHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako skrypt
. . . można też pisać skrypty
script.sh#!/bin/shexec scala "$0" "$¨!#
object HelloWorld {def main(args: Array[String]) {println("Hello, World!")}}HelloWorld.main(args)
shellgoj@abulafia ∼ % chmod +x script.shgoj@abulafia ∼ % ./script.shHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako skrypt
. . . można też pisać skrypty
script.sh#!/bin/shexec scala "$0" "$¨!#
object HelloWorld {def main(args: Array[String]) {println("Hello, World!")}}HelloWorld.main(args)
shellgoj@abulafia ∼ % chmod +x script.shgoj@abulafia ∼ % ./script.shHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako skrypt
. . . można też pisać skrypty
script.sh#!/bin/shexec scala "$0" "$¨!#
object HelloWorld {def main(args: Array[String]) {println("Hello, World!")}}HelloWorld.main(args)
shellgoj@abulafia ∼ % chmod +x script.shgoj@abulafia ∼ % ./script.shHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Czym jest ScalaHello, World!
“Hello, World!” jako skrypt
. . . można też pisać skrypty
script.sh#!/bin/shexec scala "$0" "$¨!#
object HelloWorld {def main(args: Array[String]) {println("Hello, World!")}}HelloWorld.main(args)
shellgoj@abulafia ∼ % chmod +x script.shgoj@abulafia ∼ % ./script.shHello, World!
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Fundamenty programowania funkcyjnego
Funkcje to zwykłe obiekty• Można je przekazywać jako argumenty do funkcji• Mogą być zwracane przez inne funkcje• Programujemy składając je na różne sposoby
Izolowanie efektów ubocznych• Niezmienność (immutability)• Programujemy tworząc nowe obiekty na podstawie starych,
a nie zmieniając istniejące
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Fundamenty programowania funkcyjnego
Funkcje to zwykłe obiekty• Można je przekazywać jako argumenty do funkcji• Mogą być zwracane przez inne funkcje• Programujemy składając je na różne sposoby
Izolowanie efektów ubocznych• Niezmienność (immutability)• Programujemy tworząc nowe obiekty na podstawie starych,
a nie zmieniając istniejące
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Fundamenty programowania funkcyjnego
Funkcje to zwykłe obiekty• Można je przekazywać jako argumenty do funkcji• Mogą być zwracane przez inne funkcje• Programujemy składając je na różne sposoby
Izolowanie efektów ubocznych• Niezmienność (immutability)• Programujemy tworząc nowe obiekty na podstawie starych,
a nie zmieniając istniejące
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Fundamenty programowania funkcyjnego
Funkcje to zwykłe obiekty• Można je przekazywać jako argumenty do funkcji• Mogą być zwracane przez inne funkcje• Programujemy składając je na różne sposoby
Izolowanie efektów ubocznych• Niezmienność (immutability)• Programujemy tworząc nowe obiekty na podstawie starych,
a nie zmieniając istniejące
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Fundamenty programowania funkcyjnego
Funkcje to zwykłe obiekty• Można je przekazywać jako argumenty do funkcji• Mogą być zwracane przez inne funkcje• Programujemy składając je na różne sposoby
Izolowanie efektów ubocznych• Niezmienność (immutability)• Programujemy tworząc nowe obiekty na podstawie
starych, a nie zmieniając istniejące
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Fundamenty programowania funkcyjnego
Funkcje to zwykłe obiekty• Można je przekazywać jako argumenty do funkcji• Mogą być zwracane przez inne funkcje• Programujemy składając je na różne sposoby
Izolowanie efektów ubocznych• Niezmienność (immutability)• Programujemy tworząc nowe obiekty na podstawie starych,
a nie zmieniając istniejące
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Fundamenty programowania funkcyjnego
Funkcje to zwykłe obiekty• Można je przekazywać jako argumenty do funkcji• Mogą być zwracane przez inne funkcje• Programujemy składając je na różne sposoby
Izolowanie efektów ubocznych• Niezmienność (immutability)• Programujemy tworząc nowe obiekty na podstawie
starych, a nie zmieniając istniejące
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Zalety programowania funkcyjnego
Skalowalność
Zwięzłość
Naturalny sposób opisu wielu problemów
Jest trędi–dżezi, kul, na topie
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Zalety programowania funkcyjnego
Skalowalność
Zwięzłość
Naturalny sposób opisu wielu problemów
Jest trędi–dżezi, kul, na topie
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Zalety programowania funkcyjnego
Skalowalność
Zwięzłość
Naturalny sposób opisu wielu problemów
Jest trędi–dżezi, kul, na topie
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Zalety programowania funkcyjnego
Skalowalność
Zwięzłość
Naturalny sposób opisu wielu problemów
Jest trędi–dżezi, kul, na topie
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Co to jest DSL?
Domain Specific Languages
Zewnętrzne (np. Make)
Wewnętrzne (np. Rake)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Co to jest DSL?
Domain Specific Languages
Zewnętrzne (np. Make)
Wewnętrzne (np. Rake)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Co to jest DSL?
Domain Specific Languages
Zewnętrzne (np. Make)
Wewnętrzne (np. Rake)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Co to jest DSL?
Wewnętrzny DSL w Scali — Specsobject helloWorld extends Specification {"’Hello, World!’ has 13 characters" in {"Hello, World!".size mustEqual 13
}"’Hello, World!’ matches /H.*W.*d.?/ regexp" in {"Hello, World!" must beMatching("H.*W.*d.?")
}
}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Scala a współbieżność
scala.actorsscala.concurrent
• scala.concurrent.pilib – rachunek π• scala.concurrent.jolib – join calculus• Lock, SyncChannel
Scala-STM (poza biblioteką standardową)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Scala a współbieżność
scala.actorsscala.concurrent
• scala.concurrent.pilib – rachunek π• scala.concurrent.jolib – join calculus• Lock, SyncChannel
Scala-STM (poza biblioteką standardową)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Scala a współbieżność
scala.actorsscala.concurrent
• scala.concurrent.pilib – rachunek π• scala.concurrent.jolib – join calculus• Lock, SyncChannel
Scala-STM (poza biblioteką standardową)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Scala a współbieżność
scala.actorsscala.concurrent
• scala.concurrent.pilib – rachunek π• scala.concurrent.jolib – join calculus• Lock, SyncChannel
Scala-STM (poza biblioteką standardową)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Scala a współbieżność
scala.actorsscala.concurrent
• scala.concurrent.pilib – rachunek π• scala.concurrent.jolib – join calculus• Lock, SyncChannel
Scala-STM (poza biblioteką standardową)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
Scala a współbieżność
scala.actorsscala.concurrent
• scala.concurrent.pilib – rachunek π• scala.concurrent.jolib – join calculus• Lock, SyncChannel
Scala-STM (poza biblioteką standardową)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
Programowanie funkcyjneElastyczna SkładniaInne
traity
pattern matching
składnia dla XML-a
inferencja typów
domknięcia funkcyjne
funkcje anonimowe
implicit conversions
implicit parameters
for comprehensions i monady
elastyczny system typów
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Przykłady
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
Haskellmap (1+) [1, 2, 3]
Ruby[1, 2, 3].map {|i| i+1}
Scheme (Lisp)(map (lambda (n) (1+ n)) ’(1 2 3))
Python[n+1 for n in [1, 2, 3]]
Erlanglists:map(fun(N) -> N+1 end, [1, 2, 3]).
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
Javaimport java.util.List;import java.util.ArrayList;import static java.util.Arrays.asList;
interface Function<Result, Arg> {public Result execute(Arg arg);
}
public class MapExample {public static<Result, Arg> List<Result> map(Function<Result, Arg> fn, Iterable<Arg> iter) {List<Result> result = new ArrayList<Result>();for (Arg i: iter)result.add(fn.execute(i));
return result;}
public static void main(String[] args) {map(new Function<Integer, Integer>() {public Integer execute(Integer i) {return i + 1;
}}, asList(1, 2, 3));
}}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
Scalaobject MapExample extends Application {def increase(n: Int): Int = {return n + 1;}Array(1, 2, 3).map(increase);}
Scala — którka funkcjaobject MapExample extends Application {def increase(n: Int): Int = n + 1;Array(1, 2, 3).map(increase);}
Scala — inferencja typówobject MapExample extends Application {def increase(n: Int) = n + 1;Array(1, 2, 3).map(increase);}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
Scalaobject MapExample extends Application {def increase(n: Int): Int = {return n + 1;}Array(1, 2, 3).map(increase);}
Scala — którka funkcjaobject MapExample extends Application {def increase(n: Int): Int = n + 1;Array(1, 2, 3).map(increase);}
Scala — inferencja typówobject MapExample extends Application {def increase(n: Int) = n + 1;Array(1, 2, 3).map(increase);}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
Scalaobject MapExample extends Application {def increase(n: Int): Int = {return n + 1;}Array(1, 2, 3).map(increase);}
Scala — którka funkcjaobject MapExample extends Application {def increase(n: Int): Int = n + 1;Array(1, 2, 3).map(increase);}
Scala — inferencja typówobject MapExample extends Application {def increase(n: Int) = n + 1;Array(1, 2, 3).map(increase);}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
to samo, co na poprzednim slajdziedef increase(n: Int) = n + 1;Array(1, 2, 3).map(increase);
funkcja anonimowaArray(1, 2, 3).map((n: Int) => n + 1);
dalsza inferencja typówArray(1, 2, 3).map(n => n + 1);
anonimowy argumentArray(1, 2, 3).map(_ + 1);
wygodna składniaArray(1, 2, 3) map (_ + 1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
to samo, co na poprzednim slajdziedef increase(n: Int) = n + 1;Array(1, 2, 3).map(increase);
funkcja anonimowaArray(1, 2, 3).map((n: Int) => n + 1);
dalsza inferencja typówArray(1, 2, 3).map(n => n + 1);
anonimowy argumentArray(1, 2, 3).map(_ + 1);
wygodna składniaArray(1, 2, 3) map (_ + 1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
to samo, co na poprzednim slajdziedef increase(n: Int) = n + 1;Array(1, 2, 3).map(increase);
funkcja anonimowaArray(1, 2, 3).map((n: Int) => n + 1);
dalsza inferencja typówArray(1, 2, 3).map(n => n + 1);
anonimowy argumentArray(1, 2, 3).map(_ + 1);
wygodna składniaArray(1, 2, 3) map (_ + 1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
to samo, co na poprzednim slajdziedef increase(n: Int) = n + 1;Array(1, 2, 3).map(increase);
funkcja anonimowaArray(1, 2, 3).map((n: Int) => n + 1);
dalsza inferencja typówArray(1, 2, 3).map(n => n + 1);
anonimowy argumentArray(1, 2, 3).map(_ + 1);
wygodna składniaArray(1, 2, 3) map (_ + 1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Na rozgrzewkę - map
to samo, co na poprzednim slajdziedef increase(n: Int) = n + 1;Array(1, 2, 3).map(increase);
funkcja anonimowaArray(1, 2, 3).map((n: Int) => n + 1);
dalsza inferencja typówArray(1, 2, 3).map(n => n + 1);
anonimowy argumentArray(1, 2, 3).map(_ + 1);
wygodna składniaArray(1, 2, 3) map (_ + 1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
takaSkładnia.setJestBrzydka(true)
Settery i getteryclass DateError extends Exceptionclass TimeOfDayVar {private var h, m, s: Int = 0def hours = hdef hours_= (h: Int) =if (0 <= h && h < 24) this.h = helse throw new DateError()// ...
}
def main(args: Array[String]) {val d = new TimeOfDayVard.hours = 8; d.minutes = 30; d.seconds = 0d.hours = 25 // throws a DateError exception}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Implicit Conversions
silniadef fact(n: Int): BigInt = if (n > 0) BigInt(n) * fact(n-1) else 1implicit def enrich(n: Int) = new {def !(): BigInt = fact(n)}
println(42!)
1405006117752879898543142606244511569936384000000000
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Implicit Conversions
silniadef fact(n: Int): BigInt = if (n > 0) BigInt(n) * fact(n-1) else 1implicit def enrich(n: Int) = new {def !(): BigInt = fact(n)}
println(42!)
1405006117752879898543142606244511569936384000000000
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
For Comprehensions
sprytne pętlefor (i <- 1 to 100 by 7) println(i)
for (i <- 1 to 100 by 7 if i % 3 == 0) println(i)
val numbers = for (i <- 1 to 100 by 7 if i % 3 == 0) yield i-1
odcukrzamy(1).to(100).by(7).foreach(println)
(1).to(100).by(7).filter(_ % 3 == 0).foreach(println)
val numbers = (1).to(100).by(7).filter(_ % 3 == 0).map(_-1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
For Comprehensions
sprytne pętlefor (i <- 1 to 100 by 7) println(i)
for (i <- 1 to 100 by 7 if i % 3 == 0) println(i)
val numbers = for (i <- 1 to 100 by 7 if i % 3 == 0) yield i-1
odcukrzamy(1).to(100).by(7).foreach(println)
(1).to(100).by(7).filter(_ % 3 == 0).foreach(println)
val numbers = (1).to(100).by(7).filter(_ % 3 == 0).map(_-1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
For Comprehensions
sprytne pętlefor (i <- 1 to 100 by 7) println(i)
for (i <- 1 to 100 by 7 if i % 3 == 0) println(i)
val numbers = for (i <- 1 to 100 by 7 if i % 3 == 0) yield i-1
odcukrzamy(1).to(100).by(7).foreach(println)
(1).to(100).by(7).filter(_ % 3 == 0).foreach(println)
val numbers = (1).to(100).by(7).filter(_ % 3 == 0).map(_-1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
For Comprehensions
sprytne pętlefor (i <- 1 to 100 by 7) println(i)
for (i <- 1 to 100 by 7 if i % 3 == 0) println(i)
val numbers = for (i <- 1 to 100 by 7 if i % 3 == 0) yield i-1
odcukrzamy(1).to(100).by(7).foreach(println)
(1).to(100).by(7).filter(_ % 3 == 0).foreach(println)
val numbers = (1).to(100).by(7).filter(_ % 3 == 0).map(_-1)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Opcje
Opcjeimport scala.collection.mutable.HashMapval numbers = HashMap(0 -> "nic", 1 -> "jedno", 2 -> "dwa")val rnd = new Random
numbers get rnd.nextInt(7) match {case Some(name) => println("To " + name)case None => println("Dużo")}
println(numbers get rnd.nextInt(7) map {_.capitalize + "!"}getOrElse "DUŻO!!!")
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
ScalaCheck — QuickCheck i więcej
ScalaCheckimport org.scalacheck._
object StringSpecification extends Properties("String") {specify("startsWith", (a: String, b: String) => (a+b).startsWith(a))
specify("endsWith", (a: String, b: String) => (a+b).endsWith(b))
// Is this really always true?specify("concat", (a: String, b: String) =>(a+b).length > a.length && (a+b).length > b.length)
specify("substring", (a: String, b: String) =>(a+b).substring(a.length) == b)
specify("substring", (a: String, b: String, c: String) =>(a+b+c).substring(a.length, a.length+b.length) == b)}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Traity
Trait orderedtrait Ordered[A] {def compare(that: A): Intdef < (that: A): Boolean = (this compare that) < 0def > (that: A): Boolean = (this compare that) > 0def <= (that: A): Boolean = (this compare that) <= 0def >= (that: A): Boolean = (this compare that) >= 0def compareTo(that: A): Int = compare(that)}
Użycieclass Sth(val a: Int) extends Ordered[Sth] {override def compare(other: Sth) = {val b = other.a(a*a) compare (b*b)}}val rnd = new Randomprintln(if (new Sth(-3) < new Sth(rnd nextInt 5)) "Yes" else "No")
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Traity
Trait orderedtrait Ordered[A] {def compare(that: A): Intdef < (that: A): Boolean = (this compare that) < 0def > (that: A): Boolean = (this compare that) > 0def <= (that: A): Boolean = (this compare that) <= 0def >= (that: A): Boolean = (this compare that) >= 0def compareTo(that: A): Int = compare(that)}
Użycieclass Sth(val a: Int) extends Ordered[Sth] {override def compare(other: Sth) = {val b = other.a(a*a) compare (b*b)}}val rnd = new Randomprintln(if (new Sth(-3) < new Sth(rnd nextInt 5)) "Yes" else "No")
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Domknięcia
Zapisvar counter = 0def bump_up() {counter += 1}
Odczytdef outer(a: Int): Int = {def helper(b: Int) = a * a - bhelper(4) + helper(a-1)}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Domknięcia
Zapisvar counter = 0def bump_up() {counter += 1}
Odczytdef outer(a: Int): Int = {def helper(b: Int) = a * a - bhelper(4) + helper(a-1)}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Domknięcia
Licznik — patologicznikdef mkCounter() = {var soFar = 0def counter(n: Int) = {soFar += nsoFar}counter _}
val cnt1 = mkCounter()val cnt2 = mkCounter()cnt1(1); cnt1(30)println(cnt1(11))println(cnt2(7))
wypisze 42 i 7
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
XML – tworzenie
XMLcase class Person(name: String, age: Int)class AddressBook(a: Person*) {private val people: List[Person] = a.toList
def toXHTML =<table class="XML"><tr><th>Last Name</th><th>First Name</th></tr>{ for (val p <- people) yield<tr><td>{ p.name }</td><td>{ p.age.toString }</td></tr>
}</table>;
}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
XML – wyszukiwanie 1/3
XMLdef understandFakt(note: scala.xml.Node): String = note match {case <murder>
<criminal><name>{murdererName}</name><age>{murderAge}</age></criminal><victim><name>{victimName}</name>{_*}</victim></murder> => "ZBRODNIA! " + murderAge + "-letni " +
murderAge + " zabił " + " " + victimNamecase <advert>{content}</advert> => "Kupuj " + contentcase _ => "prognoza pogody: będzie padać"}
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
XML – wyszukiwanie 2/3
XMLval stuff =<badStuff><newspapers><newspaper title="Nasz Dziennik">...</newspaper><newspaper title="NIE">...</newspaper><newspaper title="Fakt"><frontPage><advert>Fakt</advert><pogoda/></frontPage></newspaper></newspapers></badStuff>
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
XML – wyszukiwanie 3/3
XMLfor {val paper <- stuff \ "newspapers" \ "newspaper"paper.attributes("title") == "Fakt"val frontPage <- paper \\ "frontPage"val article <- frontPage child} println(understandFakt(article))
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – definicjaclass Stack[+A] {def push[B >: A](elem: B): Stack[B] = new Stack[B] {override def top: B = elemoverride def pop: Stack[B] = Stack.thisoverride def toString() = Stack.this.toString() +
" " + elem.toString()}def top: A = error("no element on stack")def pop: Stack[A] = error("no element on stack")override def toString() = ""}
hierarchia klas
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Kowariancja i dolna granica typu
Stos – użyciescala> :load examples/stack.scalaLoading examples/stack.scala...defined class Stack
scala> new Stackres0: Stack[Nothing] =
scala> res0 push "Ala" push "ma" push "kota"res1: Stack[java.lang.String] = Ala ma kota
scala> res1 popres2: Stack[java.lang.String] = Ala ma
scala> res2 push 0res3: Stack[Any] = Ala ma 0
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Hierarchia typów
stack.scala
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Funkcja
trait Function1[-T1, +R]
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Implicit Parameters
Powtórka z algebryabstract class SemiGroup[A] {def add(x: A, y: A): A}abstract class Monoid[A] extends SemiGroup[A] {def unit: A}implicit object StringMonoid extends Monoid[String] {def add(x: String, y: String): String = x concat ydef unit: String = ""}implicit object IntMonoid extends Monoid[int] {def add(x: Int, y: Int): Int = x + ydef unit: Int = 0}def sum[A](xs: List[A])(implicit m: Monoid[A]): A = (m.unit /: xs)(m.add)
println(sum(List(1, 2, 3)))println(sum(List("a", "b", "c")))
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Parser Combinators
Prosty Kalkulatorimport scala.util.parsing.combinator.lexical.StdLexicalimport scala.util.parsing.combinator.syntactical.StdTokenParsers
object arithmeticParser extends StdTokenParsers {type Tokens = StdLexical ; val lexical = new StdLexicallexical.delimiters ++= List("(", ")", "+", "-", "*", "/")
lazy val expr = term*("+" ^^^ {(x: Int, y: Int) => x + y}| "-" ^^^ {(x: Int, y: Int) => x - y})
lazy val term = factor*("*" ^^^ {(x: Int, y: Int) => x * y}| "/" ^^^ {(x: Int, y: Int) => x / y})
lazy val factor: Parser[Int] = "(" ~> expr <~ ")" |numericLit ^^ (_.toInt)
def eval(str: String) = expr(new lexical.Scanner(str))}
println(arithmeticParser.eval("4 * (5+5) + 8/4").get)
Krzysztof Goj BIWAK Scali
WstępO językuPrzykłady
rozgrzewkaciekawszeprzerażające
Parser Combinators
Prosty Kalkulatorimport scala.util.parsing.combinator.lexical.StdLexicalimport scala.util.parsing.combinator.syntactical.StdTokenParsers
object arithmeticParser extends StdTokenParsers {type Tokens = StdLexical ; val lexical = new StdLexicallexical.delimiters ++= List("(", ")", "+", "-", "*", "/")
lazy val expr = term*("+" ^^^ {(x: Int, y: Int) => x + y}| "-" ^^^ {(x: Int, y: Int) => x - y})
lazy val term = factor*("*" ^^^ {(x: Int, y: Int) => x * y}| "/" ^^^ {(x: Int, y: Int) => x / y})
lazy val factor: Parser[Int] = "(" ~> expr <~ ")" |numericLit ^^ (_.toInt)
def eval(str: String) = expr(new lexical.Scanner(str))}
println(arithmeticParser.eval("4 * (5+5) + 8/4").get)
Krzysztof Goj BIWAK Scali
Zakończenie Do poczytaniaDziękuję
Do poczytania
http://www.scala-lang.org
Blog Martina Oderskiego
Blog Daniela Spiewaka
Blog Jamesa Iry-ego
http://scala-blogs.org/
#scala na freenode
Slajdy (z linkami) będą nahttp://biwak-agh.blogspot.com/
Krzysztof Goj BIWAK Scali
Zakończenie Do poczytaniaDziękuję
Do poczytania
http://www.scala-lang.org
Blog Martina Oderskiego
Blog Daniela Spiewaka
Blog Jamesa Iry-ego
http://scala-blogs.org/
#scala na freenode
Slajdy (z linkami) będą nahttp://biwak-agh.blogspot.com/
Krzysztof Goj BIWAK Scali
Zakończenie Do poczytaniaDziękuję
Do poczytania
http://www.scala-lang.org
Blog Martina Oderskiego
Blog Daniela Spiewaka
Blog Jamesa Iry-ego
http://scala-blogs.org/
#scala na freenode
Slajdy (z linkami) będą nahttp://biwak-agh.blogspot.com/
Krzysztof Goj BIWAK Scali
Zakończenie Do poczytaniaDziękuję
Do poczytania
http://www.scala-lang.org
Blog Martina Oderskiego
Blog Daniela Spiewaka
Blog Jamesa Iry-ego
http://scala-blogs.org/
#scala na freenode
Slajdy (z linkami) będą nahttp://biwak-agh.blogspot.com/
Krzysztof Goj BIWAK Scali
Zakończenie Do poczytaniaDziękuję
Do poczytania
http://www.scala-lang.org
Blog Martina Oderskiego
Blog Daniela Spiewaka
Blog Jamesa Iry-ego
http://scala-blogs.org/
#scala na freenode
Slajdy (z linkami) będą nahttp://biwak-agh.blogspot.com/
Krzysztof Goj BIWAK Scali
Zakończenie Do poczytaniaDziękuję
Do poczytania
http://www.scala-lang.org
Blog Martina Oderskiego
Blog Daniela Spiewaka
Blog Jamesa Iry-ego
http://scala-blogs.org/
#scala na freenode
Slajdy (z linkami) będą nahttp://biwak-agh.blogspot.com/
Krzysztof Goj BIWAK Scali
Zakończenie Do poczytaniaDziękuję
Do poczytania
http://www.scala-lang.org
Blog Martina Oderskiego
Blog Daniela Spiewaka
Blog Jamesa Iry-ego
http://scala-blogs.org/
#scala na freenode
Slajdy (z linkami) będą nahttp://biwak-agh.blogspot.com/
Krzysztof Goj BIWAK Scali
Zakończenie Do poczytaniaDziękuję
Dobranoc!
Krzysztof Goj BIWAK Scali