26 lutego 2013

Android 4.1.2 na Samsung Galaxy S II - aktualizacja poszła gładko

9 komentarzy
Pamiętam, jak wypatrywałem jego nadejścia, aż w końcu się doczekałem. I nie zapomnę mojego zdumienia, kiedy wyjątkowo wcześnie rozpoczynając poranek, 22 lutego zobaczyłem powiadomienie o oczekującej aktualizacji. Nie przypuszczałem, że może to być Android 4.1.2 "Jelly Bean", bo czas aktywnego wypatrywania miałem już dawno za sobą. Przegapiłem również wiadomość o dostępnej aktualizacji, która podobno była już w sieci od 18 lutego.

I w końcu do mnie dotarło!

"I teraz co?!", pomyślałem. Grzecznie przeczytałem informacje z ekranu mojego "najulubieńszego" Galaxy S II i zacząłem zastanawiać się nad kopią bezpieczeństwa. Najbardziej szkoda było mi stracić zdjęć i nagrań, więc szybko przeniosłem je w bezpieczne miejsce. Reszta mogła iść do kosza, gdyby podczas aktualizacji doszło do skasowania zawartości telefonu. A co mi tam.


Ekranów z instrukcją aktualizacji oprogramowania nie widać było końca. Najpierw ten wyżej, później następny...


...aż w końcu pojawił się ostatni.


Podekscytowany odłożyłem jednak telefon na bok i zabrałem się za śniadanie. "Jak się człowiek spieszy, to się diabeł cieszy."



I warto było czekać. Aktualizacja przeszła gładko (podobnie jak poprzednia do ICS - Android 4.0.3), więc do tej pory nie narzekam.

Od strony użytkownika zauważyłem pewne przyspieszenie działania telefonu i jakby siła sygnału wzmocniła się. Zwolniła aplikacja do robienia zdjęć i teraz trzeba trochę dłużej odczekać zanim kamera jest gotowa do działania. Zwiększyła się liczba opcji w panelu w belce i pojawiło się kilka znaczących zmian w samym korzystaniu z systemu. Jestem zadowolony z przejścia na Jelly Bean. Polecam!

25 lutego 2013

wpis match { case BlogEntry("Klasy przypadku aka case classes") => true }

7 komentarzy
Jaki jest Twój rytuał tworzenia klas? David Pollak w swojej książce Beginning Scala (Apress, 2009) napisał, że jego obejmuje pisanie metod toString, hashCode oraz equals (wszystkie z java.lang.Object). Jako powód powołał się na Joshua Bloch, który w Effective Java (Prentice Hall, 2008) napisał, że jest to dobra praktyka, która umożliwia obiektom uczestniczyć w kontrakcie określonym przez tablice haszujące (ang. hash tables) oraz przy ich wypisywaniu. Słusznie (aczkolwiek moje skromne programowanie nie obejmowało takich szczegółów).

Może Wasze również? Jeśli tak, warto przyjrzeć się mechanizmowi klas przypadków (ang. case classes), dla których kompilator Scali generuje implementacje wspomnianych metod z pudełka oraz, co z pewnością ważniejsze, uczestniczą w mechaniźmie dopasowywania wzorców (ang. pattern matching).

Załóżmy, że mamy taką klasę X w Scali.
case class X(x: Int)
Na pierwszy rzut oka, jakby znajoma konstrukcja (szczególnie dla programistów javowych) do tworzenia definicji klas. Co rzuca się w oczy, to brak nawiasów klamrowych po definicji klasy, jeśli ciało będzie odpowiadało temu, które utworzy kompilator Scali (poniżej wyjaśnienie, czego należy oczekiwać).

Po kompilacji otrzymujemy zestaw użytecznych metod w klasie bez konieczności pisania ich własnoręcznie (!)
$ scalac X.scala

$ ls X*
X$.class X.class X.scala

