Pokazywanie postów oznaczonych etykietą fp. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą fp. Pokaż wszystkie posty

29 maja 2013

giter8 i sbt - pierwsze kroki przy tworzeniu projektów ze Scalą

0 komentarzy
Zawsze zastanawiało mnie, jak rozpocząć pracę z językiem Scala z linii poleceń. Potrzebowałem mechanizmu, który utworzyłby mi katalog na potrzeby projektu w Scali, z odpowiednio ułożonymi podkatalogami na kody źródłowe samej aplikacji oraz jej testów.

giter8 - narzędzie tworzenia plików i katalogów na podstawie szablonów w GitHub

Był czas, kiedy żyłem w błogiej niewiedzy istnienia Scala Build Tools (sbt). Potrzebowałem narzędzia do zarządzania projektem - budowania go z pobraniem zależnych bibliotek, kompilacją, wykonaniem testów, itp. To właśnie zadanie dla sbt.

Wszystkie znaki na niebie i ziemi mówiły mi, że ostatnią rzeczą, jaką robi sbt, to utworzenie nowego projektu z właściwą strukturą katalogową. Okazało się, że sbt jest na tyle "wyrafinowane", że potrafi pracować z każdą strukturą katalogów, co w zasadzie powinno mnie cieszyć, ale przy mojej niewiedzy, tylko komplikowało sprawę. Skąd miałbym wiedzieć, jak rozłożyć pliki źródłowe aplikacji, aby było dobrze, jeśli...wszystko może być dobrze (czy właśnie nie odpowiedziałem sobie na to pytanie?)

To zapewne był powód odpalenia projektu giter8 (w skrócie g8). Już nie pamiętam, kto mi go wskazał, ale to miało być rozwiązaniem moich bolączek. I faktycznie było.

"Giter8 is a command line tool to generate files and directories from templates published on github or any other git repository. It's implemented in Scala and runs through the Simple Build Tool launcher, but it can produce output for any purpose."

Instalacja opisana jest na stronie Installation. Jej zakończenie obwieszcza uruchomienie g8.
$ g8

giter8 0.5.3
Usage: g8 [TEMPLATE] [OPTION]...
Apply specified template.

OPTIONS
    -b, --branch
        Resolves a template within a given branch
    --paramname=paramvalue
        Set given parameter value and bypass interaction.


Apply template and interactively fulfill parameters.
    g8 n8han/giter8

Or
    g8 git://github.com/n8han/giter8.git

Apply template from a remote branch
    g8 n8han/giter8 -b some-branch

Apply template from a local repo
    g8 file://path/to/the/repo

Apply given name parameter and use defaults for all others.
    g8 n8han/giter8 --name=template-test

g8 typesafehub/scala-sbt - Scala sbt template

I co teraz?

W Usage do g8, napisano: "Template repositories must reside on github and be named with the suffix .g8. We're keeping a list of templates on the wiki." I to cieszy, że komuś zależy i zebrał pomocne szablony w jednym miejscu!

Właśnie dzisiaj trafiłem na projekt Scala sbt template, który jest "A giter8 template for Scala projects using sbt."

Skoro należy do repozytorium projektów Typesafe Inc., to można założyć, że jest projektem błogosławionym przez samych twórców Scali (niekoniecznie gwarancja jakości, ale chociaż aktualności). Coś mi jednak mówi, że ostatnia zmiana "authored a year ago" nie jest specjalnie obiecująca w kontekście aktualności projektu. Ale co robić?

Odpalam g8 typesafehub/scala-sbt i korzystam wstępnie z projektu.
$ g8 typesafehub/scala-sbt

Scala Project Using sbt

organization [org.example]: pl.japila
name [Scala Project]:
scala_version [2.9.2]: 2.10.1
version [0.1-SNAPSHOT]:

Template applied in ./scala-project

jacek:~/sandbox
$ cd scala-project/
jacek:~/sandbox/scala-project
$ tree
.
├── README
├── project
│   └── ScalaProjectBuild.scala
└── src
    └── main
        └── scala
            └── pl
                └── japila
                    └── ScalaProject.scala

