niedziela, 10 maja 2015

In,Co,Contra - variance - Mem driven Learning

Z tematem po raz pierwszy zetknąłem się prawie dwa lata temu - http://pawelwlodarski.blogspot.com/2013/08/covariance-i-contravariance-dla.html i był to jeden z tych momentów kiedy zrozumiałem, że jeśli znam Javę i Springa to nie oznacza, że mogę twierdzić, że umiem programować.

W oryginalnym artykule sam próbowałem zrozumieć ten temat +A,-A,A, a że najlepsza nauka to próba wytłumaczenia komuś tego czego nie rozumiemy toteż to było pierwsze podejści. Do tego by pobudzić rozrywkowe obszary mózgu próbowałem użyć odpowiednia ilość razy słowo Dupa w kontekście domeny żłopu alkoholowego.

A że chlanie wódy to nie do końca zdrowe zajęcie plus jak jest za dużo tekstu to nikomu nie chce się czytać to spróbujmy innego podejścia.

The Box

Nie chodzi o film z Cameron Diaz z 2009, który opowiadał o złudnym poczuciu braku konsekwencji z samolubnych wyborów - http://www.imdb.com/title/tt0362478/

Generalnie te wszystkie ...variance tłumaczy się w kontekście typu, który jakoś opakowuje lub jest parametryzowany przez inny typ- M[T]. Na przykład Option[A],Try[A] czy List[A]

Przykład z listą jest niby wytłumaczyć najprościej bo to jest też w javię w cudownej postaci List<? extends User> czy List<? super User>. Co wygląda trochę dziwnie ale jest.

Natomiast w kwestii Coś opakowuje coś ludzie zapominają o klasyce :

Dla tych, którzy nie znają angielskiego "Dick" to imię wieloryba z przygód "Janka Muzykanta" http://www.filmweb.pl/film/Moby+Dick-1956-32061

Mem Driven Learning

wtorek, 5 maja 2015

Mechanika funkcji - zapowiedź warsztatów kilku

{tutaj wstaw dowolny fragment, który przekonuje cię do nauki programowania funkcyjnego}. Ale zanim zaczniemy uczyć się o Fabrykach monad i funktorach może warto przysiąść przy kawałkach kodu scali, które nie wiadomo dlaczego maja kilka par nawiasów zamiast jednej czy zrozumieć dlaczego w Playu przy tworzeniu konwerterów JSONa trzeba było pisać (_.tupled _)

Warsztaty

Warsztatów wyszło na 2.5 części :

Jest w sumie 10 zadań + różne takie ciekawe drążenia czaszki.

Czego będzie można się nauczyć

  1. Funkcja jako wartość - z tego co widziałem to programistą JAvy często wiesza się proces gdy coś co ma typ => w typ przekazują do czegoś co też ma typ => w typ
  2. Różne formy zapisu funkcji jak choćby : val f3:Int=>Int= _ + 3
  3. Coś na co nie zwracało się uwagi w Javie (do niedawna) kiedy funkcja to funkcja a kiedy metoda i kiedy metoda to metoda a kiedy funkcja.
  4. I coś moim zdaniem bardzo ważnego by nie odkleić się od rzeczywistości - przykłady ze słowami, które mogą pojawić się w codziennym życiu a nie tylko w książce od matematyki :
    //To na tę chwilę jedynie aliasy
    type Cash=Int
    type Policy= Cash=>Boolean
    type BusinessLogic= Cash=>Cash
    
    //Logika abstrakcyjna
    def cashService(p:Policy)(l:BusinessLogic)(c:Cash):Cash={
      if(p(c)) l(c) else 0
    }
    
    //niezależne i łątwe do testów funkcje
    def strictPolicy(c:Cash)=c>50
    def moneyMakesMoney(c:Cash)=c*1000
    
    //konkretna usługa
    val bank=cashService(strictPolicy)(moneyMakesMoney)_
    bank(100)  //res0: Cash = 100000
    bank(10)    //res1: Cash = 0
    
  5. Funkcje częściowe - po co są i jak są wygodne
  6. Lift,Lifting,Liftowanie,Podnoszenie - czy jak to się tam zwie - to już ciekawy koncept z FP jako takiego :
    val tekst: PartialFunction[String,String] = {
      case "tekst" => "TEKST"
    }
    //tekst: PartialFunction[String,String] = 
    
    val tekstLifted=tekst.lift //tekstLifted: String => Option[String] =  !!!
    tekstLifted("dupa")  //res0: Option[String] = None
    tekst("dupa") // scala.MatchError: dupa (of class java.lang.String)
    
    //i na powrót
    Function.unlift(tekstLifted) //res1: PartialFunction[String,String] = 
    
  7. I masa innych ciekawych rzeczy

