23. 5. 2013

GeeCON 2013 - 3. den

Zápisky z třetího dne konference GeeCON 2013

První den zde. Druhý den zde.

Bodil Stokke: What Every Hipster Should Know About Functional Programming

Konečně přednáška o funkcionálním programování, u které jsem rozuměl použitému jazyku. Typescript vůbec není špatná věc. (Podle toho, jak jsem se o něm bavil s jinými programátory, zaznamenávám nejen poměrně pozitivní ohlas na samotný jazyk, ale i jakýsi druh příjemného překvapení související s tím, že autorem je Microsoft.)
Před přednáškou jsem se ještě díval na biografii přednášející, a protože mi nebyla jasná poslední věta, potřeboval jsem si doplnit vzdělání. To se nakonec ukázalo jako osudně rozhodující krok k pochopení přednášky, protože veškeré příklady pak obsahovaly postavy z tohoto seriálu.
Po stručném přehledu základních paradigmat a pár teoretických slajdech přednášející ukázala na jednoduchých příkladech základní pojmy:
  • first class functions = functions are values, can be passed or returned  as argument
    • priklad: hello() je funkce x hello je proměnná (v níž je přiřazená funkce)
  • functor is collection of X that can apply function f: X->Y over itself to create collection of Y
    function map(func: (a:any)=>any, list: any[]) : any[] {
       for (i...) newlist.push(func(list[i]));
    }
  • rozdíl ponies x map(CAPS,ponies) (ponies je seznam, CAPS je funkce pro převod na uppercase) 
  • funktor = např. filter nebo redukce:
    function reduce(func:(a,b)=>any, list:any[], initial) {...}
    reduce(add,[1,2,3,4,5],0);
  • funkce vyšších řádů jsou vlastně abstraktní továrny na funkce
    mapReducer(func:(a:any) => any) {
        return function(a,b) {
            return a.concat(func(b));
        }
    }
    reduce(mapReducer(CAPS),ponies,[]) 
  • combinators
    function square(x:number):number {return x*x;}
    function addThree(func) {return function(x) {return func(x)+3}}
    addThree(square)(5) ... 28
    • praktičtější aplikace: nullSafe - ošetří volání funkce na null a tváří se jako funkce
  • kompozice funkcí
    function CAPS ... převede na uppercase
    function hi ... vypíše hello arg
    func compose(f1,f2) {return function(x:any) {return f2(f1(x));}}
    compose(hi,CAPS)("everypony") ... totéž co CAPS(hi("everypony"))
  • applicative functors, příklad s kombinací dvou listů - kartézský součin, aplikuje mapu na 2 listy
  • currying (schonfinkeling) - transformuje funkci o mnoha argumentech na řetěz funkcí o 1 argumentu tak, že posloupnost volání dává identický výsledek (tady už to začínalo houstnout a nešlo opisovat, nicméně lepší než na fotky je podívat se přímo na prezentaci)
  • partial application
  • monads 
Celkově oceňuji názornost příkladů a motivaci podívat se na Typescript. Příklady ke konci si ještě budu muset projet, protože pak už jsem nestíhal.

Ken Sipe: Making Java Unit Test Groovy with Spock

Přednáška o Groovy testovacím frameworku Spock. Opět jedna z kvalitnějších přednášek s mnoha praktickými ukázkami. Spock je framework založený na JUnit umožňující psát testy formou specifikace předpokladů a následných očekávání přímo do testovací metody. Pomáhá řešit také další související situace při psaní testů, např. zastínění jednoho předpokladu druhým (neotestování dalšího při selhání prvního) nebo testy s parametry. Využívá k tomu sílu jazyka Groovy umožňující definovat podmínky a očekávané chování pomocí srozumitelného DSL.
  • anotace umožňují vynechat test při splnění/nesplnění určitých podmínek
    @IgnoreIf({!jvm.java8})
    def java8feature() { ... expect: friends.stream().getFirst() != null;}
    
    nebo naopak
    @Requires({jvm.java8})
    
    Zde se uplatňují výhody dynamického jazyka, ve statickém by se to díky .stream() pro Javu nižší než 8 nezkompilovalo.
  • názvy metod v groovy mohou být řetězce s mezerou. Oproti Javě, kde se u názvu metod musíme přizpůsobit syntaxi identifikátoru a řešit to různými náhražkami v podobě podtržítek a velbloudí konvence, tohle je další výhoda Groovy - čitelnější popis, dokumentace je součástí názvu metody.
  • zápis testu - given: ... when: ... then: ...
    • given odpovídá setUp resp. @Before
    • when je jako obsah testu před asserty - vlastní stimul
    • then odpovídá assertům - testuje odpověď
  • lze testovat i mocky
    def subscriber1 = Mock(Subscriber)
    Subscriber subscriber1 = Mock()  - ekvivalentní zápis
  • flexibilní zápis testu pomocí přetížených operátorů, lambd nebo wildcard podtržítek:
    • 1 * subscriber1.receive("event") ... na instanci subscriber1 byla jednou volána metoda receive s uvedeným parametrem
    • receive(!null) ... voláno receive s čímkoli různým od null
    • receive({String s -> s.contains("event"}) ... vlastní ověřovací lambda výraz
    • subscriber1./rec.*/(!null)  ... volána metoda, jejíž název splňuje regex
    • subscriber.receive(_ as String) ... nebo jejíž parametr je cokoli určitého typu
    • 2 * _.receive ... ale nerozlišuje, zda byla na jednom mocku zavolána metoda dvakrát nebo na dvou mockách po jednom
    • _ * _._(_)  ... validní zápis - libovolný počet volání libovolné metody s libovolnými argumenty na libovolném objektu
  • expect: je when a then zároveň, je to šablona pro nějaký testovací příklad
  • where: je pro doplnění parametrů do šablony, při syntaxi parametr << [list] to doplňuje parametry ze seznamu. Pokud je více parametrů, berou se pro příslušný běh testu stejnolehlé hodnoty ze všech seznamů.
  • cool feature - pokud nastane chyba, vymaluje to jednoduchý ascii art vyznačující volání a pomocí svislítek popis argumentu metody a místa chyby (mám rád ascii malůvky)
  • parametry pro expect/where lze zapsat i ve formě tabulky á la wiki, v buňce tabulky může být i volání metody
  • @Shared - použít pro resource náročný na tvorbu, existuje na úrovni třídy a mohou přes něj spolu komunikovat jednotlivé testovací metody, podobné použití static fieldů u obyčejného JUnitu.
  • old() closure - přístup na původní hodnoty před spuštěním testu
    then: map.example != old(map.example)
  • násobná klauzule then definuje, že očekáváme testované interakce v daném pořadí (naproti tomu více podmínek v jedné klauzuli then představuje podmínky testované jako celek)
  • možnost vlastních anotací na testech a další řízení testů podle anotací. Příklad:
    definice vlastních anotací:
    @Fast, @Slow
    použití:
    runner {
        exclude {
            annotation Slow
        }
    }
    Na našem Java projektu něco podobného máme a oproti Spocku je to celkem pracné.
  • extension annotation - umožňují nadefinovat si vlastní anotace, pověsit je na proces testování (specifikaci) a udělat kód onSuccess nebo onFailure (ukázka kódu, který na chybu reagoval promluvením "Failure is not an option"). Podobnou věc jsem si jednou udělal i v Javě (úspěch zahrál fanfáru, neúspěch zvuk havárie), ale bylo nutné se pořádně vlomit do tříd JUnitu.
  • další menší poznámky: anotace @Stepwise, Hamcrest expect: ... that ..., JUnit Rules už přednášející nestihl, protože značně přetáhl, ale mně osobně to vůbec nevadilo
Shrnutí: přednáška zvýšila nejen můj zájem o Spock, ale i o samotné Groovy. Není sice u nás reálné přejít s projektem na Groovy a statické jazyky kvůli typové kontrole stále preferuji. Nicméně v případě některých testů si dovedu představit úsporu práce, pokud by byly založeny na tandemu Groovy+Spock.
Za povšimnutí stojí i jednotlivé konstrukce a DSL (wiki tabulka, přetížení operátorů, klauzule). Tyto zápisy jsou sice elegantní, ale domnívám se, že je potřeba dobře znát, na jakém jazykovém principu jsou postaveny. Přistupovat k nim bez znalosti Groovy jako k magii, která funguje, se může vymstít, (resp. to člověka stejně přinutí pochopit, až s tím bude experimentovat).

Piotr Gabryanczyk: Typeclasses, Monads - Functional and simple!


Přednáška orientovaná na Scalu a NoSQL databázi Cassandra, aspekty funkcionálního programování tam byly zmíněny tak, že už to teď nedám dohromady. Poslouchal jsem jen napůl a stejně jsem v polovině odešel. Ostatní témata ve slotu mne nelákala, proto jsem využil čas alespoň pro vyzkoušení obou mindballů (ilustrační fota) na stáncích YSoftu, kde bylo jinak o přestávkách narváno. A musím uznat, že to fakt funguje :-).