6 directories, 3 files
$ cat README
A sample for the Typesafe Stack (http://typesafe.com/stack).

Scala sample project using Scala and SBT.

To run and test it use SBT invoke: 'sbt run'

jacek:~/sandbox/scala-project
$ sbt run
[info] Loading project definition from /Users/jacek/sandbox/scala-project/project
[info] Updating {file:/Users/jacek/sandbox/scala-project/project/}default-9e49ab...
[info] Resolving org.scala-sbt#precompiled-2_10_0;0.12.2 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/jacek/sandbox/scala-project/project/target/scala-2.9.2/sbt-0.12/classes...
[info] Set current project to Scala Project (in build file:/Users/jacek/sandbox/scala-project/)
[info] Updating {file:/Users/jacek/sandbox/scala-project/}scala-project...
[info] Resolving org.scala-lang#scala-library;2.10.1 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/jacek/sandbox/scala-project/target/scala-2.10/classes...
[info] Running pl.japila.ScalaProject
Hello, Scala Project
[success] Total time: 13 s, completed May 29, 2013 10:08:54 PM
"Hello, Scala Project" oraz "success" na końcu dają mi pewne poczucie spełnienia moich oczekiwań. Mam swój pierwszy projekt w Scali z udziałem g8!

g8 kobmic/plain-scala

Jeszcze na koniec swojej wyprawy w świat uruchomienia projektów scalowych z g8 przeszukałem sieć i trafiłem na kobmic/plain-scala. Wydaje się być świeższą i bardziej kompletną alternatywą do szablonu z Typesafe.

Projekt scala-project idzie do kosza i odpalam g8 kobmic/plain-scala.
jacek:~/sandbox
$ g8 kobmic/plain-scala

Plain Scala project with scalatest and/or specs2

version [0.1.0-SNAPSHOT]:
organization [my.organization]: pl.japila
name [MyScalaProject]:

Template applied in ./myscalaproject
I już widzę miejsce do poprawy w szablonie - nazwa tworzonego projektu jest bez (ostatnio ulubionych) myślników.

Kontynuuję prace...
jacek:~/sandbox
$ cd myscalaproject
jacek:~/sandbox/myscalaproject
$ tree
.
├── build.sbt
├── project
│   └── plugins.sbt
└── src
    ├── main
    │   └── scala
    │       └── Stub.scala
    └── test
        └── scala
            ├── StubSpec.scala
            └── StubTest.scala

6 directories, 5 files
Tym razem stawiam na pisanie testów do mojego wymyśl(o)nego projektu w Scali. Stąd też powód uruchomienia sbt test.

// pół pobranego Internetu później...
jacek:~/sandbox/myscalaproject
$ sbt test
[info] Loading project definition from /Users/jacek/sandbox/myscalaproject/project
[info] Set current project to MyScalaProject (in build file:/Users/jacek/sandbox/myscalaproject/)
[info] StubTest:
[info] you description here
[info] - should do something
[info] StubSpec
[info]
[info] The 'Hello world' string should
[info] + contain 11 characters
[info] + start with 'Hello'
[info] + end with 'world'
[info]
[info]
[info] Total for specification StubSpec
[info] Finished in 27 ms
[info] 3 examples, 0 failure, 0 error
[info]
[info] Passed: : Total 4, Failed 0, Errors 0, Passed 4, Skipped 0
[success] Total time: 4 s, completed May 29, 2013 10:57:20 PM
W Usage projektu można przeczytać, że odpalenie sbt eclipse lub sbt gen-idea pozwala na łatwiejsze wczytanie projektu do ulubionego IDE. Wybieram IntelliJ IDEA.

22 maja 2013

Czego i jak się uczyć funkcyjnej Scali - relacja z wystąpienia na deskach Warszawa JUG

4 komentarzy
To było moje pierwsze, deklarowane wystąpienie na deskach grupy Warszawa JUG, w którym kładłem nacisk na materiały i techniki poznawania nowego obszaru niż na samym obszarze. Programowanie funkcyjne i Scala były jedynie nośnikami, a nie meritum sprawy. I właśnie w chwili, kiedy ruszałem na spotkanie, na Ursynowie zerwało chmurę. Lało tak mocno, jakby ktoś się zawziął i postanowił nie wypuścić mnie z klatki (dosłownie i w przenośni). Istne oberwanie chmury. Nie zapowiadało się dobrze.

Miałem niemałe obawy, czy formuła mojego wystąpienia wpasuje się w oczekiwania uczestników. Z jednej strony utożsamiany jestem z tematami technicznymi (powstrzymam się od poprzedzenia ich "wysoko"), a z drugiej strony wiele osób pyta "Czego i jak się uczyć?". Postanowiłem spróbować swoich sił w prezentacji moich sposobów na efektywną naukę.

Przed spotkaniem miałem możliwość zamienić słowo z kilkoma, wcześniej nieznanymi mi osobami, które tylko wzmogły we mnie obawy o tematyce mojej prezentacji - bardziej zależało im na samej nauce Scali niż na metodach, które mogłyby w tym pomóc. I coś mi mówi, że niepotrzebnie się wsłuchiwałem w głos tłu...gawie...uczestników, bo tylko przysporzyło mi więcej nerwów niż pewności siebie. Bywa.

I zaczęło się!

Najpierw wystąpienie sponsora spotkania - firmy Decerto (również znani jako "Systemy informatyczne dla biznesu") - w osobie Tomka Kucharskiego. Dzięki Tomek za miłe słowa o mojej osobie i chwilę, w której mogłem ochłonąć (z komentarzy), ale tytuły, którymi mnie "obrzuciłeś", jeszcze bardziej wzbudziły we mnie niepokój.

Liczba uczestników i komentarze nie pozostawiały złudzeń, że musi być technicznie.


Nie było. A przynajmniej nie w mierze, która mogłaby zadośćuczynić oczekiwaniom publiczności. Bywa. Prezentacja na SlideShare a nagranie niebawem. Sugeruję obserwować forum Warszawa JUG.

Dziękuję Agnieszce, Michałowi, Jankowi, Stefanowi, Piotrowi, Julkowi, Pawłowi i pozostałym uczestnikom za podjęcie się trudu uatrakcyjnienia spotkania przez udział w dyskusjach podczas niego, czy po prostu podejście do mnie, aby przywitać się i zamienić słowo. Uścisk dłoni, bezcenne!(TM) Byłem zaszczycony móc Was gościć na moim spotkaniu i poznać Was wszystkich osobiście.

Komentarze dotyczące mojego wystąpienia znajdziesz na stronie spotkania na Meetupie. Zachęcam do komentowania i wyrażania swoich pozytywnych oraz krytycznych uwag. Niech kolejne, moje wystąpienia publiczne staną się lepsze (czytaj: dopasowane do oczekiwań uczestników, co niekoniecznie oznacza, że faktycznie będą lepsze :-))