$ javap -classpath . X
Compiled from "X.scala"
public class X implements scala.Product,scala.Serializable {
  public static <A extends java/lang/Object> scala.Function1<java.lang.Object, A> andThen(scala.Function1<X, A>);
  public static <A extends java/lang/Object> scala.Function1<A, X> compose(scala.Function1<A, java.lang.Object>);
  public int a();
  public X copy(int);
  public int copy$default$1();
  public java.lang.String productPrefix();
  public int productArity();
  public java.lang.Object productElement(int);
  public scala.collection.Iterator<java.lang.Object> productIterator();
  public boolean canEqual(java.lang.Object);
  public int hashCode();
  public java.lang.String toString();
  public boolean equals(java.lang.Object);
  public X(int);
}
Tworzenie obiektów klas przypadków jest możliwe bez słówka kluczowego new oraz domyślnie wszystkie parametry konstruktora stają się atrybutami obiektu jedynie do odczytu. Klasa przypadku jest niezmienna.
scala> case class X(x: Int)
defined class X

scala> val x = new X(5)
x: X = X(5)

scala> x
res0: X = X(5)

scala> val y = X(5)
y: X = X(5)

scala> y
res1: X = X(5)

scala> x == y
res2: Boolean = true

scala> x equals y
res3: Boolean = true

scala> x.equals(y)
res4: Boolean = true
I kontynuując dalej poszukiwania udogodnień związanych z klasami przypadku w Scala REPL:
scala> case class X(x: Int)
defined class X

scala> X.[wciśnij TAB]
andThen apply asInstanceOf compose isInstanceOf toString unapply        

scala> val x = X(5)
x: X = X(5)

scala> x.
asInstanceOf canEqual copy isInstanceOf productArity productElement productIterator productPrefix toString x

scala> x.x
res0: Int = 5

scala> x.toString
res1: String = X(5)

scala> x.hashCode
res2: Int = -1267080172

scala> x.equals(x)
res3: Boolean = true

scala> x.equals(X(5))
res4: Boolean = true
Siłę klas przypadku można dostrzeć przy dopasowywaniu wzorców, z którymi stanowią nierozerwalną parę w Scali.

Martin Odersky, Lex Spoon oraz Bill Venners w swojej książce Programming in Scala, Second Edition (Artima, 2011) napisali, że klasy przypadku są odpowiedzią Scali na umożliwienie dopasowywania wzorców (znanego z języków funkcyjnych) na obiektach bez konieczności pisania nużącego, ale niezbędnego kodu wspierającego. Wystarczy przed nazwą klasy napisać "case" i po krzyku.

Tak na marginesie, jakby się tak zastanowić nad potencjalną genezą nazwy "case classes", to przy znajomości dopasowywania wzorców w Scali - konstrukcja match-case - możnaby wysnuć wniosek, że one są dla siebie stworzone. Nawet nazwy je łączą. O pomyłkę trudno.
scala> X(10) match {
     |   case X(10) => "Obiekt X z 10 wewnątrz"
     |   case _ => "Coś bliżej niezidentyfikowanego"
     | }
res5: String = Obiekt X z 10 wewnątrz

scala> X(3) match {
     |   case X(num) => s"Obiekt X z ${num}"
     |   case _ => "Coś bliżej niezidentyfikowanego"
     | }
res6: String = Obiekt X z 3
I inne temu podobne, które dotyczą dopasowywania wzorców. Ciekawy mechanizm.

Na zakończenie warto wspomnieć o uproszczeniach w tworzeniu nowych obiektów na bazie istniejących z utworzoną metodą copy.
scala> case class Y(a: Int, b: String, c: X)
defined class Y

scala> val y = Y(5, "Five", x)
y: Y = Y(5,Five,X(5))

scala> y.copy(a=500)
res6: Y = Y(500,Five,X(5))

scala> y.copy(a=500, b="Five Hundred")
res7: Y = Y(500,Five Hundred,X(5))

scala> y.copy(c=X(500))
res8: Y = Y(5,Five,X(500))
Niskim kosztem (tworzenia klas przypadków) otrzymujemy stosunkowo bogatą funkcjonalność. To musi się podobać!

Warto przeczytać:

21 lutego 2013

Natchniony po lekturze Zippers in Scala

4 komentarzy
Zasiądź wygodnie i przygotuj się do kilku krótkich zadanek programistycznych w Scali. Nie powinny zająć więcej niż 10 minut (dla mniej wprawnych rąk).

Zacznij od implementacji funkcji def peak(list: List[Int]): Option[Int], która zwróci pojedynczy element listy, który jest większy niż jego sąsiedzi, np. peak(List(1, 2, 3, 5, 2)) zwróciłoby Some(5), ale już peak(List.range(0, 5)) zwróci None.