Bert Ertman, Paul Bakker: Building Modular Cloud Applications in Java - Lessons Learned

Architektonická přednáška předvádějící cloudovou aplikaci postavenou na OSGi pro podporu učení pro děti. Cloudové aplikace jsou pro mě jako programátora nevyzkoušená věc, přednášku jsem si proto vybral záměrně. Architektura založená na HTML5 + javascriptu, RESTful ws, OSGi servisách, OSGi frameworku Amdatu a Eclipse pluginu BndTools, které napomáhají modularitě, a MongoDB. Střípky:
  • důraz na modularitu - schopnost vyměnit část za běhu
  • autoscaling - během školního vyučování se očekává větší zátěž -> potřebují kapacitu, ale neplatit za idle provoz serverů v noci -> Amazon autoscaling
  • bezestavová architektura - dobrá škálovatelnost (HTML5 umožňuje více bezestavové klienty, zmínka o Angular.js)
  • tip na knihu: Building modular applications (O'Reilly)

Discussion panel: Functional Programming - radical thinking shift and step towards clearer and reliable software

Formát diskusního panelu jsem na GeeCONu ještě nezažil a toto znělo podle názvu slibně. Diskuse se účastnilo 7 hostů + moderátor. Byla to zčásti teoretická, zčásti praktická diskuse, asi podle povahy jednotlivých hostů. První půl hodiny však nebyl prostor pro otázky publika, a i potom se ke každé otázce vyjadřovala většina hostů, takže na konci bylo hodně tazatelů, na které se nedostalo. Zajímavosti:
  • citát Martina Oderskeho (přibližně): je výzvou pro dnešní dobu, jak provést přechod z imperativního na paralelní distribuované programování při zohlednění omezených schopností lidské mysli, které jsou třeba k jeho zvládnutí
  • vylepšení paralelismu je řízeno modernizací hardwaru, hardware už je dnes lepší a může podporovat náročnější paradigma
  • funkcionální programování je jen prostředek k dosažení paralelismu
  • neexistuje čistě funkcionální jazyk (M. Odersky)
  • nejde říct o jazyku, že je funkcionální, ale že některé jeho rysy jsou funkcionální
  • změna paradigmatu je větší problém než změna jazyka
  • otázka, jak dlouho bude trvat adopce paradigmatu v business světě

Sven Peters: How To Do Kick-Ass Software Development (závěrečná keynote)

Odlehčená přednáška na závěr, nicméně i tak s hodnotnými informacemi. Pojem vypůjčen z filmu Kick-ass (český překlad Nářez), který jsem neviděl, ale z kontextu (tím, jak tento pojem přednášející používal v každé druhé větě) se tomu dá rozumět jako "pořádný", "úžasný", dobrý postřeh měli taky kluci, že by to šlo nahradit za "agilní". Přednášející ze společnosti Atlassian (JIRA).
  • diabolical developer: compiles? == ship it!
  • team which works with legacy code != legacy team == hard to refactor if member leaves, adding processes helps, old decisions still apply, changing stuff is too complicated
  • deliver kickass software
    • kickass feedback - musí být jednoduchý, ne: vidět chybu, mít odkaz úplně jinde, odkaz zavede do JIRA, projdu wizardem, registrací a pak musím vyplnit x polí formuláře
    • easy to find, fast to submit
    • protect your developers
    • google sh't umbrealla: 425mil. users, 100 developers
    • týmy dělají daily meeting 1/2 hod. jen nad feedbackem
  • have kickass teams
    • Developer On Test - dejte testování developerům
    • QA = Quality Assistance (ne Assurance)
    • 6 tips for kickass DoTing
      • training - týdenní školení, jak psát testy, pro všechny developery
      • pairing
      • blitz test - všichni se podílí na testování důležité funkcionality, odhalí hodně chyb
      • test recipe
      • split sessions - opposite of pairing, dev a tester testují jiným způsobem
      • bug hunter - člen týmu, který se snaží to shodit
    • quality is everybody's responsibility
    • developers are doing design
    • "jednou jsem dělal GUI a dopadlo to takhle: (plný panel fieldů a checkboxů)", "pak jsem k tomu přidal barvy (strašně nabarvená složitá aplikace)"
    • design workshop for developers
    • designers are also developers - umi zaklady gitu, html atd.
  • kickass collaboration
    • lone cowboy x trouble starts with team
    • development rules protecting from making mistakes as traffic rules from accidents
    • fast,simple workflow for parallel coding
    • pull requests - what do you think?
    • atlassians prefer collocated teams - everybody in one office
    • vyhýbejte se emailům (alternativa: chatroom v ramci firmy, twitterový formát zmínky o jiném člověku: @someone)
    • v Atlassian chatují i lidi ve stejné místnosti - sluchátka na uších udržují v zóně soustředění
  • kickass automation
    • kolik času strávíte týdně automatizací vašeho softwarového vývoje?
    • buildy - dlouhé, složité, nestabilní, bez koncepce
    • 4 rady, jak se vypořádat s monster buildy
      • vynechat součást buildu, která to zpomaluje
      • paralelizovat testy
      • mít strategii buildů, např. zbuildování projektu a unit testy pokaždé, integrační testy 1x/hod., výkonové 1x/noc
      • sledovat statistiky
    • rychlé buildy = snížené přepínání vývojářů mezi úkoly
    • viditelné výsledky testů: wallboards, televize s dashboardem
    • freud bot - statická analýza kódu v pull requestu
    • release button = single push deployment
  • další kickass věci mimo vývoj softwaru: rychlost vývoje, kvalita, škálovatelnost, tým, zákazník - vše kickass
  • hledejte cesty, jak to zlepšit - ohnout pro váš tým, ne jak poslouchat nějakého gurua
  • manažeři jsou lidi, někteří se nechají přesvědčit snadněji, někteří obtížněji (u každého ilustrativní foto, u "obtížněji" to bylo foto Larryho Ellisona :-)
  • share success and failures
  • kickass firemní kultura
  • můžu si na konci dne říct: did I kickass today?

Shrnutí

Automatizace, funkcionální programování, cloudové aplikace a testování patřily mezi nejčastější témata konference. Nejvíce mne obohatily přednášky s praktickými kusy kódu, obzvlášť pokud si přednášející troufnul na live demo.
Na závěr bych také rád poděkoval společnosti YSoft, díky které jsem měl na konferenci volnou vstupenku. Budeme o GeeCON také mít lightning talk na některém setkání CZJUG. Tyto články i lightning talk jsou výsledkem snahy předat získaný užitek zas dál.

21. 5. 2013

GeeCON 2013 - 2. den

Zápisky z druhého dne konference GeeCON 2013

První den.

Oliver Gierke: Data Access 2.0? Please welcome - Spring Data!

Spring Data je knihovna Springu pro přístup k NoSQL databázím. Klasický springový přístup využívající návrhový vzor Template Method, podobně jako u relačních databází je JdbcTemplate nebo u JMS JmsTemplate.
  • zdůrazňoval, že Spring Data se snaží zachovat specifické vlastnosti konkrétních NoSQL databází (u NoSQL databází je vzájemná odlišnost přece jen větší než u relačních), např. podpora zeměpisných souřadnic u Monga
  • ukázky pro Mongo a Neo4J
  • Spring Data definuje vlastní anotace mající zhruba ekvivalent v JPA. Právě proto, že Spring Data je jen projekt zastřešující menší podprojekty pro konkrétní NoSQL databáze, má každý podprojekt na míru ušitou sadu anotací. Např. @Entity z JPA odpovídá u Monga @Document, u Neo4J @NodeEntity
  • MongoTemplate - obdoba JdbcTemplate
  • repositories - obdoba DAO u JDBC
  • možnost definovat dotaz anotací @Query v signatuře DAO metody a anotacemi parametrů metody vyznačit navázání parametrů dotazu
  • plugin do IDE dokáže zpracovat anotované třídy a vylepšit podle nich nápovědu jmen. Např. za findBy nabídne Name, pokud má entita takovou property
  • QueryDslPredicateExecutor - vyjádření dotazu pomocí predikátu, metoda findAll
  • integrace s CDI
  • DZone refcard pro projekt Spring Data (přednášející je leader projektu a zároveň autor taháku)

Jessica Kerr: Object-Oriented Design in the Wild

Poměrně informativní přednáška především v mluveném slovu, slajdy hrály spíš roli vyvolání emocí, bavení a dotvoření celkového efektu. Oceňuji především rozvedení základních principů OOD: SOLID, DRY, YAGNI a pár dalších. Po zhlédnutí přednášky stojí za to si je znovu projít na stránce Principy OOD nebo aspoň na wikipedii.
  • úvod o typech, třídách atd., porovnání Java/Haskell
  • rajský obrázek s podmanivou hudbou a zasněným prohlášením "Ruby is my developer joy" (u Haskellu protikladný projev) - docela vtipné
  • Single responsibility principle (S v SOLID)
    • třída by měla mít pouze jeden důvod ke změně
    • příklad se zbožím, které je na skladu, lze ho koupit a prodat:
    • Java: class Good implements InvItem,Purchase,Sellable
    • Ruby: class Good include InvItem include Purchase...
  • Interface segregation principle (I v SOLID)
    • deklarujte nejmenší možný interface
  • Liskov substitution principle (L v SOLID)
    • podtřída má properties nadtřídy, ale nemění jejich význam
    • LSP=PLS=Principle of Least Surprise
    • překvapením může být: přístup na globální stav, změna vstupního argumentu, změna okolí třídy, porušení očekávání
  • Dependency inversion principle (D v SOLID)
    • části by neměly o sobě vědět, přirovnání k linuxu: cat data.csv | grep 42 | cut -f2 | sort
  • Open-closed principle (O v SOLID)
    • knihovna je "closed for modification", ale "open for extension" aplikací, která ji používá
  • cohesion x coupling
  • Reuse-Release equivalency principle - znovupoužití kódu by mělo být umožněno ne kopírováním, ale pouze v releasech, u nichž je uživatel odstíněn od vnitřní implementace a jejichž vydání je patřičně komunikováno. Uvedla Guavu jako ukázku dodržování tohoto principu.
  • napsat komponentu s tím, že je předem plánována pro znovupoužití, je předčasná optimalizace (kořen všeho zla - Donald Knuth). Podepisuji to z vlastní zkušenosti: jakákoli i třeba dobře myšlená aktivita (nejen kus softwaru, ale třeba zavedení používání nějakého nástroje nebo firemního procesu), která vznikne rozhodnutím někoho od stolu, je odsouzena k tomu, že ji nikdo nepoužívá, nezvykne si na ni a nepřijme za vlastní. Musí vzniknout reaktivně, ne proaktivně.
  • Acyclic dependencies principle
  • Stable dependency principle
    • komponenta, na které někdo závisí, by měla být stabilnější než závisející komponenta
    • Příklad: stabilita roste zleva doprava: javascript na stránce -> JQuery -> browser
  • Stable abstraction principle
    • když mám modelovat tygra, nemodeluju ho jako něco, co implementuje rozhraní kočka a rozhraní zvíře v džungli, ale prostě jako tygra, jinak je to přeabstrahováno
  • nalézt zlatou střední cestu mezi znovupoužitelným a abstraktním
  • princip DRY
    • nepřehánět to a moc nevysušovat, nebo vznikne poušť
    • příklad: na řadě míst se vyskytuje formátování datumu, někdo z toho v dobré víře udělá společnou komponentu, ale to může být špatně, protože každý výskyt může formátovat podle jiných národních zvyklostí
    • někdy je copypaste lepší alternativa než zavlečení další závislosti na společné logice
  • princip YAGNI - kill zombie code, případně zakomentovat
  • každé pravidlo pomáhá jen do té míry, do jaké nasměruje správným směrem
  • starý kód je často lepší, protože již prokázal svůj přínos
  • svoboda porušit pravidla, pokud to dává smysl - používat selský rozum

Tom Bujok: SOAP sucks, doesn't it?

Pro mě nejlepší přednáška druhého dne. Uklidnila mě, že nejsem sám, komu připadá práce se SOAP webservisami přes nízkoúrovňové XML jednodušší a intuitivnější než přes heavyweight stacky jako CXF, Axis nebo Metro. Když jsme měli na projektu implementovat webservisy, rozhodl jsem se použít Spring Web Services (tehdy ale ještě ve verzi 1.5.9, podpora testů ještě nebyla součástí a musela se použít úžasná knihovna Lukáše Křečana) a nad nimi udělat jen tenkou vrstvu pro potřeby projektu. Tady zašli ještě dál a udělali nad Spring WS poměrně flexibilní, intuitivní a stručné API - knihovnu Reficio SOAP-WS.
Můj pohled na webservisy hodně utvářel článek Arjena Poutsmy (project leadera Spring WS) a bylo vidět, že prezentace byla v podobném duchu (rozdíl code-first x contract-first). To už sliboval i abstrakt přednášky. Poznámky:
  • pojem "buzzword driven architecture"
  • odstrašující příklad složitého psaní ws: hodně factory, builderů, práce s DOM, metoda normalize s nejasným významem - v Javě na jedné stránce
  • v protikladu Groovy příkad s XmlSlurper na 2 řádky
  • odstrašující příklad, co se musí vše definovat v CXF: wsdl, binding.xml, cxf.xml, 2x spring applicationContext, cxf-servlet.xml, web.xml, ant/maven pluginy: cxf-codegen, builderhelper
  • API postavené na builder patternu, který je použit pro vše: tvorbu message, WSDL i konfiguraci. Ukázky:
    • String message = Wsdl.parse(URL).binding().localPart(...)
    • WsdlParser
    • SoapContext().builder().alwaysBuildHeaders(true)...
    • SoapClient.builder().endpointUrl(...).basicAuthentication(...).connectTimeout(...).readTimeout(...).build().post(soapAction,message);
    • SoapServer.builder().httpPort(...).maxThreads(...).start() ... .stop()
    • RequestResponder, Source respond(request) - čistý OO návrh API pro práci se zprávou, které umožňuje ji v případě potřeby změnit, ale zůstává jednoduché v defaultním nastavení.
  • následovaly příklady a praktická ukázka, groovy demo

Trisha Gee: What do you mean, backwards compatibility?

Přednášející z vývojového týmu MongoDB, předváděla praktické zkušenosti s vývojem nového driveru pro Mongo. Vzhledem k povaze projektu, na kterém dělám (účelově zaměřený produkt pro jednoho klienta), neřešíme v oblasti kompatibility tak závažné problémy jako u softwaru typu Mongo, nicméně byla to zajímavá přehledová přednáška, i když slajdy opět spíš jen pro efekt.
  • Design is process not document
  • everybody is designer - jako by opsala některé myšlenky z prezentace Martina Čackého 
  • sepsali dvoustránkový dokument s cíli nového návrhu -> důležité ujasnit si, jaké podmínky má nové řešení splňovat
  • obecné podmínky:
    • konzistence (pořadí parametrů, zda jsou fieldy na začátku/na konci třídy, ale zas tyto maličkosti moc neřešit, důležitá je architektura)
    • cleaner design
    • intuitivní API ("users are our friends"), např. přirozené pořadí volání metod: collection.find(query).sort(sortCriteria).count()
    • sane exception handling
    • test friendly
    • backward compatible
  • žádné chyby ze statické analýzy, projití testů - nutná podmínka správně vyřešené zpětné kompatibility
  • identifikujte své uživatele - kdo to bude používat? (java developer, developer knihovny třetí strany, contributor)
  • přizpůsobení starého API, něco na způsob toho, co jednou psal Dagi 
  • souvislost se SpringData a předchozí přednáškou Olivera Gierkeho
Dotaz přednášející na to, kdo to používá, nakonec trochu zkazil jinak dobrý dojem - evidentně se zvedlo méně rukou, než čekala, důvodem byl zřejmě fakt, že lidé používají API na vyšší úrovni (viz právě předchozí zápisek o Spring Data).
Na přednášce byly použity UML diagramy nakreslené v online utilitě Gliffy. Vypadaly pěkně, až budu potřebovat zas někdy namalovat UML, tento nástroj rozhodně zvážím. Už jsem takto přešel od Photoshopu a Gimpu ve prospěch Pixlr. Myslím, že kvalita online nástrojů neustále roste. Chápu, že pro fulltime grafika nebo analytika by to asi cesta nebyla, ale pro nárazovou práci to splňuje úkol lépe než těžkotonážní systémy typu Enterprise Architect.

Slawek Sobótka: Model is all you need

Člověk zaměřený na DDD. Znalost business problematiky je u nás dost důležitá a okolo modelování se točí práce mnoha programátorů a analytiků. Kromě samotného modelování domény na úrovni entit řešíme i to, jak se do modelu promítá UI a také toho se prezentace dotkla. Prezentace byla jinak zajímavá počtem názorných přirovnání a parabol a v neposlední řadě i použitým prezentačním nástrojem prezi.com (prezentace).
  • složitost (complexity) systému
    • essential - složitost samotné povahy problému, nevyhnutelná (představuje hranici, za kterou není možné problém zjednodušit, jinak už by se řešil jiný problém)
    • accidental - složitost vyvolaná implementací konkrétního řešení problému, tu se snažíme minimalizovat
  • doménový expert a autor modelu spolupracují nad modelem
    • doménový expert předává znalost autorovi modelu
    • autor modelu tvoří mode
    • doménový expert ověřuje, že model odpovídá realitě
  • iterace: udělat nejdřív model z user story, zdokumentovat a pak konfrontovat s novým scénářem (a až pak ho teprve nakódovat). Např. objednávka má více položek, pak přijde scénář, kdy je nutno vydat jen některé položky z objednávky a doménový model se změní tak, že z entity Objednávka se stane entita Rezervace).
  • "compiler is your friend unless you have a dynamic language and you have to run it, static lanuage is not bad idea" - kolikrát už jsme se spolehli na překladač, když se při změně modelu něco rozbilo...
  • vztah mezi modelem a UI: z UI flow se musí rekonstruovat proces a zákonitosti business logiky, z nich API a z API teprve domain model
  • user story se zaměřuje na mentální model uživatele, což je ok, ale pro naprogramování to není dost
  • skvělé přirovnání, co odlišuje user story od znalosti business logiky: když hraju kulečník, můžu napsat 100000 user stories, které budou znít "když držím tágo tak, půjdou koule tam". Ale podstatné je znát to základní: zákon odrazu (business rules).
  • "objednávka má více řádků - tak si to namalujeme jako tabulku s řádky, ne jako UML s propojením ♦—, za UML vás lidi z businessu vyhodí. Řada lidí má vizuální inteligenci a potřebuje to vidět, nestyďte se za to." Trefné a svým způsobem osvobozující.
  • dobrý model sděluje informace o realitě implicitně svým návrhem. Např. má-li entita metodu Invoice issuance(Order order), říká tím model, že můžeme vydat a vyfakturovat právě jednu objednávku.
  • symetricky: Dont hack your model. Ústupky a špinavé triky v oblasti modelování core entit jsou větší zlo než např. hackování implementace kódu, který je jinak postaven nad dobrým modelem. Známe z praxe: např. špatná rozhodnutí v návrhu db tabulek nebo volba nesprávných datových struktur.
  • problém: overgeneralization (přehnané zobecnění) - např. různé nesouvisející objekty dědí z Document jenom proto, že implementuje Printable "to look more professionally"
  • klientská abstrakce modeluje koncepty nějak a v modelu můžou být úplně jiné
  • metoda approveOrder, kterou přednášející zakončil příklad, má v sobě tolik ifů, že by mohla sloužit jako startovní bod pro včerejší přednášku o refactoringu. Ale tady představuje cílový stav :-).
  • modelování peněz (vtip: kolik je 2 EUR krát 3 EUR? odpověď: 6 EUR čtverečních)
  • využití open-closed principu a návrhového vzoru Strategie - např. pro výpočet daně: rozdělit na pevnou logiku (BookKeeper), měnitelnou strategii (TaxPolicy) a logiku, která strategii nastaví do pevné logiky (Factory)
  • featura patří k doméně nebo k aplikační logice? Jak to poznat? Přirovnání: Kam patří nákupní košík?
    • když to je nějaký obchod, kde nemají košíky, tak jen k aplikační logice
    • když je košík např. součástí psychologického šetření chováni zákazniků, se kterým má aplikace počítat, pak je to součást domény
  • další přirovnání: pozoruji z okna, že Slunce obíhá Zemi, založím na tom nový programovací jazyk, bez getterů a setterů s jednořádkovými cykly a dám ho do cloudu (schválně tam nacpal co nejvíc cool věcí). Ale model mám špatně.
  • není důležité, aby model modeloval realitu, důležité je, aby modeloval situaci, na které funguje ten byznys. Pokud je byznys založen na tom, že Slunce obíhá Zemi a funguje, pak ho musím takhle namodelovat.
  • doménový expert musí mít znalost ne širokou, ale hlubokou. Kdo ví všechno o všem, není doménový expert.

