Acasă
Despre
Cautare
🌐
English Română
  • Collecting Hack

    Read this post in English

    May 30, 2014 collections Facebook hack map pair PHP set vector
    Share on:

    Stamp-Collection

    Ceva ce nu am abordat in blog-ul anterior au fost colectile. Hack vine cu o varietate de colectii pentru organizarea de date.

    Structurile de date reprezinta o parte fundamentala a unui linbaj de programare, pentru ca acestea vor constitui modul in care informatia circula in aplicatie.

    Pana la versiunea 5, PHP avea un singur tip de colectii de date, denumit “array”. Acest tip de date poate sa aiba trei moduri: array, hash table sau o combinatie intre cele doua.

    In PHP 5 au fost introdusi o serie de iteratori pentru a facilita constructia de structuri. Din pacate si structurile rezultate aveau scopul sa ofere posibilitatea de a accesa obiectele intr-un mod similar cu array-urile.

    Abea in PHP 5.3 au aparut structuri de date cu adevarat diferite, cum ar fi SplStack, dar si multe altele.

    Cu toate astea, structuri cum ar fi vectori si tupluri nu au aparut niciodata in mod nativ. Se pot construi, dar nu este simplu sau intuitiv.

    Hack din HHVM a venit cu o alta abordare, o serie de colectii native care sunt gata de folosire.

    Tipurile de colectii

    Lista de colectii este:

    • Vector – lista ordonata folosind un index
    • Map – hash table tip dictionar
    • Set – lista care stocheaza doar valori unice
    • Pair – un caz particular de Vector care are doar doua elemente.

    Vector, Map si Set au si cate un echivalent immutable (inflexibil si read-only). Acestia sunt: ImmVector, ImmMap si ImmSet. Scopul acestor tipuri de date este sa expuna informatii pentru citire, fara sa permita modificarea acestora. O colectie immutable se poate genera direct, folosind constructorul, sau folosind metodele toImmVector, toImmMap si respectiv toImmSet.

    Chiar si mai mult, exista si o serie de clase abstracte pentru a implementa cu usurinta structuri similare:

    • MutableVector / ConstVector
    • MutableMap / ConstMap
    • MutableSet / ConstSet

     

    Vector

    Avantajul unui vector este ca va avea tot timpul cheile in succesiune, iar ordinea elementelor nu se schimba. Cand vine vorba de array nu este nici o modalitate simpla de a verifica daca ar trebui sa se comporte ca un hash table sau ca un vector. La vector, spre deosebire de hash table, valoarea cheii nu este relevanta, doar succesiunea elementelor si numarul lor sunt importante.

    Sa luam un exemplu:

     1<?hh
     2
     3function listVector($vector) {
     4     echo 'Listing array: ' . PHP_EOL;
     5     for($i = 0; $i < count($vector); $i++) {
     6          echo $i . ' - ' . $vector[$i] . PHP_EOL;
     7     }
     8}
     9
    10$array = array(1, 2, 3);
    11
    12listVector($array);
    13
    14// eliminarea unui element din array
    15unset($array[1]);
    16
    17listVector($array);
    

    Rezultatul va fi:

    1Listing array:
    20 - 1
    31 - 2
    42 - 3
    5Listing array:
    60 - 1
    7
    8Notice: Undefined index: 1 in ../vector.hh on line 6
    91 -
    

    Motivul este foarte simplu: count intoarce intr-adevar numarul de elemente, dar index-ul nu este garantat secvential. Atunci cand al doilea element din array a fost eliminat, numarul de elemente s-a redus cu unul, dar index-ul 1 a ramas nealocat, iar ultimul index este egal cu marimea, asa ca nu se va mai ajunge la el.

    Sa luam acelasi exemplu folosind un vector:

     1<?hh
     2… 
     3$vector = Vector{1, 2, 3}; 
     4
     5listVector($vector); 
     6
     7// eliminarea unui element din vector
     8$vector->removeKey(1);
     9
    10listVector($vector);
    

    Asa cum am anticipat, rezultatul este:

    1Listing array:
    20 - 1
    31 - 2
    42 - 3
    5Listing array:
    60 - 1
    71 - 3
    

    Este de remarcat ca nu se poate folosi unset, pentru ca nu este o cheie cea care se elimina, ci elementul respectiv, iar urmatoarea valoare din vector ii va lua locul.

    Un alt lucru important este ca, daca un index nu exista si incercam sa-l modificam, va aparea o exceptie de tip “OutOfBoundsException”.

    Cateva exemple care vor genera exceptia anterioara:

     1<?hh 
     2
     3$vector = Vector{1,2,3,4}; 
     4
     5// va functiona pentru ca cheia nr 1 exista 
     6$vector->set(1, 2);
     7
     8// nu va functiona pentru ca inca nu exista cheia 4
     9$vector->set(4, 5);
    10
    11// nu va functiona din acelasi motiv
    12$vector[4] = 5;
    13
    14// pentru a adauga un element nou se pot folosi doar metode care nu specifica cheia
    15$vector[] = 5;
    16
    17// sau
    18array_push($vector, 5);
    

    Pentru accesare de elemente problema de “OutOfBoundsException” ramane la fel. De exemplu, daca indexul 10 nu exista:

    1var_dump($vector[$unsetKey]);
    

    Un alt caz mai special este atunci cand elementul nu exista, dar se foloseste metoda “get”.

    1var_dump($vector->get($unsetKey));
    

    Exemplul anterior nu va genera o eroare, in schimb rezultat va fi “null” atunci cand nu exista cheia. Mi se pare bizar un astfel de comportament, pentru ca poate exista un element null in vector, iar rezultatul va fi acelasi.

    Pentru a evita confuzia intre elemente care nu sunt definite si elemente care sunt null, exista o metoda speciala pentru a vedea daca exista cheia:

    1var_dump($vector->containsKey($unsetKey));
    

    Scoaterea elementelor din vector se face folosind:

    1$vector->remove($key);
    

    Sau, pentru scoaterea ultimului element:

    1$vector->pop();
    

    Map

    Intr-un hash table, fata de un vector, ordinea si numarul elementelor nu sunt foarte relevante. In schimb, asocierea cheie-valoare este foarte importanta. Din acest motiv, un Map se mai numeste si “dictionar” – pentru ca poti ajunge usor de la o cheie la o valoare, pentru ca sunt “mapate”. De acolo si denumirea de “Map”.

    Implementarea HHVM va retine si ordinea in care elementele au fost introduse.

    In PHP, echivalentului unui Map era un array asociativ.

    Fata de Vector, Map are nevoie de o cheie care va ramane permanent asociata cu elementul, indiferent daca se vor scoate sau adauga elemente in colectie.

    Functile array_push sau array_shift nu vor functiona pentru Map, pentru ca acesta nu trimit o cheie, iar asocierea cheie-valoare nu ar fi controlata:

    1<?hh 
    2
    3$map = Map{0 => 'a', 1 => 'b', 3 => 'c'};
    4
    5array_push($map, 'd');
    6
    7array_unshift($map, 'e');
    8
    9var_dump($map);
    

    Va genera urmatorul rezultat:

     1Warning: Invalid operand type was used: array_push expects array(s) or collection(s) in ../map.hh on line 5
     2
     3Warning: array_unshift() expects parameter 1 to be an array, Vector, or Set in ../map.hh on line 7
     4object(HH\Map)#1 (3) {
     5  [0]=>
     6  string(1) "a"
     7  [1]=>
     8  string(1) "b"
     9  [3]=>
    10  string(1) "c"
    11}
    

    Dupa cum se poate vedea, elementele nu au fost adaugate si fiecare din cazuri a generat cate un Warning.

    Adaugarea efectiva se poate face folosind:

     1<?hh 
     2
     3$map = Map{0 => 'a', 1 => 'b', 3 => 'c'};
     4
     5// adaugarea unui element folosind sintaxa de array
     6$map['new'] = 'd';
     7
     8// adaugarea unui element folosind metoda structurii
     9$map->set('newer', 'e');
    10
    11var_dump($map);
    

    Rezultatul va fi:

     1object(HH\Map)#1 (5) {
     2  [0]=>
     3  string(1) "a"
     4  [1]=>
     5  string(1) "b"
     6  [3]=>
     7  string(1) "c"
     8  ["new"]=>
     9  string(1) "d"
    10  ["newer"]=>
    11  string(1) "e"
    12}
    

    Spre deosebire de Vector, pentru ca elementul care se schimba este strans legat de cheie, unset este o metoda valida de a elimina un element:

    1unset($map[$key]);
    

    Structura are si o metoda pentru a elimina elementul cu o anumita cheie:

    1$map->remove($key);
    

    In acest caz, nici una din optiuni nu va genera o eroare daca nu exista cheia.

    Exceptia de “OutOfBoundsException” se aplica si aici pentru chei care nu sunt definite, dar la fel ca la Vectori, exista o metoda pentru a testa daca exista cheia:

    1$map->contains($key);
    

    Similar cu Vector, exista o metoda care intoarce cheia setata sau null daca aceasta nu exista:

    1$map->get($key);
    

    Pentru a ne asigura ca nu se genereaza o exceptie “OutOfBoundsException”, un Map nu ar trebui parcurs cu “for”, ci doar cu “foreach”.

    Pentru ca metoda “pop” de la vector nu se bazeaza pe o cheie, nu exista in structura Map.

    Set

    Seturile au scopul de a pastra unicitatea valorilor. Pentru aceasta structura, valorile sunt restrictionate doar la tipurile scalare: string si integer.

    Interfata pentru aceasta structura este mult mai simpla decat la Vector si Map, pentru ca scopul este mult mai limitat.

    Pentru Set cheia nu poate fi accesata, dar este relevanta din alt punct de vedere.

    Sa luam un exemplu pentru a evidentia:

    1<?hh
    2$set = Set{'a', 'b', 'c'}; 
    3
    4foreach($set as $key => $val) {
    5     echo $key . ' - ' . $val . PHP_EOL;
    6}
    

    Rezultatul va fi:

    1a - a
    2b - b
    3c - c
    

    Cheia si valoarea sunt identice, un mod ingenios de a pastra si unicitatea.

    Cu toate astea, operatiunea este transparenta, lucru care permite adaugarea de elemente fara a referentia o cheie:

     1<?hh
     2
     3$set = Set{'a', 'b', 'c'};
     4
     5array_push($set, 'd');
     6
     7array_unshift($set, 'e');
     8
     9$set[] = 'f';
    10
    11var_dump($set);
    

    Vom avea un rezultat similar cu cel de la vectori:

    1object(HH\Set)#1 (6) {
    2  string(1) "e"
    3  string(1) "a"
    4  string(1) "b"
    5  string(1) "c"
    6  string(1) "d"
    7  string(1) "f"
    8}
    

    Chiar daca se pot adauga noi valori folosind operatorul [], acestea nu pot fi referentiate folosind acest operator:

    1<?hh
    2
    3$set = Set{'a', 'b', 'c'};
    4
    5echo $set['a'];
    

    Va genera eroarea:

    1Fatal error: Uncaught exception 'RuntimeException' with message '[] operator not supported for accessing elements of Sets' in ../set.hh:5
    2Stack trace:
    3#0 {main}
    

    Pentru scoaterea de elemente se poate folosi doar metoda nativa (remove) si metode care nu presupun referentierea de chei:

     1<?hh 
     2
     3$set = Set{'a', 'b', 'c', 'd'}; 
     4
     5array_pop($set); 
     6
     7array_shift($set); 
     8
     9$set->remove('b');
    10
    11var_dump($set);
    

    Rezultatul va fi:

    1object(HH\Set)#1 (1) {
    2  string(1) "c"
    3}
    

    Fata de Vector si Map, metoda “remove” va primi valoarea, nu cheia de acces.

    Pentru Set nu exista nici un fel de cheie de acces, deci cam tot ce putem sa facem este sa verificam daca un element exista, folosind “contains”:

    1$set->contains($value);
    

    Metoda va returna o valoarea booleana, care arata daca elementul exista sau nu.

    Pair

    O pereche este o colectie cu doua elemente. Nu poate avea mai multe sau mai putine. Elementele sunt indexate la fel ca si Vectorul, printr-o cheie care in acest caz poate avea doar valorile 0 si 1.

    Nu sunt multe de spus despre aceasta structura de date, pentru ca elementele nu se pot scoate, adauga sau inlocui. Acesta este si motivul pentru care nu exista un echivalent immutable, deoarece structura in sine nu este flexibila:

    1<?hh 
    2
    3$pair = Pair{'a', 'b'}; 
    4
    5foreach($pair as $key => $val) {
    6     echo $key . ' - ' . $val . PHP_EOL;
    7}
    

    Rezultatul va fi:

    10 - a
    21 - b
    

    O structura foarte simpla cu un scop foarte simplu.

    Notiuni comune

    Aproape toate structurile prezentare anterior au cateva metode si comportamente comune. Spun aproape toate, pentru ca Set si mai ales Pair, prin natura lor mai restrictiva, nu dispun de unele functionalitati pe care Vector si Map le au.

    Filter

    Este o functie de filtrare care vine din programarea functionala. Scopul este de a filtra o structura de date si de a genera una noua de acelasi fel, exceptie facand Pair, ca urmare a restrictiei legate de numarul de elemente. In PHP, echivalentul este array_filter.

    Vector si Map au doua metode: filter si filterWithKey. Acestea accepta un argument de tip “callable”, cu alte cuvinte o functie:

     1<?hh 
     2
     3$vector = Vector{'a', 'b', 'c', 'd', 'e'}; 
     4
     5// eliminarea elementului cu valoarea 'a' 
     6$result = $vector->filter($val ==> $val != 'a');
     7
     8// eliminarea fiecarui al doilea element folosind cheia
     9$result2 = $vector->filterWithKey(($key, $val) ==> ($key % 2) == 0);
    10
    11var_dump($vector);
    12var_dump($result);
    13var_dump($result2);
    

    Rezultatul va fi:

     1object(HH\Vector)#1 (5) {
     2  [0]=>
     3  string(1) "a"
     4  [1]=>
     5  string(1) "b"
     6  [2]=>
     7  string(1) "c"
     8  [3]=>
     9  string(1) "d"
    10  [4]=>
    11  string(1) "e"
    12}
    13object(HH\Vector)#3 (4) {
    14  [0]=>
    15  string(1) "b"
    16  [1]=>
    17  string(1) "c"
    18  [2]=>
    19  string(1) "d"
    20  [3]=>
    21  string(1) "e"
    22}
    23object(HH\Vector)#5 (3) {
    24  [0]=>
    25  string(1) "a"
    26  [1]=>
    27  string(1) "c"
    28  [2]=>
    29  string(1) "e"
    30}
    

    Dupa cum se poate observa, rezultatul functiei “callable” este tratat ca un bool si, in functie de acesta, elemente sunt adaugate in structura rezultata.

    Map are un comportament identic cu cel de la Vector, diferenta fiind doar in natura cheilor.

    Un lucru interesant este ca o colectie poate sa fie si immutable, pentru ca operatiunea nu modifica structura de la care a plecat, dar colectia va fi si ea de tipul structurii initiale:

     1<?hh 
     2
     3$vector = Vector{'a', 'b', 'c'}; 
     4
     5$vector = $vector->toImmVector();
     6
     7// eliminarea elementului cu valoarea 'a'
     8$result = $vector->filter($val ==> $val != 'a');
     9
    10var_dump($vector);
    11var_dump($result);
    

    Rezultatul va fi:

     1object(HH\ImmVector)#2 (3) {
     2  [0]=>
     3  string(1) "a"
     4  [1]=>
     5  string(1) "b"
     6  [2]=>
     7  string(1) "c"
     8}
     9object(HH\ImmVector)#4 (2) {
    10  [0]=>
    11  string(1) "b"
    12  [1]=>
    13  string(1) "c"
    14}
    

    Pair are si el aceleasi functii ca Vector si Map, dar comportamentul nu este identic, din cauza faptului ca un Pair poate sa aiba doar 2 elemente, nici mai mult nici mai putin. Din acest motiv, cand se filtreaza un Pair, rezultatul va fi ImmVector, adica o structura similara cu Pair, dar care nu are un numar exact de elemente:

    1<?hh 
    2
    3$pair = Pair{'a', 'b'}; 
    4
    5// eliminarea elementului cu valoarea 'a' 
    6$result = $pair->filter($val ==> $val != 'a');
    7
    8var_dump($result);
    

    Structura rezultata va fi:

    1object(HH\ImmVector)#3 (1) {
    2  [0]=>
    3  string(1) "b"
    4}
    

    Set nu are decat metoda “filter”, pentru ca, asa cum am demonstrat anterior, cheile sunt identice cu valorile. Daca ar fi existat si o valoare cu chei, ar fi functionat similar.

    Map

    O alta functie provenita din limbajele functionale este “Map”. Aceasta are scopul de a modifica valorile unei structuri, folosind o functie, rezultatul fiind o noua structura de tipul celei initiale. In PHP, echivalentul este array_map.

    Similar cu filter, Vector si Map au metodele comune: “map” si “mapWithKey”. Si in acest caz, accepta un argument de tip “callable”:

     1<?hh 
     2
     3$vector = Vector {'a', 'b', 'c'}; 
     4
     5$result = $vector->map($val ==> $val . $val);
     6
     7$result2 = $vector->mapWithKey(($key, $val) ==> str_repeat($val, 1 + $key));
     8
     9var_dump($vector);
    10var_dump($result);
    11var_dump($result2);
    

    Rezultatul va fi:

     1object(HH\Vector)#1 (3) {
     2  [0]=>
     3  string(1) "a"
     4  [1]=>
     5  string(1) "b"
     6  [2]=>
     7  string(1) "c"
     8}
     9object(HH\Vector)#3 (3) {
    10  [0]=>
    11  string(2) "aa"
    12  [1]=>
    13  string(2) "bb"
    14  [2]=>
    15  string(2) "cc"
    16}
    17object(HH\Vector)#5 (3) {
    18  [0]=>
    19  string(1) "a"
    20  [1]=>
    21  string(2) "bb"
    22  [2]=>
    23  string(3) "ccc"
    24}
    

    Rezultatul functiei “callable” este noua valoare a elementelor din structura.

    La fel ca si in cazul “filter”, o colectie immutable are ca rezultat o colectie immutable.

    Tot similar cu filter este si faptul ca functia map, aplicata pe un Pair, va avea ca rezultat un ImmVector:

    1<?hh 
    2
    3$pair = Pair{'a', 'b'}; 
    4
    5$result = $pair->map($val ==> $val . $val);
    6
    7var_dump($result);
    

    Va avea ca rezultat:

    1object(HH\ImmVector)#3 (2) {
    2  [0]=>
    3  string(2) "aa"
    4  [1]=>
    5  string(2) "bb"
    6}
    

    Conversie

    Unele elemente pot fi convertite in alte tipuri:

    din \ catre Vector Map Set Pair Array
    Vector da da da nu da
    Map da da da nu da
    Set da nu da nu da
    Pair da da da nu da
    Array da da da nu da

    La tabelul de mai sus se mai adauga cateva restrictii de structura:

    1. Orice structura, cand se converteste catre Set, trebuie sa contina doar valori scalare de tip int sau string:
    1(Map{})->add(Pair {'a', new stdClass()})
    2    ->toSet();
    

    Va genera eroarea:

    1Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Only integer values and string values may be used with Sets' in …
    
    1. Un Map, cand este convertit la orice alta structura in afara de array, isi va pierde cheile in majoritatea cazurilor.
      Conversia de la array catre altre structuri se face folosind:
    1$vector = new Vector ($array);
    

    In afara de Pair, toate structurile de mai sus au ca unic parametru al constructorului un element care implementeaza Traversable.

    Concluzii

    Hack aduce o noua perspectiva asupra celui mai popular tip de date din PHP. Motivul celor de la Facebook este unul simplu, optimizarea. Daca ai un comportament consistent, poti optimiza pentru structura respectiva. In PHP acest lucru nu este tocmai posibil, din cauza faptului ca un array in PHP poate sa fie orice fel de colectie.

    Din punct de vedere al structurilor de date, mi se pare interesant sa ai astfel de tipuri de date. In framework-uri, de obicei exista structuri care emuleaza comportamentul colectiilor introduse de Hack. Spre exemplu, intr-un ORM, o colectie de obiecte este reprezentata in general ca un vector, pentru ca are scopul de a se itera asupra valorilor ei. Un obiect care reprezinta valorile unor campuri dintr-o tabela o sa fie o structura de tip Map, pentru ca valoarea campului este legata de denumirea campului.

    Mi se pare foarte interesant nu doar faptul ca exista aceste structuri, dar si faptul ca exista interfete pentru a implementa unele noi.

    Sper ca Hack sa influenteze PHP, aducand stucturi cu un scop bine determinat in limbaj.

  • Limbajul de programare Hack, apocalipsa PHP?

    Read this post in English

    Apr 29, 2014 Facebook hack PHP
    Share on:

    you-have-been-hacked

    Introducere

    Facebook a lansat acum aproape o luna limbajul de programare Hack.

    De atunci, peste tot au inceput sa apara articole apocaliptice legate de acest limbaj si cum acesta va inlocui PHP. Titlul acestui articol a fost inspirat din “Will Hack Kill PHP?“.

    Ce mi se pare si mai ciudat este ca a urmat un val de aprecieri negative legate de PHP, aparent Hack “repara” limbajul mai sus mentionat. Parerea mea este ca, in primul rand, limbajul ar fi trebuit sa fie “stricat” ca sa poata fi “reparat”.

    Evident ca si PHP are multe lipsuri, la fel ca orice alt limbaj de programare, dar trebuie sa fie si un motiv pentru care este cel mai popular limbaj pentru Web. Pana la urma, Facebook l-a folosit atata timp, iar acum nu il schimba, incearca sa-l imbunatateasca… nu?

    Un lucru este sigur, este probabil cel mai neinspirat nume. Atunci cand cauti “Facebook hack” gasesti orice altceva decat acest limbaj de programare…

    Despre Hack

    Hack ruleaza pe HHVM. HHVM este incercarea Facebook de optimizare a limbajului PHP prin Just In Time complication, ultima abordare de optimizare a limbajului. Practic, Facebook incearca sa-si reduca din costuri, optimizand interpretatorul de limbaj, iar acum un alt limbaj cu totul. Pana la urma, daca ne gandim la infrastructura Facebook, este normal sa faca asta. Chiar si o optimizare relativ minora duce la o reducere consistenta a costurilor.

    Initial am crezut ca este o versiune “imbunatatita”, dar se pare ca este alt limbaj de programare, practic este un PHP cu ceva in plus!

    Un mic tutorial al limbajului este la: http://hacklang.org/tutorial/.

    Tutorialul nu prinde chiar toate facilitatile limbajului, mai multe detalii sunt la: http://docs.hhvm.com/manual/en/hacklangref.php.

    Practic cam toate facilitatile care deosebesc Hack de PHP sunt de fapt optionale. Aproape ca poti scrie PHP si va functiona. Contrar asteptarilor, nu este obligatorie nici macar specificarea tipului de input/output pentru variabile.

    Pentru ca pana la urma este un limbaj de programare, nu voi intra in detaliu legat de tot ce aduce nou. Acesta este mai degraba rolul unui carti, nu al unui articol.

    Doresc sa subiliniez cateva lucruri care mi se par interesante.

    Typechecker

    In mod bizar, cel putin pentru inceput, la runtime tipul rezultatului chiar daca este trimis, nu este neaparat interpretat.

    Sa luam un exemplu:

    1<?hh 
    2
    3function a($a): void {
    4     return true;
    5}
    6
    7echo a('a');
    

    Acest exemplu va avea output… 1.

    Practic, la runtime nu se verifica decat tipul de input, nu si cel de output.

    Pentru a rula Typechecker-ul se adauga in directorul curent un fisier gol:

    1$ touch .hhconfig
    

    Apoi se ruleaza:

    1$ hh_client
    

    Dupa cum se poate vedea, tipurile de date se testeaza intr-un pas separat fata de runtime.

    La rularea manuala de Typechecker, acesta va identifica toate inconsistentele. Scopul este ca acesta sa identifice problemele inainte de runtime, de exemplu cand se editeaza un fisier, nu cand ruleaza efectiv aplicatia.

    Output-ul de la Typechecker este:

    1../test.php:4:9,12: Invalid return type
    2../test.php:3:17,20: This is void
    3../test.php:4:9,12: It is incompatible with a bool
    

    Din pacate mai este de lucru la aceste feature. Daca incercam sa validam doar la runtime, folosind “type hinting” la fel ca in PHP, functia devine:

    1function a(int $a): void {
    2     return true;
    3}
    4
    5echo a('a');
    

    Output-ul de la Typechecker nu se schimba, dar la rulare vom obtine:

    1Fatal error: Argument 1 passed to a() must be an instance of int, string given in ../test2.php on line 5
    

    Practic, Typecheckerul face ce nu face type hinting, iar cel din urma poate sa primeasca acum si argumente de tip scalar.

    Chiar daca ar fi fost vorba doar de adaugarea de  argumente scalare, tot mi se pare o inbunatatire importanta.

    Lambda operator

    Este o formula mai degraba cunoscuta in limbajele functionale.

    Un exemplu:

    1<?hh 
    2
    3$sqr = $x ==> $x * $x;
    4
    5echo $sqr(5) . PHP_EOL;
    

    Rezultatul o sa fie, evident, 25.

    Mi se pare un mod foarte interesant si lizibil de a ingloba logica de mici dimensiuni.

    Folosind noua sintaxa, o functie poate intoarce si alta functie:

    1$add = $x ==> $y ==> $x + $y;
    2
    3$result = $add(1);
    4
    5echo $result(2) . PHP_EOL;
    

    Rezultatul o sa fie 3.

    Daca o variabila din interiorul unei expresii lambda nu se intalneste in interiorul functiei care o defineste, atunci acesta va prelua variabila din mediul in care expresia este declarata:

    1// variabila in scope-ul curent
    2$z = 5;
    3
    4$addZ = $x ==> $x + $z;
    5// schimbat variabila in scope-ul curent
    6$z = 6;
    7
    8// efectuat adunare
    9echo $addZ(1) . PHP_EOL;
    

    Rezultatul o sa fie… 6!

    Echivalentul in PHP ar fi:

    1$addZ = function ($x) use ($z) {
    2     return $x + $z;
    3}
    

    Valoarea lui $z se ia din mediul in care functia este definita, nu este o referinta la variabila.

    Evident ca, in cazul in care variabila care este preluata din scope este un obiect, ea va fi preluata prin referinta:

     1<?hh 
     2
     3class a {         
     4     public function __construct(public string $x) {}         
     5     public function __toString() { 
     6          return $this->x; 
     7     }
     8}
     9
    10// variabila in scope-ul curent
    11$z = new a('Claudiu');
    12
    13$addZ = $x ==> $x . ' ' . $z . '!';
    14
    15// schimbat variabila care se va folosi la concatenare
    16$z->x = 'World';
    17
    18// rulat concatenare
    19echo $addZ('Hello') . PHP_EOL;
    

    Rezultatul va fi:

    1Hello World!
    

    Shapes

    Din nou o sintaxa mai des intalnita in limbaje functionale. Scopul este de a valida un tip de structura mai specific decat un array.

    Motivul este foarte bun, valiadarea de structuri de date simple. Structurile care se verifica ar trebui sa contina elementele care au fost definite in shape.

     1<?hh 
     2
     3// definirea unei structuri 
     4newtype Circle = shape('radius' => int, 'b' => int);
     5
     6// functie care foloseste tipul structurii de mai sus
     7function areaCircle(Circle $param) {
     8     return M_PI * $param['radius'] * $param['radius'];
     9}
    10
    11// o serie de shape-uri care folosesc structura
    12$circle = shape('radius' => 10);
    13$cilinder = shape('radius' => 10, 'height' => 15);
    14
    15// o structura care nu ar trebui sa functioneze cu Circle
    16$sqr = shape('side' => 10);
    17
    18echo areaCircle($circle) . PHP_EOL;
    19echo areaCircle($cilinder) . PHP_EOL;
    20echo areaCircle($sqr) . PHP_EOL;
    

    Outputul este:

    1314.15926535898
    2314.15926535898
    3
    4Notice: Undefined index: radius in /home/brand/test.hh on line 6
    5
    6Notice: Undefined index: radius in /home/brand/test.hh on line 6
    70
    

    Un pic dezamagitor, speram ca parametrul care nu se potriveste cu structura sa genereze o eroare, dar se pare ca va trece mai departe.

    Nici Typechecker-ul nu gaseste nimic in neregula.

    Initiativa este foarte buna, acum trebuie doar sa asteptam varianta functionala.

    Concluzie

    Probabil Hack va influenta PHP, lucru normal pana la urma, se intampla asta tot timpul cu limbajele de programare.

    Va inlocui PHP? Nu cred, probabil vor fi multi care il vor adopta pentru a reduce costurile si pentru o mai buna structura a codului.

    Este foarte putin probabil ca acest limbaj sa aiba succes in urmatorii ani, in afara de proiecte de dimensiuni medii si mari. Pentru proiecte mici, in general se foloeste shared hosting, iar acesta de obicei nu are ultima versiune de PHP, putin probabil sa foloseasca ultima versiune de HHVM. Acesta poate nu este cel mai interesant argument, dar pana la urma cele mai multe site-uri de pe web sunt mici si foarte mici.

    Un mod multi mai simplu de optimizare este sa folosesti HHVM si atat. Teoretic nu trebuie sa schimbi nimic si rezultatele se vor vedea imediat! Practic HHVM nu este 100% compatibil cu Zend Engine, dar probleme de compatiblitate se rezolva progresiv cu fiecare versiune. Una din prioritatile HHVM este sa intepreteze codul la fel ca Zend Engine, dar sa fie mult mai eficient!

  • Yahoo! Open Hack Day Europe 2011 la Bucuresti – review

    Read this post in English

    May 24, 2011 Douglas Crockford hack jquery node.js Yahoo Yahoo Open Hack yui
    Share on:

    Dupa doua zile aproape fara somn, cam 6 Red Bull si o aplicatie, Yahoo! Open Hack Day Europe 2011 s-a terminat.

    Initial am vrut sa merg doar la prezentari. Mai tarziu m-am gandit sa vin ca hacker pentru ca nu vroiam sa ratez nimic din eveniment, dar sa nu prezint un proiect. In ultima instanta am fost ales sa prezin proiectul.

    Totul a inceput pe la 7 dimineata cand un coleg a venit cu masina sa ne stranga in timp sa bem si o cafea. Eram 6 participanti asa ca ne gadeam sa formam doua echipe.

    Pe la 9:00 am ajuns la Crystal Palace Ballrooms. Am fost intampinati de “crew” in tricouri verzi care ne-au indrumat spre birourile de inregistrare.

    O data inregistrati am inceput sa ne cautam o masa in sala, incapatoare pentru toti 6. In sala erau in jur de 350 de persoane care venisera atat pentru hack cat si pentru prezentari.

    In mijlocul salii era o masa rezervata pentru prezentatori si staff Yahoo!. Un coleg imi spune la un moment dat “acela nu e Crockford?”. Intradevar la masa rezervata era Douglas Crockford alaturi de multe alte personalitati importante de la Yahoo!. Am fugit sa-mi iau cartea (JavaScript: The Good Parts) pe care am adus-o special in speranta ca voi lua un autograf.

    Emotionat m-am apropiat de masa: “Mr. Crockford?”, el a vazut cartea si zambind imi raspunde “Hey, my book!”. Plin de emotie i-am intins pix-ul si l-am rugat sa-mi dea un autograf. Stiu ca suna ridicol, dar pentru mine sa intalnesc o personalitate de talia lui DC despre care doar am citit si l-am vazut in prezentari la Google si Yahoo!, sa-l intalnesc fata in fata, sa am ocazia sa-i cer un autograf si sa-i strang mana a fost ca si cum intalneam un actor celebru.

    Am revenit la masa noastra si m-am laudat la toata lumea cu autograful meu, mi-am zis ca primul punct pe agenda mea a fost atins.

    Au inceput prezentarile:

    • “Hacking 101” de Murray Rowan
    • “YQL and other Y! APIs” de Jon Leblanc
    • “YUI” de Luke Smith
    • “node.js” de Reid Burke
    • “Introduction to Yahoo Messenger API” de Vivek V Aggarwal
    • “Server Sidedness” de Doug Crockford

    Pentru mine node.js si YQL au fost cele mai fascintante prezentari pentru ca nu am mai folosit nici una din tehnologii. Node.js mi se pare foarte interesant pentru jocuri in JavaScript unde comunicarea este foarte dinamica iar PHP nu este foarte potrivit. YQL pe de alta parte, daca stiam de existenta lui probabil ma scapa de multa munca pana acum.

    Dupa prezentari s-a dat startul la hacking. Doi dintre colegi se gandeau sa faca o aplicatie care sa curete pagina de altceva decat continut relevant. Restul de 4 totusi eram un pic debusolati ca nu aveam nici o idee, tot ce era clar era ca vrem sa folosim node.js sau YQL. Am inceput sa ne instalam node.js pe laptop-uri si sa vedem ce stie sa faca. Undeva pe parcurs a aparut si ideea, un joc de snake in retea cu numele “Tequila Worms“. Eu trebuia sa fac partea de UI pentru ca aveam mai multa experienta cu jocuri in JavaScript. Initial am vrut sa refolosesc codul folosit la jocul de meu de snake. Dar era o mica problema, nu aveam sursele originale la mine. Pe de alta parte asta a fost primul meu joc facut in JavaScript, deci nu e tocmai “frumos” scris, asa ca am inceput de la 0 folosind canvas.

    Eram foarte fericit ca lucrez la o aplicatie fara sa ma gandesc la backwards compatibility.

    Pe la 18:30 a mai fost o prezentare a lui Douglas Crockford “The JSON Saga”. Am mai vazut prezentarea pe developer.yahoo.com si credeam ca nu o sa fie foarte fascinanta pentru mine. Dar se pare ca a fost destul de schimbata. O parte interesanta a fost cand pe unul din slide-uri scria mare “IE6 MUST DIE!”, un punct de vedere foarte bun, dar apoi… “IE7 MUST DIE!”, apoi 8, apoi 9. La un moment dar ma intrebam de ce nu a scris pur si simplu “IE MUST DIE!”, raspunsul a venit cu urmatorul slide “IE10 MAY LIVE!”. IE10 este singurul browser de la Microsoft care implementeaza “ECMAScript 5: Strict Mode”. Prezentarea inregistrata este aici: http://www.youtube.com/watch?v=NXiAKPTDXk.

    Dupa prezentare l-am rugat pe Douglas Crockford sa faca o poza cu mine, un motiv in plus sa ma laud ca am fost la eveniment!

    Prezentarea a fost si ultima pana la momentul cand se incheia hackathon-ul.

    Pe la 19:30 a fost partea de “entertaiment”, algoritmi de sortare pe muzica populara:

    A urmat cina si o lunga noapte.

    Dupa cateva ore bune de codare intensiva am facut o vizita pana la sala de jocuri unde ne asteptau: XBOX, WII, masa de Ping-Pong, un aparat de Fuzzball si una o masa de biliard. In timpul noptii am facut mai multe vizite pe acolo ca sa ne relaxam si sa ne dezmortim dupa lungile sederi pe bean bags.

    Undeva dupa miezul noptii cealalta echipa a renuntat la proiect pentru ca s-au impotmolit in YUI, asa ca noi am ramas singurii activi.

    Pe la 3 dimineata cativa dintre colegi au inceput sa adoarma pe bean-bags, dar in echipa noastra somnul nu era o optiune. Ca sa nu adorm de tot am baut 2 sau 3 RedBull, proiectul incepea sa capete forma si am zis ca nu voi adormi pana nu va fi functionala prima varianta.

    Pe la 5:30 dimineata am inchis ochii pentru o clipa si am adormit cu mainile inca pe tastatura timp de o ora, una din cele mai odihnitoare partide de somn de care am avut parte.

    Dimineata a aparut un nou expresor de cafea care avea sa ne mai tina in viata in continuare, iar noi cu forte proaspete am continuat.

    Dupa ce am ajuns la o versiune functionala a fost mai degraba o joaca continua cu scurte pauze ca sa rezolvam si bug-urile gasite pe parcurs. Cred ca parea suficient de distractiv incat pana si Ted Drake a venit sa se joace cu noi.

    Dupa 24h de cand a inceput hackathon-ul s-a anuntat si finalul si a trebuit sa mergem la inscriere. Eu urma sa prezint, eram coplesit de emotie. Am luat un numar, mi-am reglat monitorul si m-am dus la masa.

    Aveam o mica problema, jocul functiona optim folosind websockets in retea si inca nu stiam cum vom face sa prezentam. Dupa putina agitatie am reusit sa stabilim detaliile dar nu si prezentarea. M-am trezit in fata a peste 300 de persoane fara discurs cu un joculet facut literalmente peste noapte. Am terminat foarte repede si nuprea-mi aduc aminte ce am spus, nu puteam sa vad decat reflectoarele in fata ochiilor si credeam ca voi lesina de tensiune, dar ca a iesit ok.

    Au urmat inca 1.5h de prezentari de la aproximativ 50 de echipe.

    Cat timp juriul a deliberat am stat afara si am purtat o scurta discutie cu Luke Smith si una mai lunga cu Reid Burke care pe timpul noptii ne-a oferit o mana de ajutor la proiect. Am inceput discutia cu Reid de la node.js si am terminat cu YUI si de ce nu este foarte popular. Am aflat cat Reid desi nu are decat 22 de ani lucreaza la Yahoo! de 3 ani. La un moment dat discutia a ajuns la faptul ca YUI nu ne-a placut pentru ca are o abordare foarte diferita fata de jQuery, Reid ne-a raspuns foarte deschis la intrebarile noastre explicand de ce este o abordare diferita. Probabil daca YUI ar pune mai bine in evidenta de ce abordeaza unele lucruri diferit ar deveni un framework mult mai popular.

    La premiere Anil Patel (organizatorul) a insistat ca prezentatorii sa stea pe bean bags in fata. Pentru ca juriul intarzia sa revina Anil ne-a povestit despre ce s-a intamplat la alte evenimente Yahoo! Open Hack. Si pentru ca juriul tot nu a aparut ne-a cantat niste Abba.

    S-au anuntat castigatorii:

    • Best Messenger Hack: Yahoo! Social Programming – Corabia Nebunilor
    • Best Yahoo! product enhancement: TheBatMail – The BatMen
    • Best Hack for Social Good: Map of Deforested Areas of Romania – We plant good deeds in Romania!
    • Best Mashup: Ymotion – The Guys
    • Best Local Hack – Tourist Guide – Javascript Team
    • Best BOSS Hack – Take a Hike – Plan 9
    • Hacker’s Choice – The Yahoo! Farm – “Cloud Data in Your BedRoom” – The RoboFun Team
    • Best in Show – Pentru 3 mashup-uri: Take a Hike, Quick info, Playlist-O-Matic – Plan 9 – Alexandru Badiu

    Dupa premiere am aflat si de ce era asa important sa stam pe bean bags, prezentatorii luau bean bag-ul acasa!

    A urmat after-party-ul, dar noi eram mult prea obositi, asa ca dupa ce am fumat o tigare si am baut un pahar de vin am incheiat experienta noastra la Yahoo Open Hack Day Europe 2011!

    Concluzionand, organizarea a fost aproape perfecta, cu toate detaliile puse la punct. Am auzit o discutie ca pregatisera chiar si umbrele in caz ca se strica vremea.

    __

  • Yahoo! Open Hack Europe 2011 la Bucuresti!

    Read this post in English

    Apr 21, 2011 hack Yahoo
    Share on:

    Evenimentul Yahoo! Open Hack Europe 2011 se va desfasura la Bucuresti! In perioada 14-15 mai suntem norocosii europeni care avem acest eveniment.

    La eveniment exista doua tipuri de bilete: Tech Talk si Hacker. Cei care aleg Tech Talk vor asista doar la seminarii si decernarea premilor, pe cand cei care aleg Hacker vor ramane peste noapte sa lucreze la proiectele alese.

    Vor fi prezente personalitati importante din stafful Yahoo!, deci pe scurt este un eveniment care nu trebuie ratat!

  • Scurta istorie a hackerilor

    Dec 8, 2008 hack
    Share on:

    • ««
    • «
    • 1
    • 2
    • »
    • »»