Już? Gotowe? Test przechodzi? Zatem kolejne zadanko.

Następnie przejdź do implementacji funkcji def raisePeak(list: List[Int]): Option[List[Int]], która znajdzie "peak" wyżej, ale zwróci nową listę z tym elementem zwiększonym o jeden.

Już? Nie za szybko?! :-)

Na pewno dostrzegłeś, że funkcja raisePeak znacząco się skomplikowała i to może być ten moment, kiedy zechcesz wejść w świat struktury danych zwanej Zipper. Zanim jednak zdecydujesz się na własną implementację w Scali proponuję zajrzeć do wpisu Zippers in Scala. Ciekawie poprowadzony "wykład", w którym znajdziesz nie tylko rozwiązania tych dwóch problemów powyżej, ale również daje pogląd na problem, który rozwiązują zipper'y.

"Zippers in Scala" nazwałbym inspirującą lekturą, która kształtuje mój światopogląd scalowy. Mnie natchnął do dalszego zgłębienia tematu zipper'ów. Ktoś już nad tym ślęczał? Jakie wrażenia?

20 lutego 2013

Pierwszy projekt w Scali - obróbka XMLi przy migracji z WLI do IBM BPM

3 komentarzy
Chwała każdemu, komu udaje się dopiąć swego i wdrożyć nowy język w projekcie, aby produkt ciężkiej pracy umysłowej komuś ułatwił życie (niechby to był sam klient, albo koledzy programiści z zespołu).

A niechby to był taki malutki projekcik, jak ten mój, dzisiejszy do obrabiania XMLi. Nic nadzwyczajnego, ale czego oczekiwać od nowicjusza scalowego, który karierę w tym języku liczy w dniach (a nie tygodniach, czy miesiącach)?! Każdy przecież kiedyś był początkujący w rzeczach, w których teraz wiedzie prym. Ja właśnie zaczynam swoje pierwsze kroki w Scali i twory przypominają prawdziwe potwory, ale od czegoś zacząć należy!

Wierzę, że z pomocą Grześka, teamon'a oraz dmilith'a nauka Scali będzie tylko przyjemnością!

Pora na odsłonę mojego dzieła. Komentarze mile widziane.
package pl.japila.wli.transformations.control

import scala.xml.{ XML, Node, Elem }
import scala.xml.transform.{ RuleTransformer, RewriteRule }

object WLIControlMigrationMain {
  // FIXME: Remove it once the script reads input args or we find them a better place
  val pkg = "pl.japila.wli.transformations.control".replace(".", "/")
  
  def main(args: Array[String]) {
    // The file comes from the BPEL Exporter in WLI
    val processCtrlXml = XML.load(getClass.getResourceAsStream(s"/${pkg}/process_ctrl.wsdl"))
    val portType = (processCtrlXml \ "portType" \ "@name").text

    // The file is ours - the template for a JMS import
    val importXmlTemplate = XML.load(getClass.getResourceAsStream(s"/${pkg}/import-xml.template"))
    // The file name and the name of the import component must be alike
    val importComponentName = portType + "_MB_Publish_control"
    println(s"+++\n+++ Save the following file as ${importComponentName}.import:\n+++")
    println(importXmlTemplate.toString
      .replace("{importComponentName}", importComponentName)
      .replace("{portType}", portType))
    println(s"+++\n+++ Save the following file as process.component:\n+++")
    wireComponentWithImport(importComponentName)
  }

  def wireComponentWithImport(importComponentName: String) {
    val processComponentXML = XML.load(getClass.getResourceAsStream(s"/${pkg}/process.component"))
    val wire = XML.loadString(s"<wire target='${importComponentName}'/>")
    val wiredProcessComponentXML = new RuleTransformer(
                                     new AddChildrenTo("reference", wire))
                                       .transform(processComponentXML).head
    println(wiredProcessComponentXML)
  }

  // http://stackoverflow.com/questions/2199040/scala-xml-building-adding-children-to-existing-nodes
  def addChild(n: Node, newChild: Node) = n match {
    case Elem(prefix, label, attribs, scope, child @ _*) =>
      Elem(prefix, label, attribs, scope, child ++ newChild: _*)
    case _ => sys.error("Can only add children to elements!")
  }