Sam Newman: Surfing The Event Stream

Tato přednáška mne zajímala především proto, že často hledám ve velkém množství logů. Myšlenkou přednášky bylo zacházet se zprávami logu jako s eventy a tyto eventy přeposílat a rozesílat (do jiných systémů nebo knihoven pro zobrazení a zpracování statistik), filtrovat atd. I když řešení, které předváděl, bylo určené pro zpracování mnohem rozsáhlejších dat než naše logy, byla přednáška užitečná kvůli zmínkám o mnoha stránkách, odkazech a dalších nástrojích:
Celkový dojem: téma je mi v tomto podání vzdáleno, ale přednáška nabídla hodně odkazů ke studiu a prozkoumání. Myšlenka zpracovávat logy online, generovat události a rovnou je třídit a posílat monitorovacím systémům, je fajn.

Joel Spolsky: The Cultural Anthropology of Stack Exchange (keynote)

Autor StackOverflow, odlehčující keynote na konec, nicméně se zajímavými informacemi spíš k poslouchání než pro nějaké dlouhé poznámky.

  • yahoo answers jsou jako otázky školáků, když se vrátí ze školy - otázky do diskuse, ne do Q&A fóra
  • proč reputation? jako sociální jev, který je všude (srov. s armádou)
  • meta stackoverflow - SO o SO
  • "we hate fun" - zavírají se otázky, jaká je nejvtipnějši hláška v kódu/komentářích (neřeší problém, site je zaměřena na řešení problémů)