Dziękuję wszystkim za udział. Jednocześnie zachęcam do dzielenia się własnym warsztatem poznawczym, abyśmy stali się społecznością, w której rodzą się ciekawe pomysły (zamiast naśladować czy uczyć się innych). Wciąż zdecydowanie "wynalazczości" wśród nas. Wszystko pro publico bono!

p.s. Właśnie wpadłem na ciekawy pomysł prezentacji - "Poznaję Scalę rozwiązując zagadki z Project Euler". Można również pokusić się o uruchomienie prezentacji w stylu kata z pomysłami z Any practical coding dojo/kata ideas? Kto chciałby wziąć udział w takim pomyśle - jako organizator, (współ)prowadzący czy uczestnik? Ciekawym Twojej opinii.

09 maja 2013

Funkcyjny maj na Coursera, Atmosphere Conference, GeeCON, Warszawa JUG oraz JEEConf

6 komentarzy
Z tygodnia na tydzień zadania w szkoleniu Functional Programming Principles in Scala w serwisie szkoleniowym Coursera stają się boleśnie trudniejsze. Coraz częściej przekraczają moje możliwości intelektualne i cierpi moja dusza (ego) oraz ciało (z powodu przeciągającego się niedostatku snu).

Ale się nie poddaję! Dam radę i ostatnie wyniki są obiecujące - już gwarantują, że za zadanie z tygodnia 6 o anagramach, w którym należy wyznaczyć wszystkie anagramy podanego zdania, otrzymam co najmniej 8,46 na 10 możliwych. Została już tylko jedna funkcja do implementacji i będę w domu. Może nawet wcześniej w łóżku!