  class AddChildrenTo(label: String, newChild: Node) extends RewriteRule {
    override def transform(n: Node) = n match {
      case Elem(_, `label`, _, _, _*) => addChild(n, newChild)
      case _ => n
    }
  }
}

19 lutego 2013

Nowy artykuł o pisaniu servletów w Scali z Eclipse i WebSphere Application Server V8.5 Liberty Profile

3 komentarzy
Ku mojemu zaskoczeniu, ostatni wpis Listy w Scali przyciągnął dość znaczą uwagę - pojawiły się komentarze, które nie pozostają w mojej głowie bez echa. Dają mocno do myślenia. teamon oraz dmilith nie odpuszczają w swojej krucjacie podniesienia wartości moich wpisów i ku okrzepieniu serc zebrałem się na napisanie czegoś dłuższego - artykułu Developing Java Servlets in Scala with Eclipse and WebSphere Application Server V8.5 Liberty Profile. Ciekawym Waszego zdania na TEN temat.

Jak napisałem na swoim angielskojęzycznym blogu planuję poświęcić kilka wieczorów na Play Framework, którego planuję uruchamiać na WebSphere Application Server V8.5 Liberty Profile, a może nawet na pełnym WebSphere Application Server 8.5. Gdyby ktoś zechciał pomóc, pokierować, to zapraszam do sekcji komentarzy poniżej lub maila. Dziękuję!

17 lutego 2013

Listy w Scali

17 komentarzy
Nie, nie chodzi mi o pisanie listów, a ich używanie. I nie chodzi mi również o tradycyjne listy w kopercie, a tradycyjne listy jako struktury danych w Scali. Są one wszechobecne w Clojure i mają w tym języku specjalne traktowanie, co okazuje się być w sprzeczności do Scali, w której "lists now integrate more closely into the collections framework, and are less of a special case than before."

Początkowo sądziłem, że istnieje literał dla utworzenia listy, ale najwyraźniej się myliłem, bo…
scala> ()

scala> val a = ()
a: Unit = ()
...jest to oznaczenie dla typu scala.Unit, w którym "There is only one value of type Unit, (), and it is not represented by any object in the underlying runtime system. A method with return type Unit is analogous to a Java method which is declared void."

Myślałem sobie, że może () ma specjalne traktowanie w Scali, podobnie jak w Clojure, dla którego oznacza pustą listę. Spróbowałem więc…
scala> (1, 2, 3)
res1: (Int, Int, Int) = (1,2,3)

scala> res1.getClass
res2: Class[_ <: (Int, Int, Int)] = class scala.Tuple3
...co okazało się być tym razem jeszcze innym typem scala.Tuple3, a nie oczekiwaną listą. Cóż pozostaje przyzwyczaić się do zapisu...
scala> List(1, 2, 3)
res3: List[Int] = List(1, 2, 3)
lub
scala> 1 :: 2 :: 3 :: Nil
res4: List[Int] = List(1, 2, 3)
...i poczytać dokumentację dla scala.collection.immutable.List. Zacznę od Lists w Scala Documentation.

Nie za krótki wpis? Nie za trywialny? Kontynuować wspólne poznawanie Scali w serii takich wpisów czy może uzupełnić to i owo? Sugestie mile widziane.

16 lutego 2013

Scala i programowanie funkcyjne. Wprowadzenie cz. 2

1 komentarzy
Nie spodziewałem się, że ów "concise, elegant, type-safe programming language that integrates object-oriented and functional features", którego zwią Scala może mnie tak zmęczyć umysłowo. Kiedy dzisiaj wróciłem do domu po drugiej części szkolenia "Scala i programowanie funkcyjne. Wprowadzenie" Grześka Balcerka miałem wszystkiego serdecznie dość.

Scala trywialnym językiem zdecydowanie nie jest.