Claudiu Perșoiu

Programare, tehnologie și altele
Mai multe

Postări recente

  • 30 de ani de PHP
  • Slider in Tasmota folosind BerryScript
  • Proiectul care rezista probei timpului
  • Docker in interiorul wsl2
  • Migrând de la Wordpress
  • Calea personalizată pentru Composer cache
  • Magento2 si crudul adevar
  • Un pic de PHP, Go, FFI si atmosfera de sarbatori

DIVERSE 72 PHP 68 JAVASCRIPT 22 BROWSERS 12 MYSQL 12 WEB STUFF 12 MAGENTO 7 DESIGN PATTERNS 5 HARDWARE 3 HOME AUTOMATION 2 LINUX-UNIX 2 GO 1 MISCELLANEOUS 1

PHP 53 JAVASCRIPT 20 PHP5.3 14 MYSQL 13 PHP6 12 PHP5 10 FIREFOX 9 CERTIFICARE 8 INTERNET EXPLORER 8 ZCE 8 ZEND 8 CERTIFICATION 7 MAGENTO 7 HACK 6
Toate etichetele
10 ANI1 3D1 ADOBE AIR2 AJAX1 ANDROID3 ANGULAR1 ANONYMOUS FUNCTIONS3 API1 APP1 BERRYSCRIPT1 BETA1 BOOK1 BROWSER4 C2 CALCULATOARE1 CARTE2 CERTIFICARE8 CERTIFICATION7 CERTIFIED2 CERTIFIED DEVELOPER1 CHALLENGE1 CHM1 CHROME1 CLASS1 CLI2 CLOSURES5 COD1 CODE QUALITY1 CODEIGNITER3 COFFEESCRIPT1 COLLECTIONS1 COMPOSER1 CSS3 CSV1 CURL1 DEBUG1 DESIGN PATTERNS4 DEVELOPER1 DEVELOPMENT TIME1 DIAGRAME1 DOCKER2 DOCKER-COMPOSE1 DOUGLAS CROCKFORD3 DRIVERE2 ELEPHPANT2 ENGINEER1 EXAMEN1 EXCEL1 FACEBOOK2 FEEDBACK1 FFI1 FINALLY1 FIREFOX9 FISIERE1 FPDF1 FRUMOS1 FTP1 GAMES1 GD2 GENERATOR1 GO1 GOOGLE5 GOOGLE ANALYTICS1 GOOGLE CHROME3 GOOGLE MAPS2 HACK6 HARDWARE1 HC-911 HEADER1 HEIGHT1 HOMEASSISTANT2 HTML2 HTML HELP WORKSHOP1 HTML51 HUG1 HUGO1 IDE1 IMAGINE1 INFORMATION_SCHEMA1 INI1 INTERNET4 INTERNET EXPLORER8 IPV41 IPV61 ISP1 ITERATOR2 JAVA1 JAVASCRIPT20 JQUERY1 LAMBDA2 LAPTOP2 LINUX1 LIVELY1 LUNI1 MAGENTO7 MAGENTO22 MAP1 MAPS1 MICROSOFT1 MINESWEEPER1 MOTIVATION1 MSN MAPS1 MYSQL13 MYSQL WORKBENCH1 NGINX1 NODE.JS2 NOFALLOW1 NOSQL1 OBSERVER3 OBSERVER PATTERN1 OOP1 OPERA1 OPTIMIZATION1 ORACLE2 PAGESPEED1 PAIR1 PARSE_INI_FILE1 PASCAL1 PEAR1 PECL1 PERSON VUE2 PHAR1 PHONEGAP2 PHP53 PHP ELEPHANT2 PHP FOR ANDROID1 PHP-GTK1 PHP42 PHP510 PHP5.314 PHP5.46 PHP5.53 PHP5.61 PHP612 PHP7.41 POO1 PR1 PROGRAMMING1 PROIECTE1 RETEA1 REVIEW1 ROCK STAR1 ROMANIAN STEMMER2 RSS1 SAFARY1 SCALAR TYPE HINTING1 SCHEME1 SEO1 SET1 SHOPPING CART PRICE RULE1 SIMPLEXML1 SINGLETON1 SOAP2 SPL2 SQLITE1 SSH1 STACK TRACE1 STDERR1 STDIN1 STDOUT1 STOCATE1 STUDY GUIDE1 SUN2 SYMFONY2 TABLE1 TASMOTA1 TEST TO SPEECH1 TITANIUM2 TRAITS1 TTS1 UBUNTU1 UNICODE3 UTF-82 VECTOR1 VISTA2 WEB2 WEBKIT1 WINBINDER1 WINDOWS2 WORDPRESS1 WSL21 WYSIWYG1 XP3 YAHOO3 YAHOO MAPS2 YAHOO OPEN HACK1 YSLOW1 YUI1 ZCE8 ZCE5.31 ZEND8 ZEND FRAMEWORK4
[A~Z][0~9]

Copyright © 2008 - 2025 CLAUDIU PERȘOIU'S BLOG. Toate drepturile rezervate