Třetí den.






19. 5. 2013

GeeCON 2013 - 1. den

Zápisky z prvního dne konference GeeCON 2013.


Ve dnech 15.-17.5.2013 jsem poprvé navštívil konferenci GeeCON v polském Krakówě. Už mi začínalo být trochu těsno z běžného pracovního stereotypu a cítil jsem, že je potřeba zas konfrontovat hlavu s novými ideami, jazyky, projekty a trochu ji tím provětrat. Na konferenci jsem jel v autě s kluky z Forrestu, kteří už jsou na rozdíl ode mne ostřílenými návštěvníky GeeCONu - Novojem (otcem Furou) a Petrem Čížkem, a Pavlem Lahodou. Tady jsou poznámky z prvního dne:

Patrick Copeland: Pretotyping (Úvodní keynote)

Člověk z Googlu ve funkci Engineering Director. Nejdřív jsme mysleli, že je to překlep, ale je to dobře. Pretotyping je metodika nebo spíš přístup, který klade důraz na to, aby řešení řešilo skutečný problém a špatná cesta se opustila co nejdříve. Asi to lépe přiblíží heslovité poznámky:
  • většina nových myšlenek zfailuje. Grafy ukazující statistický počet všech pokusů, pomalý fail, rychlý fail a úspěch.
  • myšlenka nic neznamená, dokud se nepřetransformuje v něco hmatatelného. (Přednáškou se prolínaly vtípky na toto téma, např. nabídka/dražba "úžasné myšlenky od Patrika" v zapečetěné obálce, kterou se snažil prodat publiku postupně za 3000, 1500 a 60 PLN - za 60 se mu to nakonec podařilo a o kupci pak řekl "trouba". Nebo job Ideator: hledám engineera na tvorbu myšlenek, dříve jsem se zabýval převodem myšlenek do praxe, ale teď už se koncentruji pouze na jejich vytváření.)
  • building right "it" over building it right
  • zlatý střed mezi chybějícími testy a přehnanými testy (přehnaný test = např. použitelnost webu pro 500 různých odstínů modré)
  • nehledejte myšlenky, hledejte inovátory
  • pretotyping manifesto: innovators beat ideas, pretotypes beat productypes (ukazoval spoustu nezdařených produktů, např. Google wave), data (měření) beats opinion, simple beats complex
  • fail fast - nutkání pokračovat v neúspěšném projektu za každou cenu je exponenciálně úměrné množství již investovaného času. Vzpomněl jsem si na radu Tomáše Bati (zdravím tímto Míru Burdu): nepokračujte v práci, která je špatně.
  • fake it before you make it - příklad s prázdným odkazem pouze pro změření, kolik lidí na to klikne
  • další graf: na ose x pozváni/vyzkoušeli/zůstali po 1/2/4 týdnech - strmě klesal u neúspěšných projektů, u úspěšných projektů pouze malý pokles, rozebíral to ještě podrobněji
  • pretostorming x brainstroming: brainstorming přetváří myšlenky v názory, pretostorming myšlenky v data
  • další zdroj http://www.pretotyping.org/