Pierwszy warsztat pewnie uda się zrobić w drugiej połowie maja a drugą część jakoś na początku czerwca. Trzeba wycelować w złą pogodę i tyle.

Scala & Java 8

Spróbujmy zdefiniować sobie prostego acz zakręconego
Jest zwykła funkcja Int=>Int
zdefiniujmy funkcję, która zmodyfikuje tę pierwotną funkcję funkcję. (Int=>Int) => (Int=>Int)
Stwórzmy funkcję dekorującą, która przyjmie jakiś parametr typu Int Int=>....
zrobi currying Int=>(Int=>Int)
i zwróci funkcję, która przyjmuje pierwotną funkcję i dekoruje ją tak, że do wyniku dodaje podany wcześniej parametr i

val funkcja=(i:Int)=>(f:Int=>Int)=>(arg:Int)=>f(arg)+i
//typ to funkcja: Int => ((Int => Int) => (Int => Int)) = 
//wywołanie 
val curried=funkcja(2) curried: (Int => Int) => (Int => Int) = 
curried(_*5)(2) //12

Kompilator scali jak długo by nie pracował bardzo pomaga bo możemy skupić się na tym co po prawej
(i:Int)=>(f:Int=>Int)=>(arg:Int)=>f(arg)+i a typy zgadnie sam.
Jeśli bardzo chcemy możemy dać cały typ przy deklaracji:
val funkcja:Int => ((Int => Int) => (Int => Int))= i =>f => arg=>f(arg)+i
Albo wszystko na raz :
val funkcja2:Int => ((Int => Int) => (Int => Int))= (i:Int) =>(f:Int=>Int)=>(arg:Int)=>f(arg)+i

A jak to wygląda w Javie 8? Tutaj za dużo pomocy nie ma (albo ja coś robię źle) :

Function<Integer,Function<Function<Integer,Integer>,Function<Integer,Integer>>> function= i -> f -> (arg) -> f.apply(arg)+i;
Function<Function<Integer, Integer>, Function<Integer, Integer>> curried = function.apply(2);
Integer result = curried.apply(i -> i * 5).apply(2);

Linki i Nagrania z JUGa

Hello world w c++

object endl

//not thread safe!
object cout{
  private var texts=Vector.empty[String]
  def <<(s:String)={
    texts=texts :+ s
    cout
  }
  def <<(e :endl.type)=texts foreach print
}

cout << "Hello" <<" "<< "World c++" << endl;

------------------------------------------------------------------------------------------------------------------

niedziela, 12 kwietnia 2015

W głąb Value Classes,Warsztaty ze ScalaCheck,Scalar

Temat pojawił się na warsztatach : Czy jeśli klasa rozszerza AnyVal i się wywali w Runtimime to co dokładnie będzie widać w stacktrace? Czy będzie informacja o tym, ze to była klasa czy też będzie tam widniał typ prymitywny?

Odpowiedź na tak postawione pytanie brzmi "Tak, masz rację, teraz mnie zostaw w spokoju"

Labolatorium

Na początek przygotujmy aparaturę badawczą

class Domenowa(val s:String) extends AnyVal
Ćwiczenie pierwsze - zrobić aby coś się wywaliło. Wrzućmy granat w środek :
val d=new Domenowa(null)
"Exception in thread "main" java.lang.NullPointerException
 at com.wlodar.nauka.oop.Domenowa$.hashCode$extension"
Zaraz zajrzymy pod mikroskop ale najpierw jeszcze jedna wypierdółka :
class Domenowa(val s:String) extends AnyVal{
    null.toString
  }

I tu się tego nie spodziewałem :
Error:(18, 10) this statement is not allowed in value class
    null.toString
         ^
Wygląda na to, ze ValueClasses w ogóle nie mogą mieć konstruktorów.
To jeszcze inaczej :
class Domenowa(val s:String) extends AnyVal{
    def logic=null.toString
}
I się wywaliło :
Exception in thread "main" java.lang.NullPointerException
 at com.wlodar.nauka.oop.Domenowa$.logic$extension

Pod oscyloskop go

Po kompilacji mamy tka naprawdę dwie klasy. Ta Domenowa$ nie pojawia się gdy nie rozszerzamy AnyVal
-rw-rw-r-- 1 pawel pawel 1875 kwi 12 21:22 Domenowa.class
-rw-rw-r-- 1 pawel pawel 1170 kwi 12 21:22 Domenowa$.class

javap Domenowa

public final class com.wlodar.nauka.oop.Domenowa {
  public static boolean equals$extension(java.lang.String, java.lang.Object);
  public static int hashCode$extension(java.lang.String);
  public static java.lang.String logic$extension(java.lang.String);
  public java.lang.String s();
  public java.lang.String logic();
  public int hashCode();
  public boolean equals(java.lang.Object);
  public com.wlodar.nauka.oop.Domenowa(java.lang.String);
}