Tydzień temu ruszyliśmy z tematem nauki Scali i w 11 osób plus prowadzący Grzesiek popróbowaliśmy się z kilkoma problemami programistycznymi. Dzisiaj kontynuacja - dosłownie i w przenośni. Kiedy pojawiło się zadanie z kontynuacjami (przy realizacji zadania z trampoline), już byliśmy po zadaniu stworzenia listy bez listy i innych mniej lub bardziej intensywnych umysłowo zadankach. Czuję, że dzisiejszy dzień był wartościowy "emocjonalnie", bo Covariance and contravariance w Scali oraz górne i dolne ograniczania akceptowalnych typów w parametryzowanych typach nie pozostawiły we mnie nadziei na szybkie wejście w temat zrozumienia systemu typów w Scali. Będzie trzeba jeszcze posiedzieć i podumać. I to z pewnością nie będą dni, a całe tygodnie, jeśli nie miesiące!

Wspólne męki ze zrozumieniem tematu jednoczą i grupa podejmowała wyzwania implementacji typów w sposób godny i z wysoko podniesioną głową :-)

Dzisiaj wdrożyliśmy podejście, w którym najpierw zmagamy się z zadaniem samodzielnie, aby po kilku upadkach i, przynajmniej dla niektórych, szczęśliwym Happy Endem, wspólnie podjąć się jego rozwiązania i tym samym uzupełnienia braków. W końcu co dwie...tzn. jedenaście głów, to nie jedna i zawsze ktoś z czymś wyskoczy i rozwinie się dyskusja.

Ten aspekt właśnie najbardziej mi się spodobał. Już dawno nie uczestniczyłem w sobotnim "zgrupowaniu" programistycznym i widzę, jak bardzo pomocne jest poznawanie języka (Scala) wspólnie. Ktoś coś zapyta, ktoś coś zarzuci i już jest dyskusja. Możliwość spędzenia z językiem całej soboty i w gronie innych zapaleńców uważam za bezcenne. Dziękuję Panowie za miłą atmosferę. Warto było poświęcić dwie soboty z Wami i z nią! :-)

Trudno powiedzieć, czy to zasługa prowadzącego - Grzegorza Balcerka - czy grupy, czy materiałów, języka, czy jeszcze czegoś innego, ale udział w tym projekcie szkoleniowym dał mi tak wiele, że trudno mi teraz pisać o niedociągnięciach (jeśli w ogóle takowe były). Za bardzo jestem podekscytowany, aby pamiętać o nich. Przyjmijmy, że jeśli były, to stanowiły tak niezauważalną część, że szkoda byłoby się silić na ich wypisywanie. Błahostka.

Najbardziej utkwiła mi część związana z Covariance and contravariance w Scali. Pewnie dlatego, że jest to nowe i na pierwszy rzut oka niezwykle skomplikowane. Cały system typów w Scali może przyprawić o ból głowy! Ale mnie to nakręca i skoro jest trudno, ja w to wchodzę!

Podczas wyjaśniania +T czy -T w połączeniu z >: i <: w Scali nietrudno było dostrzec biegłość Grześka w posługiwaniu się tymi "narzędziami". Nie była to wiedza ze slajdów, ale bardziej projektowa (chociaż Grzegorz nie wspominał o jakimkolwiek projekcie scalowym, w którym brałby udział, a jedynie wspominał o intensywnej pracy umysłowej - niektórym jakoś tak łatwiej przychodzi rozumienie problemów niekoniecznie rozwiązanych na placu boju). Fascynuje mnie ta mnogość niespotykanych wcześniej konstrukcji programistycznych. Przy każdym spotkaniu z Clojure co krok olśniewa mnie, jak można ciekawie rozwiązywać problemy przy pomocy programowania funkcyjnego. Teraz procentuje to łatwiejszym przyswajaniem funkcyjnej części Scali - wiele rzeczy, które sprawiały trudność grupie, dla mnie była oczywista. Dziękuję Clojure za twórczą znajomość.

Jak napisałem wcześniej - Scala jest trudna i pewnie dużo jeszcze upłynie czasu zanim rozważę zmianę zdania. Chylę czoła przed osobami, które śmiało przyznają się do porażki w jej poznaniu, a jeszcze bardziej przed tymi, którzy wiedzą, co w trawie piszczy. Szczęśliwie mnie to nie zraża i nie zamierzam składać broni. Bynajmniej. Po szkoleniu Grześka Scala wchodzi na plan pierwszy językowo (wybacz Clojure, niedługo wrócę do Ciebie, ale teraz są ważniejsze sprawy do poznania). Wciąż patrzę na Scalę przede wszystkim przez jej funkcyjne oblicze i w ten sposób utrzymuję kurs obrany kilka lat temu, kiedy postanowiłem zrozumieć zalety programowania funkcyjnego jako uzupełnienie lub nawet alternatywę dla programowania imperatywno-obiektowego. Teraz jeszcze dochodzi bagaż systemu typów (który Gilad Bracha określił jako...dokumentację i mniej nieistotny przy projektowaniu nowego języka Dart!)