Po přednášce dotazy. Pár tazatelů využilo příslušnosti přednášejícího ke Googlu a neodpustilo si rýpnutí, zda považují Google Reader za neúspěšný projekt.

Dalibor Topic: 55 New Things In JDK8

Člověk z Oraclu, už jsem byl na jeho prezentacích před rokem a půl na Oracle Java Developer Day v Brně. Přednáška mě zajímala i kvůli slibovanému formátu 1 téma / min., i když tento formát jsem v tom nakonec nepostřehl. Bylo to spíš do šířky a kdybych o těchto věcech něco nevěděl už předtím, nejsem si jistý, zda bych se to z přednášky naučil. Začátek byla jen řeč o JDK Enhancement Proposals a ukazování webových stránek JDK (ano, těch, jak se na nich pořád odkládají ty termíny milestonů). Opět poznámky bodově:
  • lambda, method references, extension methods
  • generalized target type inference. Hurá, už konečně nebude třeba psát zobáky (a tudíž bude možno použít statický import) u Collections.<String>singleton() v případech, kdy se ta množina dává do generické metody. Aspoň tak jsem to pochopil, příklad přednášejícího byl obdobný (cons(42,List.nil()))
  • anotace u typů
  • přístup k názvům parametrů v runtime (to dnes jde jen za použití workaroundu s javac -g)
  • opakující se anotace
  • odebrání APT
  • programový přístup na javadoc (DocTree API, DocLint, javax.tools javadoc support)
  • bulk data operations - map, reduce, serial, parallels (připadalo mi, že skáče z tématu na téma, proč to neřekl u lambd?)
  • concurrency - ForkJoinPool, ConcurrentHashMap, parallel array sorting Arrays.parallelSort
  • Date and Time APIs
  • JDBC 4.2
  • BASE64, místo dosavadního sun.misc trvalé API
  • změny v I18N, Unicode 6.2
  • security, SecureRandom je na linuxu zatím work in progress
  • java.security.cert nové třídy RevocationChecker|Parameters, nové šifry, algoritmy, digest typy
  • @CallerSensitive - podpora metod, jejichž chování je závislé na volající metodě. Pro zjištění volající metody se dnes může použít proprietární třída z Reflection API, ale pokud je volaná metoda volaná přes reflexi, je volající metodou nějaká pomocná z Reflection API a to nechceme. Anotace by měla sloužit k explicitnímu označení metod, v jejichž implementaci je závislost na volající metodě. Příklad by nezaškodil, každopádně to je zajímavé téma, o jehož existenci v Javě jsem dosud netušil. Připomíná mi to dobu, kdy jsme se zamlada učili, že Smalltalk na volající kontext přistupuje přes klíčové slovo thisContext (a kdy jsem se po přechodu na Javu 1.3 divil, že ona to nemá).
  • URL permissions
  • přímé spouštění JavaFX aplikací
  • java commandline launcher
  • Compact Profiles - možnost ovlivnit velkost Javy v paměti volbou profilu: static footprint: full/compact3/compact2/compact1 - od 140MB do 10MB
  • některé změny, kterými už se připravuje Jigsaw: ClassLoader fixes, ServiceLoader, analyze tool, deprecating java.util.logging.LogManager.addPropertyChangeListener
  • Nashorn - nový javascriptový engine, commandline utilita jjs pro spuštění javascriptu
  • odstranění zřídka používaných přepínačů GC
  • odstranění permgenu, všechny statické proměnné, metadata tříd a internované stringy budou na heapu (nebo nativně v paměti)
  • Fence Intrinsic - nějaký trik s JNI pro nepřerovnávání pořadí instrukcí, nové metody v Unsafe
  • JDK autoconf based build system - ./configure style build setup 