javap Domenowa$

public final class com.wlodar.nauka.oop.Domenowa$ {
  public static final com.wlodar.nauka.oop.Domenowa$ MODULE$;
  public static {};
  public final java.lang.String logic$extension(java.lang.String);
  public final int hashCode$extension(java.lang.String);
  public final boolean equals$extension(java.lang.String, java.lang.Object);
}

Strzelam, że kiedy wywoływana jest metoda logic na klasie Domenowej to gdzieś tam pod spodem ten string ze środka jest przekazywany do tego logic$extension(java.lang.String). Jest jedna instancja Domenowa$, ValueClasses nie maja pól to nei ma stanu i to wszystko tak działa (chyba). Postanowiłem zdekompilowac kod z opcja -c by zobaczyć bytecoda
 public final java.lang.String logic$extension(java.lang.String);
    Code:
       0: aconst_null
       1: invokevirtual #18                 // Method java/lang/Object.toString:()Ljava/lang/String;
       4: areturn

Po czym się zastanowiłem po co właściwie chce go zobaczyć jak i tak się na tym nie znam?

To może jednak prościej

Potwórzmy kilka identycznych klas.
class Domenowa(val s:String) extends AnyVal{
    def logic=this.toString()
  }

println(new Domenowa("abc"))
    println(new Domenowa("abc"))
    println(new Domenowa("abc"))
    println(new Domenowa("abc"))
    println(new Domenowa("abc2"))
    println(new Domenowa("abc2"))
    println(new Domenowa("abc").logic)
    println(new Domenowa("abc").logic)
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@2d9410
com.wlodar.nauka.oop.Domenowa@2d9410
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@17862
I cuda. Jak jest ten sam string to i jest ta sama referencja. Jeśli dla eksperymentu usuniemy extends AnyVal to już to nie działa. Czyli tu nie działa przez co udowadniamy , że ogólnie mechanizm jak taki działa.
class Domenowa(val s:String){
    def logic=this.toString()
  }

com.wlodar.nauka.oop.Domenowa@48140564
com.wlodar.nauka.oop.Domenowa@58ceff1
com.wlodar.nauka.oop.Domenowa@7c30a502
com.wlodar.nauka.oop.Domenowa@49e4cb85
com.wlodar.nauka.oop.Domenowa@2133c8f8
com.wlodar.nauka.oop.Domenowa@43a25848
com.wlodar.nauka.oop.Domenowa@3ac3fd8b
com.wlodar.nauka.oop.Domenowa@5594a1b5
wracamy do class Domenowa(val s:String) extends AnyVal{ def logic=this.toString() } Znowu zdekompiluje bytecod Domenowa$ (sam nie wiem po co).
 public final java.lang.String logic$extension(java.lang.String);
    Code:
       0: new           #16                 // class com/wlodar/nauka/oop/Domenowa
       3: dup
       4: aload_1
       5: invokespecial #19                 // Method com/wlodar/nauka/oop/Domenowa."":(Ljava/lang/String;)V
       8: invokevirtual #23                 // Method java/lang/Object.toString:()Ljava/lang/String;
      11: areturn

i niby tutaj jest instrukcja new, która tworzy klasę domenową. Według dokumentacji to alokuje nową instancję a jednak sprawdzaliśmy, że tak się nie dzieje. Co umacnia mnie w przekonaniu, ze na bytecodzie Javy się nie znam.
http://docs.scala-lang.org/overviews/core/value-classes.html

Najbliższe spotkania i warsztaty ze Scalacheck

W Maju/Czerwcu przyjedzie Damian Warszawski z Touka z warsztatem o Javie8 :
"
żeby się nie zastanawiać za długo to moja propozycja warsztatu: 

Intro to java8 workshop: 
agenda: 
Lambda Expressions 
Stream API 
DateTime package 

W ciągu tygodnia przygotuje repo na githubie i przygotuje krótki opis warsztatu.
"

I jeszcze jakoś na początku maja Cezary Draus który też pracuje w Touku (oraz pociągu relacji Łódź-Warszawa) zrobi warsztaty z intellij.

W tym wszystkim jedyny rozsądny termin w jaki mogę się wcisnąć z warsztatami to 20 kwietnia : Scalacheck i Property Based Testing - Warsztaty

Będą trzy iventy w tygodniu ale damy radę.

Scalar

W końcu laptop wygląda jak laptop do programowania :
Muszę sobie załatwić drugi zestaw na komputer w pracy zanim mi ktoś nie przylepi naklejek : "Sharepoint,Excel,Outlook,Ms Project,UML "
Konferencja była fajna i dłuższej relacji pisać nie będę bo ludzie później nie kumają dowcipów i rzucają kamieniami w okna :D Było fajnie i tyle.