W Function representation in Scala trafiłem na:
val add:(Int, Int) => Int = (x,y) => x + ypodczas gdy większość przykładów, które do tej pory napotkałem definiowały funkcję jak poniżej:
def add(x: Int, y: Int): Int = x + yNiby nic odkrywczego, ale przywołały mi różnicę między funkcjami a symbolami (aka vars), które wskazują na funkcje w Clojure. W programowaniu funkcyjnym funkcje są pierwszej kategorii, więc można je przypisywać, akceptować na wejściu do funkcji i zwracać jako wyjście. Dokładnie tak, jak ma to miejsce w Javie z obiektami, co pozwala nazwać Javę obiektowym językiem.
Również w Thread: Code in book as transcript in REPL pojawiła się ciekawa cecha Scala REPL:
scala> scala> println("Hello, World!")
// Detected repl transcript paste: ctrl-D to finish.
Hello, World!
// Replaying 1 commands from transcript.
scala> println("Hello, World!")
Hello, World!Wystarczy wkleić dowolną kombinację powyższych linii i REPL wykryje, że wkleiliśmy kawałek kodu, który był prezentowany jako wynik działania REPL. Użyteczna cecha scalowego REPLa. Trochę pokręcone przy próbie wytłumaczenia, więc zachęcam do samodzielnego popróbowania się z tym.Jeszcze trafiłem na słówko lazy, które jak łatwo było się domyśleć ma służyć opóźnieniu wykonania obliczenia.
scala> lazy val a = 4 + 4 a: Int = <lazy> scala> a res13: Int = 8Nie spędziłem specjalnie wiele czasu na poszukiwania i poprzestanę na poniższym, aby uzmysłowić leniwe obliczenie.
scala> lazy val b = { println("Ala ma kota"); }
b: Unit = <lazy>
scala> b
Ala ma kotaGdyby usunąć lazy wykonanie przypisania będzie wykonane natychmiast i wyświetli się napis "Ala ma kota", tak jak wykonanie b z lazy powyżej.Na zakończenie, czytając player/winner typo, zwróciłem uwagę na
if (p1.score > p2.score) declareWinner(p1) else declareWinner(p2)które powtarza wywołanie funkcji declareWinner. Sądzę, że możnaby zamienić to na reduce. W Clojure już mam, pracuję nad wersją w Scali. Może ktoś pomoże?
Poniżej kod w Clojure. Uzmysławia stosowanie mapy jako jednej z podstawowych struktur danych (coś ala javowy obiekt) oraz map i reduce - filary programowania funkcyjnego w Clojure.
$ lein2 repl
nREPL server started on port 55072
Welcome to REPL-y!
Clojure 1.3.0
Exit: Control+D or (exit) or (quit)
Commands: (help)
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
(sourcery function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Examples from clojuredocs.org:
(clojuredocs name-here)
(clojuredocs "ns-here" "name-here")
nil
user=> (def players {:p1 10 :p2 20 :p3 15 :p4 8 :p5 2})
#'user/players
user=> (defn pme [me] [(me 0) (me 1)])
#'user/pme
user=> (map pme players)
([:p1 10] [:p3 15] [:p2 20] [:p4 8] [:p5 2])
user=> (defn >me [me1 me2]
(if (> (val me2) (val me1)) me2 me1))
#'user/>me
user=> (reduce >me players)
[:p2 20]
user=> (defn declareWinner [[name score]]
(format "Player %s won (score: %s)" name score))
#'user/declareWinner
user=> (declareWinner
(reduce >me players))
"Player :p2 won (score: 20)"Proszę pytać, jak coś niejasne. Chętnie udzielę odpowiedzi.

Śledzę sobie Twoje zmagania ze Scalą.
OdpowiedzUsuńJeśli chodzi o drugą definicję add, to zwracam uwagę, że to nie jest funkcja tylko metoda. To nie to samo. Funkcje są wartościami, a metody nie są.
Ponadto może Cię zainteresują inne jeszcze definicje:
val add = (x:Int,y:Int) => x + y
val add:(Int, Int) => Int = _ + _
val add = (_:Int) + (_:Int)
object add { def apply(x:Int, y:Int) = x+y }
val add = new Function2[Int,Int,Int] { def apply(x:Int, y:Int) = x+y }
Grzegorz
Jeszcze reduce:
OdpowiedzUsuńval players = Map( 'p1 -> 10, 'p2 -> 20, 'p3 -> 15, 'p4 -> 8, 'p5 -> 2 )
players.reduce{(a,b) => if(a._2 > b._2) a else b}
Grzegorz