Co mnie w tym wszystkim zdumiewa, to wszechobecna akceptacja Scali, który pomimo trudów okiełznania systemu typów i składni Scali, staję się coraz częściej językiem alternatywnym u programistów javowych, zamiast wejścia w...Clojure, który, przyznaję, wprowadza inną składnię, ale twierdzę, że mimo wszystko jest duuuużo prostszym językiem?!

Wracam do projektu scala-exercises. Zachęcam do udziału i wspólnej zabawy.

p.s. Dwa dni temu wyszła Scala 2.10.1-RC1, które ma być "designed to be a drop-in replacement for 2.10.0." Wciąż jeszcze mam wybór wersji języka, więc szybko uaktualniam. I Ty również nie czekaj, zanim nie będzie za późno.

15 lutego 2013

Chcesz zasmakować Scali? Może Venkat pomoże?

0 komentarzy
Na forum Warszawa JUG Bartek Zdanowski wrzucił namiary na nagrania z JavaOne, na które zareagował Marcin Matuszak i zaproponował Scala Tricks Venkata Subramaniama.

Podchwyciłem pomysł i uruchomiłem nagranie. I tak się zrodziła mini-recenzja wystąpienia Venkata.

Kiedy włączyłem od razu poznałem głos Venkata. Przyjemny gość, którego miałem możliwość poznać osobiście podczas GeeCON, a może 33rd Degree i jakkolwiek może zmęczyć jego ciągły poziom zachwytu na wysokim poziomie, zostawiłem tę prezentację i...tak przeleciała mi godzina.

Nie trwało długo, kiedy zorientowałem się, że już widziałem tę prezentację, ale wtedy niewiele rozumiałem o Scali. Po pierwszej części warsztatów Grześka Balcerka i kilku artykułach i książce Functional Programming in Scala, było znacznie łatwiej, żeby nie napisać trywialnie. To może świadczyć, że prezentacja nie jest dla osób, które ze Scalą spędziły już kilka tygodni (chyba, że chcą nauczyć się, jak o niej mówić).

Czego nie znałem, to Venkat pokazał klasy anonimowe z new {} (około 20 minuty), więc pojawiło się natychmiast dobre uzasadnienie oglądania.

Na co zwróciłbym uwagę w kodzie Venkata, to użycie f zamiast acc przy 30 minucie, kiedy wprowadził pojęcie rekurencji ogonowej. acc jest
akumulatorem, który zbiera wynik częściowego obliczenia silni i sprawia, że rekurencja nie rozwali stosu. f to skrót dla funkcji i znajomość tego zapisu trochę mną wstrząsnęła, kiedy zobaczyłem f w sygnaturze, a bez wskazania, że to funkcja. Tutaj Venkat popełnił niewybaczalny błąd nazewniczy :-)

Również na uwagę zasługuje minuta 41, w której Venkat korzysta z przypisania element do krotki zamiast zrobić to już w momencie przypisania elementu mapy jako parametr do funkcji w map (przed =>). Po Clojure, zauważenie tzw. "destructuring assignment" (polecam Clojure: Destructuring) jest jakoś naturalne i doskonale wpasowuje się w jeszcze bardziej precyzyjne opisanie publicznego interfejsu z zachowaniem struktury danych, ale ze wskazaniem na jej wnętrze (zamiast rozbicia na pojedyncze elementy w sygnaturze funkcji).

"That's all I have. Thank you" :-)

Moja lista scalowa warta obejrzenia została właśnie zaktualizowana na YouTube. Dzięki Marcin za wskazanie!

10 lutego 2013

Nagranie z mojej prezentacji o Enterprise OSGi na scenie Warszawa JUG już jest