Szczepan Faber: Automation dogfooding

Autor Gradlu a Mockita. Na začátku dotaz, kdo používá Gradle a úvod do Gradlu. Live demo vypadalo přesvědčivě.
  • Přiblížení Gradlu začalo hláškou: "its like Maven but if it was like Maven I would kill myself"
  • Gradle má taky pluginy. Pro Java projekty je Java plugin. Pluginy se zapojí pomocí apply
  • ekvivalent pom.xml - build.gradle
  • UP-TO-DATE mechanismus - hlídá jednotlivé fáze buildu, aby se nespouštěly zbytečně ty, které není potřeba pouštět
  • Přednáška pokračovala povídáním o Gradleware. Výraz dogfooding (nebo eating your dog's food) v názvu přednášky znamená, že společnost sama používá produkty, které nabízí svým klientům
  • důraz na automatizaci - maximálně automatizovat vše, co jde
  • jak dlouho trvá novému programátorovi, než se zapojí do projektu, a kolik z toho je kvůli neaktuální wiki? Důsledek: minimalizovat i wikistránky, raději nahradit automatizovaným procesem. Příklad: gradle idea vyrobí metadata pro Ideu, podobně i pro Eclipse. Toto mě oslovilo, protože na wiki máme spoustu zastaralých informací a páky pro údržbu textu nikdy nejsou tak silné jako pro údržbu živého kódu.
  • task wrapper - nemusím mít instalován Gradle, použitím tasku se nahraje jen malý jar, který stáhne zbytek Gradlu
  • AbstractIntegrationSpec - podpora pro integrační testy, používá spock (o tom byla pozdější výborná přednáška)
  • módy - embedded, forking, daemon (zůstává v paměti po skončení buildu), parallel (u Gradleware se používá tento mód, využívá více jader)
  • je možné pustit testy proti různým verzím gradlu (crossversion)
  • testují se i příklady v users guide, v javadocu jsou příklady podobně jako u Mockita. Další věc, ve které mě Gradle zaujal, protože na Mockitu mi přijde praktické mít dokumentaci frameworku jako součást javadocu jeho ústřední třídy.
  • automatický deployment dokumentace - u nás další prostor pro inovaci, možnosti gradlu - wiki formát a samozřejmě rozkopírování na potřebná místa
  • Gradle nabízí i nástroje pro kvalitu kódu (dokumentace public API, přidání licence headers, spouštění nástrojů pro statickou analýzu) a napojení na webové rozhraní a údaje o buildu v Teamcity
Rozhodně jsem si představu o Gradlu vylepšil, nevypadá tak nevyzrále jako dřív. Po zkušenostech s Mavenem, kde stejně máme pár procedurálních prvků (volání antrun pluginu), se zdá snaha Gradlu o skloubení toho nejlepšího z deklarativního a imperativního přístupu jako přirozená a dobrá.

Daniel Spiewak: Life in a Post-Functional world

Spíše teoretická přednáška, která začala slajdem s definicí funkcionálního programování a po představení základních pojmů pak nastoupily příklady ve Scale, Haskellu a Clojure. Což mně osobně funkcionální programování moc nepřiblížilo, protože v těchto jazycích jsem zatím nic v praxi nepsal.
  • funkce je striktně matematická funkce (pro stejný vstup vždy dostaneme stejný výstup, neexistují vedlejší efekty)
  • u funkcionálního programování je funkce primární jednotka abstrakce (u OOP objekt)
  • jmenné prostory modulů řeší kolizi jmen, ale kolize jmen není hlavní problém, tím je vyjádření vazby mezi moduly
  • pojmy pak demonstroval na příkladu rozhraní fronty (což mě vrátilo do školních let - na takových příkladech si člověk uvědomí, jak už si zvykl na vysokoúrovňové API současných jazyků a knihoven a že takové věci nemusí řešit)
  • ve Scale ukazoval příklad, který mi připomínal situaci známou z použití návrhového vzoru Visitor - když mám hierarchii tříd a sadu metod, vyplatí se visitor jen pokud se hierarchie tříd moc nemění a  metody se mění hodně. Pokud je to naopak, pak je lepší mít metody u tříd a nedávat je do visitorů. Akorát v příkladu tomu říkal cases a problems a modeloval to nějakými konstrukcemi ve Scale (pattern matching, ale zbytek jsem moc nepochytil, neznám Scalu dobře).
  • ne vše objektové/procedurální je špatné
  • některé myšlenky mají důsledky v modularizaci a organizaci projektu a mohly by být zajímavé z pohledu JDK9 a Jigsawu.
Přednáška byla zajímavá, ale teorie tam bylo dost a málo návodu na aplikování v praxi. Utkvěla mi v paměti výrazná rétorika "this difference is very very very important" u situací, kde mi ten rozdíl jako moc výrazný nebo pro praxi důležitý nepřišel.

Andrzej Grzesik, Marcin Sawicki: Continuous delivery antipatterns

Přednáška dvou lidí, kteří se střídali po odstavcích a na představovacím slajdu měli každý uvedeno "I hate computers.". Pro situaci projektů u nás měla omezenou použitelnost, jednak protože zahrnovala celkový proces dodání (nešlo od toho čekat antipatterny jen v oblasti continuous integration), jednak že některé rady se týkaly virtualizovaného prostředí (Puppet x Chef). Jako v mnoha ostatních přednáškách i zde byl důraz na automatizaci (sarkastický vtípek: manual deployment = job security). Další střípky:
  • release more often
  • know what is where
  • paralelizovat proces dodání produktu vytipováním míst, která na sobě nezávisí
  • samotný pohled na release jako něco, co se musí zkompilovat a udělat (ve smyslu, že je to nedotknutelný artefakt někoho, kdo právě kompiluje a nikdo jiný mi na to nesahejte), je antipattern - release by měl být schopný udělat kdokoli
  • deployování přes scp = antipattern, zřejmě myšleny ruční pokoutní zásahy
  • protein-based automation process = proces založený na lidském faktoru
Celkový dojem jsem měl povrchní - viděl jsem, že to, co děláme, neděláme úplně špatně a tam, kde máme rezervy, to víme většinou i bez této přednášky.

Sandro Mancuso: Testing and refactoring legacy code

Taky občas prožíváte ten deadlock, kdy byste rádi refaktorovali kód a přísně vzato nesmíte kvůli absenci testů, ale testy se těžko píšou, protože kód vyžaduje refactoring? Já jsem si kvůli tomu tuto přednášku vybral a nezklamal jsem se. Úžasná přednáška, nejlepší z celého dne a nejspíš i celého GeeCONu, poctivě programátorská bez rozjásaných slajdů a buzzwordů.
Většinu času byl na plátně Eclipse s dvěma editory, vlevo test, vpravo kód. Přednášející začal příkladem fiktivní sociální sítě cestovatelů, kde existovala servisní metoda pro nalezení výletů všech přátel přihlášeného uživatele. To byla legacy metoda - špagetový kód plný ifů a forů (popravdě tak moc zašpagetěné to nebylo, ale to mělo podle mne jen pedagogické důvody, které přednášejícímu rád prominu - musel to přizpůsobit časovému rozsahu prezentace a nemohly tam být úplné špeky). Cíl: refaktoring kódu a a vytvoření testů zajišťujících jeho plné pokrytí. Vtipem jsou pravidla hry: smí se použít pouze nástroje automatizovaného refactoringu v IDE.
Na začátku byla tedy jedna servisní metoda, na konci bylo více menších metod a tříd plus testy k veškeré napsané logice. To, co bylo mezi, bylo napínavé pozorovat. Pokud má kód projít skutečně pouze automatizovanými transformacemi, musí si programátor rozmyslet, co má udělat jako první a kde začít s rozbitím příslovečného "deadlocku". Během procesu např.
  • vznikaly nové pomocné metody a zase zanikaly
  • některé části kódu původně vznikly v testu, ale přesunuly se do testované třídy (např. UserBuilder - builder pattern pro vytvoření instancí třídy User)
  • dočasně existoval i anonymní potomek testované třídy kvůli překrytí jedné metody pro test
  • uživatelé s určitými vlastnostmi (GUEST, ANONYMOUS) byli extrahováni do static final fieldů testu
  • zabýval se přesným a vypovídajícím pojmenováním testovacích metod (should...)
  • změna ifu s dvěma rovnocennými větvemi na if, který představuje spíš assert (oproti původnímu ifu podmínka testuje chybu a při splnění metoda ihned končí)
  • na závěr pár kosmetických změn pro lepší čitelnost, atd.
Názornost zvýrazňovalo použití doplňkových nástrojů: Eclipse plugin zajišťující spuštění testu při uložení (tuším, že říkal infinitest, ale je jich jinak dost), plugin pro zobrazení pokrytí kódu zeleno-červeným podbarvením (podle screenshotu se zdá, že to byla eCobertura) a samozřejmě git, do kterého každou změnu hned commitnul a na konci prezentace ukázal téměř dvoustránkový log git messagí (mezi nimiž bylo vždy tak 3-5 minut).
Střípky:
  • legacy kód může být i kód se singletony a statickými metodami, ne pro samotný fakt, že jsou statické, ale proto, že pro ně kvůli této vlastnosti nemůže být vytvořen tak spolehlivý test. Snažit se ze statických metod udělat instanční (na začátku ukázky byla statická i metoda DAO, což bylo do očí bijící a zjevně jen kvůli prezentaci).
  • metodika pro rozkrytí motanice:
    • refactoring začněte od nejvíce zanořené větve a postupujte směrem k nejkratší (hlavní) větvi
    • testování začněte od nejkratší větve a postupujte směrem k nejhlubší větvi
    • takže když bylo tělo metody tvořeno bezmála jedním velkým ifem, zda přihlášený uživatel je null, nejprve se napsal test na null
  • při refactoringu bylo důležité u zašpagetěného kódu identifikovat, že metoda má více chování (porušení S v SOLID). Tomu odpovídá i skladba a minimalizace budoucích testů: např. to, že uživatel, který je přítel Paula, není přítel Boba - to jediné má být předmětem testu, nikoli už např. test přihlášení nebo počtu jeho výletů.
  • menší ruční refactoringy, které neporušují pravidlo hry, ale byly tam také: proměnné by se měly deklarovat v blízkosti jejich použití (např. proměnná byla použita jen v jedné větvi ifu a tím bylo možné if rozdělit na validaci a vlastní logiku), if nahrazen za ?:
  • nepojmenovávat field servisy v testu jako testee, ale podle třídy, tj. FooService fooService.
  • používal mocky - Mockito a anotaci @InjectMocks
  • dával privátní členy až na konec těla třídy a docela mi to začíná připadat dobré (prokládání mezi public metody stírá na pohled rozdíl mezi public a private členy, naopak u takovýchto refactoringů na viditelnosti záleží)
  • další rady:
    • snažte se o jednoduchost
    • znejte dobře používaný framework
    • preferujte malé a bezpečné inkrementální změny
    • boy scout rule (zanechte po sobě kód v lepším stavu)
    • no broken windows (vzepřít se postoji "tohle můžu naprasit, už je to stejně celkově zprasený")
Přednáška mi hodně dala i proto, že jsem si řadu zkušeností sám zažil a snažím se takto při tvorbě a údržbě postupovat. Samozřejmě v praxi bývají komplikovanější úkoly a programátor by si měl osvojit i cit vědět, kdy tam může risknout střelit změnu, která není bezpečná a jejíž rozdělení na malé kousky by bylo buď zdlouhavé a pracné nebo z principu nemožné. Doporučil bych ji všem, kdo se řídí přístupem "nešahej do toho, ať tam něco nerozbiješ" nebo "všechno to zahodíme a napíšeme znovu", jako konstruktivní protiklad.
Zdrojáky zde.

Google IO Extended


Krakovská Google Developer Group streamovala live přenos z konference Google IO v San Franciscu a účastníci GeeCONu měli možnost se na přenos podívat přímo v Googlu v Krakově. První den jsem toho využil a chvíli se koukal na představování hračiček:
  • autodráha na několika mobilech s Androidem (demonstrace komunikace)
  • rozpoznání obrázků na G+ (např. Eiffelovka), i když obrázek nemá hashtag
  • automatická detekce lepších (highlight) fotek (podle úsměvu)
  • úpravy fotek á la Photoshop filtry
  • když je několik fotek, kde na každé se směje někdo jiný, Google z toho udělá fotku, kde se smějou všichni 
  • hlasové ovládání vyhledávače: "Ok, google..." a otázky jako např. "kam v Santa Cruz na procházku" nebo "kde je manžel"
Nedokoukal jsem to celé, protože jsem už toho měl za den dost, ale některé věci mi přišly jako technologická exhibice, i když je pravděpodobné, že za pár let je budeme používat zcela normálně.
Cestou z Googlu jsem ještě chtěl vidět na vlastní oči Wavel.

Druhý den.