Brakuje mi najbardziej, aby z kimś pogadać na temat programowania funkcyjnego w Scali, ale nie odpuszczam również Clojure (i rzadziej F#). Język zaczyna mieć mniejsze znaczenie, bo zależy mi najbardziej na pełnym przyswojeniu myślenia funkcyjnego. Scala, Clojure czy F# to jedynie zestaw słów, którymi mogę wyrazić "zdania" funkcyjne.

I w nadchodzący poniedziałek, 13 maja, pojawię się w Poznaniu na konferencji Atmosphere Conference 2013 z tematem Functional web development with Git(Hub), Heroku and Clojure. Temat niespecjalnie rozwijany od ostatniego mojego wystąpienia z nim podczas łódzkiej konferencji Przyszłość w IT (właśnie przez "wtopienie" ze Scalą na Courserze). Wierzę jednak, że wiedza z alternatywnego języka Scala wzbogaci tę o Clojure, co sprawi, że poziom merytoryczny wystąpienia będzie wysoki. Ciekawym komentarzy po.

Z Poznania udaję się 15 maja do Krakowa na GeeCON 2013, w trakcie którego zamierzam kontynuować mój rozwój w kontekście programowania funkcyjnego. Poza udziałem w kilku prezentacjach o Scali i Clojure, dzięki uprzejmości organizatorów poprowadzę panel dyskusyjny Functional Programming - radical thinking shift and step towards clearer and reliable software. Kiedyś już uczestniczyłem w panelu jako mówca (z twórcą Spring Framework - Rod'em Johnson'em, James'em Strachan'em oraz Ted'em Neward'em w roli moderatora), a teraz przyszło mi się zmierzyć z trudniejszą rolą - moderowaniem panelu z udziałem znawców tematu programowania funkcyjnego. To 17 maja. Liczę na pomoc, bo animowanie dyskusji bez zainteresowania nią wśród uczestników może być kolejnym (majowym) wyzwaniem.

Później na chwilę wracam do Warszawy, aby 21 maja wystąpić na deskach grupy Warszawa JUG z tematem Moje pierwsze kroki w programowaniu funkcyjnym w Scali. Nie widzę go jeszcze opublikowanego na stronie grupy, ale wstępnie mam akceptację grupy organizatorów cyklicznych spotkań, więc spodziewam się ogłoszenia niebawem. Zachęcam do udziału, bo liczę na aktywny udział obu stron - prowadzącego oraz słuchaczy - co powinno wyjść na dobre każdemu. Na pewno pomoże w zrozumieniu chociażby kilku problemów funkcyjnych, z którymi borykałem się podczas kursu Odersky'ego na Coursera, warsztatów Grześka Balcerka oraz lektury Functional Programming in Scala.

A pod koniec tygodnia, 24 i 25 maja, pojawię się w Kijowie na konferencji JEECOnf. Tam zdobędę się na wystąpienie o Clojure (Introduction to web application development in Clojure) i Scali (Introduction to functional programming in Scala). Jednocześnie o obu językach? Tego jeszcze nie było w moim wykonaniu! Nie mogłem odmówić sobie spróbowania, bo okazja do bezpośredniej wymiany doświadczeń nie zdarza się często. Będzie z pewnością bogato merytorycznie, bo w końcu będę mógł podjąć się wyjaśnienia pewnych problemów programistycznych przez pryzmat języków Java, Clojure, a teraz i Scala. Ciekawym, kiedy do mojego repertuaru dołączy F#?!

Do zobaczenia!

29 października 2012

Różnica między wyrażeniem a wyrażeniem (instrukcją)

3 komentarzy
Istnieje różnica między wyrażeniem a wyrażeniem. Jaka?! - zapytasz? Natychmiast idzie to wyłapać przy przejściu na język angielski, w którym mamy dwa różne słowa odpowiadające pojedynczemu w polskim - "expression" oraz "statement" (aczkolwiek dla tego drugiego Google Translator wskazuje na "oświadczenie" czy "deklaracja" przed "wyrażenie").

Jeśli pracujesz z językami imperatywnymi, np. Java, w których króluje "statement" i/lub językami funkcyjnymi, np. Scala lub Clojure, w których prym wiedzie "expression", warto znać różnicę. Przyznaję, że mi to trochę zajęło (zajęcia na studiach jakoś tak wtedy nużyły).

Niby oczywista jest ta różnica, ale nie wszyscy ją wyłapują. U mnie długo trwało zanim zaskoczyło. "expression" zawsze zwraca wartość i jest jej reprezentantem, a "statement" może, ale nie musi i zwykle stosowany jest dla skutków ubocznych, np. przypisanie częściowego wyliczenia do zmiennej poza nim, np. pętla for w Javie.

Od tej chwili usilnie próbuję zapamiętać, że w językach funkcyjnych korzystamy wyłącznie z "wyrażeń", podczas gdy w imperatywnych również i "instrukcji" (patrz Wikipedia w Instrukcja (informatyka) w sekcji Wyrażenia).

I już nie mam problemów ze wskazaniem wyrażenia od instrukcji. A nawet w tłumaczeniu!

Dla zwrócenia uwagi, posłużę się kawałkami kodu w Clojure.

If jest specjalną formą (= wyrażeniem) w Clojure (w przeciwieństwie do Javy) i działa na podobieństwo funkcji, które można przypisywać (aliasować), przekazywać do czy zwracać z funkcji.
user=> ; przypisanie
user=> (def if-inside
  #_=>   (if nil "nil jest prawda" "nil nie jest prawda"))
#'user/if-inside
user=> if-inside
"nil nie jest prawda"

user=> ; przekazanie do funkcji
user=> (defn my-fn [if-stmt]
  #_=>   if-stmt)
#'user/my-fn
user=> (my-fn if-inside)
"nil nie jest prawda"

user=> ; zwrocenie z funkcji
user=> (defn my-fn-returns-if-stmt [if-stmt]
  #_=>   (fn [] if-stmt))
#'user/my-fn-returns-if-stmt
user=> (my-fn-returns-if-stmt if-inside)
#<user$my_fn_returns_if_stmt$fn__3525 user$my_fn_returns_if_stmt$fn__3525@2304a962>
user=> ((my-fn-returns-if-stmt if-inside))
"nil nie jest prawda"
Proste, co?

A może jednak nie? Pytaj, aby było! Mówią, że to podstawy podstaw programowania funkcyjnego i brak zrozumienie fundamentów może negatywnie "promieniować" na dalszą znajomość jego.

30 kwietnia 2012

Wywołanie funkcji w Scali inaczej

1 komentarzy
Podczas lektury Different ways of calling functions w artykule Use functional programming techniques to write elegant JavaScript z 13 czerwca 2006 trafiłem na dosyć ciekawe wywołanie funkcji, którego wcześniej nie miałem przyjemności poznać.


$ scala
Welcome to Scala version 2.10.0-M2 (OpenJDK 64-Bit Server VM, Java 1.8.0-jdk8-b35).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val f = (x:Int, s:String) => s*x
f: (Int, String) => String = <function2>

scala> f(2, "a")
res0: String = aa

scala> (f) (2, "a")
res1: String = aa

scala> ((x:Int, s:String) => s*x) (2, "a")
res2: String = aa
Jeszcze nie wiem, gdzie i dlaczego chciałbym z tego skorzystać, ale moja głowa prawie eksplodowała z wrażenia! Czy to, aby nie ma związku z częściowym wywołaniem funkcji (ang. currying)?!

Po kwadransie, w którym główkowałem wciąż nad tematem...

Już wiem! Nie ma znaczenia, czy korzystam z symbolu funkcyjnego czy definicji funkcji anonimowej, która przez przypisanie do symbolu staje się nieanonimowa, owe wykonanie powyżej, w każdym przypadku po prostu wywoła funkcję. Ostatni przykład to właśnie prezentuje. Takie zagadki językowe lubię.

29 kwietnia 2012

Definiowanie symboli przez val w Scali - wartości również jako funkcje

0 komentarzy
Za 1.3 Wartości niezmienne:

"Za pomocą słowa kluczowego val można w języku Scala definiować wartości niezmienne."

Wartością może być znana programistom Javy liczba, napis lub referencja.
scala> val n = 10
n: Int = 10
Na uwagę zasługuje sposób, w jaki interpreter przedstawia wartość - n: Int = 10. Spróbuję skorzystać z tej wiedzy, aby zdefiniować n ponownie.
scala> val n: Int = 10
n: Int = 10
Być może istnieją inne sposoby deklarowania wartości, ale dla mnie wystarczy składnia
val [symbol] : [typ] = [wartość]
Za [symbol] mogę podstawić własną nazwę - identyfikator lub jak to nazywa się w Clojure - symbol. Następnie mamy [typ] i później przypisanie [wartość].

I teraz najlepsze, wartością [wartość] może być również funkcja. To jest istotna różnica między Javą a Scalą.

Moje (niewielkie) doświadczenie z F# pozwoliło mi przyswoić już sobie składnię deklaracji funkcji z symbolem implikacji =>. Po jednej stronie mamy typ danych wejściowych, a po drugiej wyjściowych. Po znaku przypisania składnia podobna, ale już definiujemy ciało funkcji, a nie jej sygnaturę (pojęcia użyte luźno, więc proszę purystów językowych o wyrozumiałość).
scala> val f:Int => Int = x => x * 3
f: Int => Int = <function1>
Proste, nieprawdaż? Wywołanie funkcji f pozostawiam Wam do samodzielnego rozgryzienia (podpowiedź: jak w Javie).

Warte spróbowania i unaocznienia pojęcia funkcji jako wartości jest wykonanie symbolu funkcyjnego (w powyższym przykładzie f).
scala> f
res15: Int => Int = <function1>
Pojawi się sygnatura funkcji, na którą wskazuje symbol (funkcyjny). Dodatkowo, od tej pory res15 jest również tym, na co wskazywał symbol f.

A na koniec inna ciekawostka: spróbuj wywołać wartość liczbową z parametrem wejściowym, np. powyższy symbol n jakby wskazywał na funkcję.
scala> n
res13: Int = 10

scala> n(2)
<console>:9: error: Int does not take parameters
              n(2)
               ^
Chciałbym napisać, że stała to również funkcja, która akceptuje zero parametrów wejściowych, ale czym różniłoby się to od funkcji bezparametrowej?! A może za bardzo chcę rozróżniać między nimi, a nie ma po co?! Jak czytam w Symbol funkcyjny:

"Wprowadzając język pierwszego rzędu najpierw określamy jego alfabet τ czyli zbiór symboli funkcyjnych, symboli relacyjnych i stałych. Każdy z tych symboli ma jednoznacznie określony charakter (tzn. wiadomo czy jest to stała, czy symbol funkcyjny, czy też predykat) i każdy z symboli funkcyjnych i predykatów ma określoną arność (która jest dodatnią liczbą całkowitą)."

co sugeruje, że nawet jeśli teoretycznie stała jest odpowiednikiem funkcji zeroargumentowej (lub odwrotnie), to faktycznie z góry wiemy, że mamy do czynienia z symbolem wskazującym na stałą lub funkcją (dowolnej arności). Trzeba mi było uważać na studiach - może wtedy takie rzeczy nie byłyby dla mnie swego rodzaju mentalnym wyzwaniem. A jakie jest Twoje zdanie w temacie? Co byłoby interesujące dla Ciebie w poznawaniu Scali?

27 kwietnia 2012

Aplikacje graficzne dynamicznie w Scali

0 komentarzy
Do Euro 2012 coraz bliżej, a ja coraz bardziej pewnie czuję się w Scali. Nie staram się poznawać tego języka zgodnie z jakimkolwiek wzorcem, a jedynie, jak coś wpadnie mi w ręce, to sobie przeczytam i popróbuję się z tym w Scala REPL. Na chwilę obecną jest więcej "popróbuję" nad "poczytam".

Zanim jednak o Scali...

Jutro (sobota, 28 kwietnia) prowadzę zajęcia w ramach Studiów podyplomowych studiów ITB (Informatyczne Technologie Biznesowe) na Wydziale Matematyki i Informatyki Uniwersytetu im. Adama Mickiewicza w Poznaniu. Będę mówił o różnych rzeczach wspieranych w ramach rodziny IBM WebSphere. I z tego powodu dotarłem dzisiaj do Poznania.

Podczas wysiadania z pociągu zobaczyłem, że pewna kobieta (nazwijmy ją roboczo KOBIETA) męczy się z dosyć sporawą walizą, więc zaoferowałem swoją pomoc. I tak się to dalej potoczyło.

JA: Czy mógłbym Pani pomóc?
KOBIETA: Nie, dziękuję. Brat mi pomoże.
JA: W porządku.

Podchodzi w tym momencie brat (roboczo nazwany BRAT) i patrzy na mnie jakoś dziwnie. Myślę sobie, gość mi zaraz spuści łomot za to, że dostawiam się do jego siostry. Wydawał się być zdeterminowany, aby to zrobić.

Po chwili, już poza pociągiem, kiedy ja zdejmowałem bluzę na pobliskiej ławce, na peronie.

Stanowczym krokiem nadchodzi brat. Myślę sobie, no to się zaczęło.

BRAT: Czy Ty jesteś Jacek?
JA: Tak. (zdumiony i prawie zlany potem)
BRAT: Czy Ty jesteś Jacek Laskowski?
JA: Tak. (coraz bardziej zaskoczony obrotem sytuacji, pamiętając o czujności)
BRAT: Znam Cię! Ja też jestem programistą!
JA: O, to miłe. Cześć!

I BRAT odszedł do KOBIETA zostawiając mnie w niezłym szoku. Ale pozbierałem się, przypomniałem sobie, że to nie szok, ale ego powinno teraz mną kierować i od razu zrobiło się przyjemniej :)

A wracając do Scali...

Dzisiaj czytając kolejny rozdział książki Real-World Functional Programming (With examples in F# and C#) zatytułowany "11. Refactoring and testing functional programs" przypomniałem sobie o Scali i jej REPL, i zacząłem zastanawiać się, czy mógłbym zbudować aplikację GUI dynamicznie, podobnie jak to miało ostatnimi czasy miejsce z Clojure. Jakież było moje zdumienie, kiedy niewiele trzeba mi było, aby coś zbudować. I pojawiło się okienko. A później przycisk.

Poniżej moja sesja. Zachęcam do samodzielnego popróbowania się z interpreterem scala, bo nie wymaga wiele, a sprawia niemało radochy. Ach, dodatkowo na portalu scala.net.pl pojawił się artykuł Grzegorza Balcerka zatytułowany "Metody i funkcje" i wiele się wyjaśniło. Bardzo pomocny artykuł! Zachęcam do spróbowania się z nim (aka "przeczytania") również. Czas nie będzie stracony. A jak się jeszcze wahasz, to możemy się umówić, że następny mój wpis ominiesz, aby mieć więcej czasu na artykuł :)
$ scala
Welcome to Scala version 2.10.0-M2 (OpenJDK 64-Bit Server VM, Java 1.8.0-jdk8-b35).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import javax.swing._
import javax.swing._

scala> val frame = JFrame(title="Hello")
<console>:10: error: object javax.swing.JFrame is not a value
       val frame = JFrame(title="Hello")
                   ^

scala> val frame = new JFrame(title="Hello")
<console>:10: error: overloaded method constructor JFrame with alternatives:
  (String,java.awt.GraphicsConfiguration)javax.swing.JFrame <and>
  (String)javax.swing.JFrame <and>
  (java.awt.GraphicsConfiguration)javax.swing.JFrame <and>
  ()javax.swing.JFrame
 cannot be applied to (title: String)
       val frame = new JFrame(title="Hello")
                   ^

scala> val frame = new JFrame("Hello")
frame: javax.swing.JFrame = javax.swing.JFrame[frame0,0,22,0x0,invalid,hidden,layout=java.awt.BorderLayout,
title=Hello,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,
invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,
maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

scala> frame.setSize(200, 200)

scala> frame.setVisible(true)

scala> val btnOk = new JButton("Press me")
btnOk: javax.swing.JButton = javax.swing.JButton[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.5,
border=com.apple.laf.AquaButtonBorder$Dynamic@443385ae,flags=288,maximumSize=,minimumSize=,preferredSize=,
defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=2,
bottom=0,right=2],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,
rolloverSelectedIcon=,selectedIcon=,text=Press me,defaultCapable=true]

scala> frame add btnOk
res2: java.awt.Component = javax.swing.JButton[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.5,
border=com.apple.laf.AquaButtonBorder$Dynamic@443385ae,flags=288,
maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,
margin=javax.swing.plaf.InsetsUIResource[top=0,left=2,bottom=0,right=2],paintBorder=true,paintFocus=true,
pressedIcon=,rolloverEnabled=false,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Press me,
defaultCapable=true]

scala> frame pack
A później natrafiłem na twitterze wzmiankę o :reset w Scala REPL i byłem niezwykle uradowany mogąc od razu spróbować tego w działaniu. Użyteczne, nie powiem.
scala> :reset
Resetting interpreter state.
Forgetting this session history:

import javax.swing._
val frame = new JFrame("Hello")
frame.setVisible(true)
frame.setSize(200, 200)
val btnOk = new JButton("Press me")
frame add btnOk
frame pack

Forgetting all expression results and named terms: btnOk, frame

scala> frame
<console>:8: error: not found: value frame
              frame
              ^

26 kwietnia 2012

Opóźnianie wykonania w Scali

4 komentarzy
Dostałem dostęp do MEAP dla książki Functional Programming in Scala i poza lekturą bezpłatnego rozdziału wprowadzającego "Introduction", mam jeszcze możliwość przeczytania "Strictness and laziness". Na razie niewiele stron do czytania, bo jedynie 25, ale i tak poznałem stosunkowo wiele w obszarze programowania funkcyjnego ze Scalą jako językiem "wykładowym".

Tam też trafiłem na ciekawostkę opóźniania wykonania kodu w Scali, dla której w Clojure musiałbym zaprząc mechanizm makr (wciąż moją znajomość tematu określiłbym jako teoretyczną) lub utworzyć funkcję.

W języku Scala wystarczy użyć symbolu => - tego samego jak przy rozdzielaniu części funkcji - wejścia od wyjścia dla deklaracji typów i samego ciała funkcji. Brzmi pogmatwanie, ale należy to zrzucić na barki mojej niewielkiej znajomości tematu. Przykład powinien rozjaśnić zagadnienie.

Pytanie rozgrzewające: "Czy potrafisz wskazać element(y) języka Java, które pozwala na warunkowe wykonanie kodu?" Chętnie poznam Twoją odpowiedź - skorzystaj z możliwości komentowania.

W Scala sprawa przedstawia się jak poniżej. Uruchamiamy interpreter Scali - scala i do dzieła.
scala> def laaazy(x: => Int): Int = { println("Inside laaazy"); x}
laaazy: (x: => Int)Int

scala> laaazy({ println("Input argument"); 5 })
Inside laaazy
Input argument
res16: Int = 5

scala> def laaazy(x: Int): Int = { println("Inside laaazy"); x}
laaazy: (x: Int)Int

scala> laaazy({ println("Input argument"); 5 })
Input argument
Inside laaazy
res17: Int = 5
Czy potrafisz wskazać owe szczególne miejsce w powyższej sesji do opóźnienia wykonania? Zwróć uwagę na kolejność występowania napisów "Inside laaazy" praz "Input argument". Ciekawe, co? A jak zrealizował(a)byś to w Javie?

25 kwietnia 2012

Sprawdź TAB w interpreterze scala

2 komentarzy
Czas biegnie nieubłaganie i coraz częściej doświadczam olśnienia właściwego przeznaczania czasu na rzeczy, które mają dla mnie znaczenie (zamiast na takie, które jedynie przez krótki moment wydają się być wartościowe). Widzę to chociażby na przykładzie moich dzieciaków, szczególnie tego najmłodszego, ale również i najstarszej. Pierwszy może pochwalić się pierwszym ząbkiem (poza innymi nowinkami, którymi obdarza nas właściwie każdego dnia), a druga ukończoną 18tką (!) Jak ten czas leci! Kiedy dodać do tego "zabawę" w egzamin gimnazjalny u drugiego syna, czasu zdecydowanie nie starcza na wszystkie uciechy.

Mimo to, nie poddaję się ze Scalą i wykorzystując czas w drodze do pracy komunikacją miejską udało mi się przejść przez darmowy rozdział Functional Programming in Scala. Nie zamierzam się rozpisywać na jej temat, bo można krótko: "Polecam!" Jeśli tylko autorzy utrzymają narrację, zapowiada się naprawdę wyśmienita książka. Każdemu początkującemu w programowaniu funkcyjnym polecam, a jako, że przykłady będą w Scali, to zainteresowanym tym językiem przede wszystkim. W zasadzie trudno wyobrazić mi sobie programistę dowolnego poziomu, który nie skorzystałby z lektury tej książki. Chociaż, jeśli się zastanowić, to jest to wrażenie po jednym rozdziale, który koniec końców nie jest zapewne jeszcze nawet w finalnej wersji. Nadzieja jest i poprosiłem Manning o dostęp do MEAP. Właśnie dostałem odpowiedź, że zgoda jest. Będzie okazja dostąpić zaszczytu przeczytania kolejnego rozdziału "Strictness and laziness".

Jako, że próbuję ukończyć lekturę innej książki o programowaniu funkcyjnym, tyle że w F# - Real-World Functional Programming (With examples in F# and C#), to Scali nie poświęcam tyle czasu, ile chciałbym. Nie zapominam również o Clojure, któremu poświęciłem wszystkie moje publiczne wystąpienia w 2012 do tej pory. A jest jeszcze planowanych kilka (niektóre jeszcze niepotwierdzone) - GeeCON, spotkanie na Warszawa JUG, podobnież Softdevcon, jar.camp(), podobnież Eclipse DemoCamp w Poznaniu i Warszawie, oraz planowane wspólne wystąpienie z Grzegorzem B. na Confiturze. Jeszcze będzie spoooro tego Clojure w moim życiu. Konrad Garus utwierdza mnie w przekonaniu, że nawet uda mi/nam się coś w Clojure napisać - zachęcam do udziału w zabawie w projekcie librarian-clojure.

Kiedy jednak zasiadam przy kompie, zaczynam od odrobiny Clojure, a później szczypty Scali. Jest to o tyle łatwe, że wystarczy uruchomić lein2 repl, aby doświadczyć przyjemności pracy z Clojure, a scala, aby skorzystać z interpretera Scali.

I tak bodajże wczoraj zasiadłem przy Scali i kiedy zacząłem wpisywać kawałki kodu javowego, jakoś niechcący skorzystałem z klawisza tabulacji. Jakież było moje zdumienie, kiedy dla typów z dopiero co zaimportowanego pakietu java.net (import java.net._) zacząłem dostawać w odpowiedzi dostępne klasy, a później nawet i ich składowe - metody i pola. Trzeba było widzieć moją minę, kiedy uzmysłowiłem sobie siłę środowiska Scala, w którym mogłem śmiało wpisywać wyrażenia javowe, które wcześniej wymagały ode mnie pracy w IDE - nie zawsze zgodnie z moimi potrzebami.

Spróbuj samemu/-ej. Wystarczy pobrać dystrybucję Scali, uruchomić interpreter scala i zacząć od importu wybranego pakietu. Wtedy TAB i voila. Próg wejścia bardzo obniżony mając do dyspozycji bardzo dynamiczne środowisko, w którym odpowiedź jest natychmiastowa. To lubię!

p.s. Wciąż nie mogę oduczyć się rozpoczynania od nawiasu, kiedy widzę środowisko scala. Czarne tło interpretera Scali nie sprzyja koncentracji?

22 kwietnia 2012

scala> lazy val days2Euro2012 = 47

2 komentarzy
Słoneczna niedziela nie sprzyjała głębszej nauce, więc skończyło się na przejrzeniu forum książki o programowaniu funkcyjnym w języku Scala - Functional Programming in Scala. Niewielka liczba wątków zachęcała do krótkiego rekonesansu do Scali przez pryzmat dyskusji w temacie jej funkcyjnej strony.

W Function representation in Scala trafiłem na:
val add:(Int, Int) => Int = (x,y) => x + y
podczas 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 + y
Niby 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 = 8
Nie 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 kota
Gdyby 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.

21 kwietnia 2012

scala> (-48 to Euro2012)

8 komentarzy

Lektura Functional Scala: Introduction pozwoliła mi ułożyć sobie w głowie koncepcję programowania funkcyjnego. Mimo ukierunkowania autora na Scalę, prawie żadna z części nie wskazywała na jakikolwiek związek z tym językiem. Wystarczy 30 minut skupienia i zrozumienie cech paradygmatu funkcyjnego powinno być jaśniejsze. Mi pomogło znacznie.

Najbardziej płodną sekcją artykułu była końcówka Stateless vs. Stateful, w której dotarło do mnie, że:

Skutek uboczny jest sposobem na przechowanie tymczasowego wyniku obliczeń na potrzeby innych części aplikacji. W programowaniu funkcyjnym zmienne nie istnieją, więc jedynym sposobem na przekazanie wyniku obliczeń jest użycie rekurencji (przekazywanie wyniku funkcji samej sobie) lub zwrócenie go (przekazanie wyniku innym funkcjom).

Podczas lektury miałem uruchomioną konsolę scala i bawiłem się poznanymi konstrukcjami. Nie zagłębiam się w lekturę składni Scali, więc idzie mi jak po grudzie i próbuję odgadywać, jak mogłoby dane wywołanie wyglądać. Najbardziej zaskakujące jest, że bezwiednie wpisuję wywołania w składni Clojure - zaczynam nawiasem! Stało się to dla mnie naturalne! Całkowicie przestawiłem swoje myślenie na "wszechobecne funkcje" w Clojure na "metody są przypisane do obiektów" w Scali. Scala wymusza u mnie przestawienie się na myślenie obiektowe z dodatkiem funkcyjnym.

Poniżej wycinek moich wyczynów scalowych. Samo środowisko często samo z siebie podpowiada co mogłoby być właściwe w danym kontekście. Bajka!
$ scala
Welcome to Scala version 2.10.0-M2 (OpenJDK 64-Bit Server VM, Java 1.8.0-jdk8-b29).
Type in expressions to have them evaluated.
Type :help for more information.

scala> (1 to 9)
res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> Range(1, 4)
res1: scala.collection.immutable.Range = Range(1, 2, 3)
Zwróć uwagę na sufix Inclusive przy nazwie klasy, która obsługuje pierwszy przykład vs drugi.
scala> (0 to 10).foldLeft(0)
<console>:8: error: missing arguments for method foldLeft in trait TraversableOnce;
follow this method with `_' if you want to treat it as a partially applied function
              (0 to 10).foldLeft(0)
                                ^

scala> (0 to 10).foldLeft(0)_
res3: ((Int, Int) => Int) => Int = <function1>

scala> val fl = (0 to 10).foldLeft(0)_
fl: ((Int, Int) => Int) => Int = <function1>

scala> fl(_+_)
res4: Int = 55

scala> val fl = (0 to 10).reduceLeft_
<console>:7: error: value reduceLeft_ is not a member of scala.collection.immutable.Range.Inclusive
       val fl = (0 to 10).reduceLeft_
                          ^

scala> val fl = (0 to 10).reduceLeft _
fl: ((Int, Int) => Int) => Int = <function1>

scala> fl(_+_)
res5: Int = 55

20 kwietnia 2012

Scala w 49. dzień do Euro 2012

3 komentarzy

Wczoraj na forum Warszawa JUG zaproponowałem pewną zabawę skojarzoną z upływającym czasem do Euro 2012 - 50 dni do Euro 2012 - idealnie, aby zaczać naukę.... Celem zabawy jest "nauki technologii, którą zwykle mianował TODO."

Mamy 50 dni (wczoraj) i ciekawie będzie móc zasiąść przed ekranem telewizora wiedząc, że przygotowania do tej pozycji były związane z nauką czegoś nowego. Możnaby wtedy świętować nie tylko rozpoczęcie mistrzostw, ale ukończenie rozpoznania czegoś, co warte było 50 dni.

Ja postawiłem na funkcyjne oblicze języka programowania Scala. Niech to będzie mój udział w ogólnopolskim wyścigu ku Euro 2012. Piłka mnie nie kręci, ale Scala już tak. Mam nieodparte wrażenie, że zrozumienie programowania funkcyjnego w Scali pomoże mi znacznie podnieść swój warsztat i w Clojure.

Dzisiaj zacząłem skromnie od pobrania dystrybucji języka Scala 2.10.0-M2 i po przejrzeniu Chapter 2 of Programming in Scala, First Edition "First Steps in Scala" uruchomieniu środowiska scala.
$ scala
Welcome to Scala version 2.10.0-M2 (OpenJDK 64-Bit Server VM, Java 1.7.0-jdk7u4-b19).
Type in expressions to have them evaluated.
Type :help for more information.

scala> println("Hello")
Hello
Obejrzałem prezentację Guerrilla Guide to Pure Functional Programming i popróbowałem się z kilkoma wyrażeniami ze slajdów. Można żyć z tym systemem typów.

Teraz nie pozostaje mi nic innego jak rozpocząć projekt. Chciałbym stworzyć coś w czystej Scali, bez konieczności poznawania dodatkowych bibliotek, czy szkieletów aplikacyjnych i mam nieodparte wrażenie, że najbardziej odpowiednia byłaby jakaś aplikacja desktopowa. Boję się Lifta jako sposobu na wejście w Scalę i stąd te poszukiwania.