4 komentarzy
W zeszły wtorek miałem przyjemność zaprezentować Enterprise OSGi, którego nagranie właśnie trafiło do przestrzeni publicznej i jest dostępne na YouTube - Praktyczne wprowadzenie do OSGi i Enterprise OSGi - Jacek Laskowski. Sam(a) zobacz, co straciłeś(aś). A uważam, że wiele.

Oszczędzę sobie tym samym relacji, bo po komentarzach po spotkaniu, trudno byłoby mi być obiektywnym i zachować umiarkowanie. Oceny kilku uczestników świadczyły o dobrej zabawie podczas mojego wystąpienia, a o to zabiegałem najbardziej. Samej wiedzy nie było wiele, ale wystarczająco, aby pobudzić do dalszego rozpoznania tematu we własnym zakresie. Bardzo zależało mi również na prezentacji możliwości WebSphere Liberty Profile i jak słyszę, to ma szansę znaleźć swoje miejsce u kilku z Was. Dzięki i daj znać, jak idzie poznawanie kolejnego serwera aplikacyjnego. Możesz być mile zaskoczony(a) możliwościami!

Sam przykład niestety nie odpalił, ale ostatecznie uważam, że to i tak dobrze, bo zainteresowanych tym mocniej zachęci do własnych prób. Ciekawym Waszych doświadczeń odnośnie poznawania Enterprise OSGi i jego zastosowania w projektach. Pewnie zastanawia Was, czy dałoby się pożenić tę technologię ze Scalą (hej, skąd w ogóle pomysł na taki mariaż?!) i po sobotnim szkoleniu Grzegorza nie mam złudzeń, że tak (ach, teraz rozumiem, skąd ten pomysł). A może już ktoś się z tym próbował? Jakie rezultaty?

Dostałem w międzyczasie maila:

"Mógłbyś podpowiedzieć jak/gdzie/od czego mogę zacząć, żebym mógł czerpać z korzyści liberty w codziennej pracy? Póki co potwierdzam, to o czym wczoraj mówileś (developerom przeszkadza ciężkość WASa)."

i pomyślałem, że umieszczę odpowiedź i tutaj. A może się komuś jeszcze przyda?! Oto ona.

"Zacznij od pobrania Eclipse IDE i instalacji IBM WebSphere Application Server V8.5 Liberty Profile Developer Tools V8.5.1.

Później przejdź przez moje artykuły na Wiki:
Po nich poczujesz klimaty. Brakuje jeszcze opisu instalacji WebSphere Liberty Profile, ale to sprowadza się do jego pobrania ze stronki http://wasdev.net/, rozpakowania i działasz!

Pytaj, jeśli coś niejasne. W ten sposób uzupełnię braki na Wiki. Powodzenia!"

04 lutego 2013

Sobotnia społecznościówka w Łodzi na Przyszłość w IT

3 komentarzy
Jest sobota, godzina 12:30, stacja Łódź Kaliska. Wysiadam z pociągu.

Jadę do, jak się później dowiedziałem, świeżo postawionego hotelu Holiday Inn na ul. Piotrkowskiej 229/231.

Jak na konferencję informatyczną "Przyszłość w IT" w samym centrum Łodzi, to niewiele osób kręciło się na parterze, przy recepcji, a jeszcze mniej określiłbym jako uczestnicy konferencji. Niedługo trwało, kiedy z tej garstki wyłonił się znajomy, z którym zacząłem dysputy nt. konferencji. Początkowa ocena konferencji niska.

Siadam w hallu i przeglądam slajdy. Ostatnie poprawki, wdrożenie przemyśleń z podróży i dopasowanie slajdów do miejsca. Zwykle sam nastrój przedkonferencyjny intensyfikuje moją pomysłowość i powstaje slajd "zgrywający" (patrz slajd o grywalizacji, chociaż ja nazwałem go grywalnością i tak mi się zrymowało).

Przysiada się Krzysiek Telka. W samą porę, bo jeszcze trochę, a pewnie mnogość pomysłów nie pozwoliłaby mi na dogranie slajdów do wersji finalnej. Zamykam komputer i gawędzimy.

Bodaj siedzieliśmy tak z godzinę, może ciut krócej. Krzysiek miał pewien problem z budowaniem aplikacji ze Spring Framework w NetBeans IDE, które muliło się przy każdej podpowiedzi, czego nie można było powiedzieć o JBoss Tools w Eclipse IDE. Nie znałem odpowiedzi, jak rozwiązać ten problem, ale zwróciłem uwagę na owe programowanie klikając - potwierdzenie, że w Javie wielu z nas programuje klikając zamiast korzystając z klawiatury. W Springu XML przybiera częstokroć masakryczne rozmiary i daje się we znaki przy próbie odsiania plew (znaczniki XML) oraz ziaren (springowych).

To mi przypomniało, że wprowadzenie notacji nawiasowej w Clojure do umysłów osób programujących aplikacje javowe można oprzeć właśnie na...XMLu. Pomysł polega zastąpieniu znaczników otwierających i zamykających na nawiasy i tyle (prawie).

Czy skoro potrafimy czytać XMLe i akceptujemy ich format, to może to być również argument ZA nawiasami w Clojure? Ciekawym opinii.

W międzyczasie pojawił się Marek Defeciński, który potwierdził moje przypuszczenie, że jego poranne (tak, tak, zmieniono harmonogram na ostatnią chwilę!) wystąpienie o referencjach faktycznie dotyczyło pakietu java.lang.ref. Zawsze sobie obiecywałem, aby przysiąść nad tym pakietem dłużej, ale jakoś tak się człowiek zebrać nie może. I niestety nie uczestniczyłem w prezentacji Marka, która była zbyt wcześnie jak dla mnie - siedziałem jeszcze w pociągu o tej porze. Z tego, co udało mi się zorientować, nagrania również nie ma.

Pojawił się na krótko Mariusz Saramak, ale zaganiany jakoś szybko zniknął. Za mobilny jak dla mnie :)

Z Krzyśkiem poszliśmy na wykład Cezarego Tarnowskiego "Osiągaj więcej - zmień podejście do pracy w zespole". Gość dobrze prawił i gdyby nie moje wystąpienie w innej sali, z przyjemnością zostałbym do samego końca. Udało mi się jednak wyłowić kilka cytatów, które później, za pozwoleniem Czarka, użyłem podczas mojej prezentacji. Wspólnie stworzyliśmy wspaniały zespół! Dzięki Czarek.


Wyłapałem kilka tez, które pozostaną w mojej głowie na dłużej, jak "Wiele kamieni milowych to wiele sukcesów, które motywują zespół", zespół jest bytem podstawowym (nie członek zespołu) oraz firma powinna budować środowisko do zawiązywania się zespołów. W tym ostatnim najbardziej przemówiło do mnie użycie terminu "zawiązywanie się", które przywodzi mi na myśl ziarno, które dobrze pielęgnowane przekształca się w roślinę (co kojarzy mi się bardzo pozytywnie). Jak później przekazałem Czarkowi, slajdy były do kitu i w zasadzie przeszkadzały swoim ochydztwem. Odstawały od reszty wystąpienia. Zrozumiałbym ludzi, którzy z zamkniętymi oczyma wsłuchiwaliby się w wypowiedzi Czarka. Pewnie byłyby jeszcze bardziej wartościowe. Odnoszę wrażenie, że bodaj każde zdanie niosło dla mnie jakąś wartość i zastanawiam się, czy to pora dnia, miejsce, czy osoba Czarka sprawiła, że, poza slajdami, prezentację mogę polecić każdemu. Jak się później dowiedziałem, była składana jakby na przysłowiowym kolanie, więc aż strach pomyśleć, co byłoby, gdyby Czarek zasiadł nad nią z większym zaangażowaniem!

I przyszła wreszcie moja chwila - społecznościowe budowanie oprogramowania z GitHub, Travis, Heroku i Clojure. Podobało mi się. Zmieściłem się w czasie! Była interakcja z publicznością. Padło co prawda jedno, dwa pytania, ale dało się również namówić publiczność na aktywność fizyczną - podnoszenie rąk. Na rozpoczęcie mojego wystąpienia zapytałem o użycie GitHuba do własnych prac. Podniosło rękę 7 osób. Po wykładzie, na pytanie o chęć użycia GitHuba, pojawił się las rąk! Cudnie.


Uradowane miny uczestników niech mówią same za siebie.

Prezentacja dostępna niebawem na SlideShare. Zapewne pojawi się wcześniej zajawka na twitterze.