Claudiu Persoiu

Blog-ul lui Claudiu Persoiu


Ghid de motivare pentru programatori sau cum sa aiba parte de un challenge adevarat

without comments

motivationIT-ul este probabil unul dintre cele mai dinamice domenii de pe piata de locuri de munca, iar oamenii reprezinta o resursa foarte importanta si totodata limitata.

Si totusi oamenii vin si pleaca destul de des, iar cei mai multi se plang de lipsa motivatiei.

Totul se va termina acum cu acest ghid simplu pentru motivarea programatorilor si nu numai!

Programatorii au nevoie de probleme “challenging”, tot timpul spun ca vor lucruri mai noi si mai challenging, nu?

Da-i un challenge adevarat! Pune-l sa obtina specificatii de la un client care nu stie ce vrea, lasa-l sa se chinuie, eventual lasa-l singur, sa simta adrenalina unei provocari adevarate!

Trebuie retinut ca un programator nu este decat un Project Manager reprimat, da-i sansa sa se exprime!

Dar nu trebuie sa te opresti aici, nu exista provocare mai mare decat sa lucrezi la mai multe lucruri in acelasi timp. O idee buna ca sa maresti complexitatea este sa-i dai ocazia sa lucreze la mai multe proiecte in paralel. Da-i ocazia sa aiba mintea ocupata cu lucruri cat mai diferite, diversitatea este mereu buna, nu?

Un secret pentru a exploata diversitatea la potential maxim este sa aiba atributii diferite pe diferite proiecte, poate un proiect care implica management sa alterneze cu unul de mentenanta. Este pacat sa nu aiba parte de suficienta diversitate!

Scrie prea mult cod? Trebuie sa faci ceva in sensul asta! Atunci cand un programator sta concentrat si lucreaza la ceva nu este nimic altceva decat un strigat disperat dupa atentie. Trebuie sa faci ceva ca sa intrerupi cercul acesta vicios, este de datoria ta ca manager sa-l salvezi!

Trebuie sa gasesti un mod sa-l intrerupi: incearca cu cateva sedinte, ajuta mereu. Daca pare dornic sa iasa din sedinta, este doar un semn ca isi doreste sa intre in urmatoarea sedinta!

In timp o sa observi ca oamenii cu cat sunt mai buni la scris cod, cu atat isi doresc mai tare sa nu mai aiba timp sa faca asta. Totusi, nu iti va spune asta, sau, chiar daca iti spune, este doar pentru ca el nu stie ce-si doreste cu adevarat.

Iar pana la urma, daca ii place atat de mult sa scrie cod, poate ar trebui sa-l duci la nivelul urmator si sa-l pui sa si-l testeze singur. Pana la urma, daca el l-a scris, cine altcineva sa stie mai bine cum sa-l testeze?

Mai este un lucru de mentionat legat de cod in contextul unui challenge. Cand vine un programator la interviu, ce spune el de fiecare data este “vreau sa invat lucruri noi”. Cum aplici aceasta dorinta? Simplu, trebuie doar sa-l pui sa faca ceva ce nu stie! Asa ii prezinti ceva ce este nou si challenging in acelasi timp. Este programator PHP? Nu-i nimic, da-i un proiect de Java! Este programator de Java? Nimic mai simplu, da-i un proiect Objective-C! Poate uneori este greu sa gasesti noi tehnologii pe care nu le cunoaste si pe care nu a incercat deja sa le invete, dar fericirea unui programator nu este un lucru usor de obtinut!

Sa nu cazi in greseala da a acorda salarii corelate cu postul, nu-ti face griji, salariul este confidential, nu vorbeste nimeni despre el. In special atunci cand recomanda un prieten, in mod sigur nu o sa se intereseze de salariul care i-a fost oferit acestuia, doar este confidential, ar fi lipsa de etica profesionala sa se intereseze, nu ar trebui sa-ti faci griji in acest sens.

Si, ca tot am mentionat interviuri, poate uneori te gandesti ca procesul de angajare trebuie sa produca rezultate coerente. Nimic mai gresit, de ce este nevoie cu adevarat? Asa cum am spus si mai devreme: Diversitate! Am citit un articol acum ceva vreme despre firme chinezesti care angajeaza femei frumoase pentru a stimula mediul. Mereu trebuie sa gasesti moduri noi de a integra ultimele tendinte, dar daca tu ai doar posturi tehnice deschise, trebuie sa te descurci cu ce ai. Poate te gandesti ca a angaja pe criterii estetice poate fi problematic uneori, mai ales cand sunt posturi tehnice. In acest caz trebuie sa-ti dai seama ca motivarea trebuie gandita si la scara larga. Da, poate unele echipe o sa se adapteze mai greu la acesti noi membri ai echipei, dar daca persoana respectiva o sa se faca remarcata in orice fel, inseamna ca ai facut o treaba buna!

Sa nu uitam de traininguri si conferinte. Cand ai vorbit ultima oara cu un programator si a zis ca nu-si doreste un training sau sa mearga la conferinte de specialitate?

Motivatia trebuie mentinuta, ca orice alta dorinta. Exista doua componente: dorinta pentru ceva si, nu in ultimul rand, lipsa acelui ceva dorit. Daca iti doresti ceva este pentru ca nu il ai inca, nu-i asa?

Daca nu ai inteles deja, solutia este simpla: nu-l lasa sa aiba acel ceva dorit. Vrea un training? Organizeza trainingul, apoi ai grija sa trimiti persoanele care sunt cel mai putin interesate la el. El o sa vada ca se poate, chiar daca nu pentru el.

Poate asta o sa fie uneori un challenge si pentru management, dar cu multa atentie este realizabil! Pastreaza dorinta vie!

Un alt sfat legat de traininguri: pentru a pastra dorinta vie este util sa-l trimiti la traininguri de care nu este interesat, dar de care este interesat altcineva. Asa o sa ai mereu angajati interesati de traininguri si care fac traininguri, dar care sunt motivati in continuare!

Atunci cand munceste nu trebuie sa vada utilitatea muncii lui, este foarte important. Daca o sa o vada, cum o sa mai fie motivat sa continue? E ca si cum urci un munte, de ce sa-l mai motiveze urcarea daca a vazut cat este de sus? Trebuie sa ai grija sa nu-si dea seama unde a ajuns: este bine sa nu aiba acces la statistici ca nu cumva sa aiba un sentiment de finalitate, de tinta atinsa, de tel realizat, cum ar mai putea fi un challenge atunci?

Si nu uita sa nu-i arati incredere, trebuie sa o construiasca singur. Trebuie sa-i dai o tinta si apoi sa o mentii doar o tinta. Intr-adevar, o tinta atinsa provoaca placere si satisfactia muncii, dar oare tu asta iti doresti sa-i oferi? Gandeste-te la asta putin, de fiecare data cand il lauzi pentru munca realizata o sa mai fie motivat? De ce sa incerci sa-l stimulezi sa se autodepasasca cand poti sa-l stimulezi sa atinga o tinta pe care nu o poate atinge. Nu-i arata ca ai incredere in el, lasa-l sa se chinuie, sa simta challenge-ul.

O vorba spune: “drumul cunoscut e cel mai scurt”. Totusi, unii incearca sa automatizeze lucrurile rudimentare. Practic incearca sa scape tocmai de drumul cunoscut. Efectiv, daca il opresti din automatizarea proceselor il ajuti sa ramana ocupat, il ajuti sa aiba o minte ocupata, iar o minte ocupata este o minte activa!

Si, in al doilea rand, cu aceasta abordare il ajuti sa-si mentina locul de munca. Poate el nu-si da seama, dar daca o sa-si piarda utilitatea cand o sa ramana tocmai fara task-urile pe care, pana la urma, le si cunostea atat de bine, pentru ca le-a facut de atatea ori… Programator sau nu, nu trebuie sa-l lasi sa fie inlocuit de un robot!

In al treilea rand este satisfactia drumului cunoscut – nu-l lasa sa deturneze de la el, oricum, la cat este de cunoscut, ar trebui sa fie destul de scurt.

Nu in ultimul rand trebuie sa-l inveti importanta managementului. Trebuie sa vada ca il poti ajuta, ca tu esti cheia catre succesul lui. Ca sa ii arati acest lucru, trebuie mai ales sa ai incredere in tine. Incearca sa organizezi o petrecere fara sa-l chemi. Nimic nu spune mai mult “puteam sa fiu si eu acolo” decat faptul ca nu ai fost acolo.

Un alt mod este sa-ti organizezi o calatorie de afaceri intr-o locatie exotica. Nu-ti face griji, nu este important sa ai efectiv ce sa faci acolo. Cat timp esti acolo, nu uita sa te distrezi, este foarte important sa stie si el asta. Cand o sa fie obositor trebuie sa-ti aduci aminte ca nu faci asta pentru tine, faci asta pentru el si imaginatia lui!

Poate unele sugestii nu functioneaza la toata lumea, dar trebuie sa incerci sa combini cat mai multe pentru a avea parte de un succes real si programatori cu adevar motivati!

Nu incerca sa identifici aceasta lume utopica, pentru ca orice asemanare cu realitatea cotidiana este pur intamplatoare.

Written by Claudiu Persoiu

4 April 2016 at 9:39 PM

Posted in Diverse

Tagged with ,

PHP6, doar o alta poveste… (PHP6 si cartile)

without comments

Gata, razboiul s-a terminat, PHP7 s-a lansat, iar PHP6 va ramane doar o legenda, o poveste a versiunii care nu a existat.

Dupa o vreme nu cred ca se mai astepta nimeni sa apara, au trecut totusi aproape 10 ani, dintr-un total de 20 de ani de viata pentru PHP.

Dar cum se poate ca o versiune atat de asteptata sa nu apara de loc?

Sa incepem cu inceputul, cand, acum aproximativ 10 ani, PHP devenea un limbaj “serios”. Dupa versiunea PHP5, model obiectual avea in sfarsit vizibilitate specifica pentru metode si proprietati, obiectele nu mai erau copiate, ci trimise prin referinta. Aceste facilitati au generat o multitudine de framework-uri obiectuale, care acum erau destinate si mediului enterprise, nu doar pentru site-uri micute.

In tot acest context exista o problema, internationalizarea.

Asa a aparut PHP6, trebuia sa fie un limbaj care sa foloseasca nativ Unicode, mai specific UTF-16. Asa totul se va procesa intr-un format unic si international.

Proiectul a fost pornit si intretinut de Andrei Zmievski. Poate astazi nu multi au auzit de Andrei, dar acum 10 ani era foarte popular pentru proiecte precum Smarty si PHP-GTK.

Dupa cativa ani proiectul a ramas intepenit, iar atunci a aparut PHP5.3. Acesta, desi aducea schimbari importante, nu era o versiune majora pentru ca inca mai era speranta ca intr-o zi va fi un PHP6.

Existau totusi niste oameni plini de speranta! Si mai ales, care au fost gata sa monetizeze speranta!

Fie ca unii au fost autori, iar altii editori, ei stiau un lucru legat de carti (in special de cele tehnice) ca au niste lucruri clare: un public tinta si o perioada in care este relevanta.

Dar sa analizam si niste rezultate.

PHP_6_and_MySQL_5_for_Dynamic_Web_Sites_Visual_QuickPro_GuidePHP 6 and MySQL 5 for Dynamic Web Sites: Visual QuickPro Guide (3rd Edition) (Peachpit Press – 2008) – Larry Ullman

Larry a scris mai multe carti, printre care: “PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide (2nd Edition)” si evident “PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide”.

Intamplator am avut ocazia sa rasfoiesc toate cele 3 carti, dar nu in ordinea cronologica ci pur intamplator am inceput cu “PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide (2nd Edition)”. Ce e interesant este ca similitudinea este izbitoare, practic a pus un 6 in titlu si in rest aproape ca nu a schimbat cartea de loc.

In general toate cartile Visual QuickPro Guide sunt carti pentru incepatori, iar de la o editie la alta lucrurile nu se schimba prea mult, doar se adapteaza.

Professional_PHP6_Wrox_Programmer_to_ProgrammerProfessional PHP6 (Wrox 2009) – Ed Lecky-Thompson, Steven D. Nowicki (Thomas Myer)

Interesant este ca in imagine apar 3 persoane, dar pe Amazon.com si pe Wrox apar doar doua nume, de asta am tinut sa-l trec separat, este vorba de Thomas Myer.

Ma intreb oare daca Thomas Myer a cerut sa dispara, sau a fost scos? E bizar sa ai numele pe o carte dar sa nu apari in lista de autori pe site-ul editurii.

Nu intamplator exista si o “Professional PHP5” – Ed Lecky-Thompson, Heow Eide-Goodman, Steven D. Nowicki, Alec Cove.

PHP_6_MySQL_Programming_for_the_Absolute_BeginnerPHP 6/MySQL Programming for the Absolute Beginner (Cengage Learning PTR – 2008) – Andrew B. Harris

Este intradevar o carte bizara, nu exista un echivalent de PHP5, ba chiar pe site-ul scriitorului nu mai exista alta carte de PHP: .

Exista oare un motiv? In cazul lui Larry Ullman era un alt subiect atins, un alt public tinta, dar in acest caz e doar ciudat, un singur autor, o singura carte de PHP si intr-o versiune fantoma, publicata in 2008.

PHP_6_Fast_and_Easy_Web_DevelopmentPHP 6 Fast and Easy Web Development (Cengage Learning PTR – 2008) – Matt Telles, Julie C. Meloni

Fara prea multa dificultate am gasit si: “PHP Fast & Easy Web Development” – Julie C. Meloni

Ciudatenia acestei carti este ca Matt Telles nu mai are alta carte de PHP, desi are de Python, C# si C++.

Ceva imi spune ca poate el a fost adus doar ca sa actualizeze cartea originala la noul context. Am crezut ca este doar o parere presonala, doar ca la o cautare pe Google am gasit ca este si Technical Reviewer pentru “PHP 6/MySQL Programming for the Absolute Beginner (Cengage Learning PTR)”, carte care a fost prezentata anterior.

Beginning_PHP_6_Apache_MySQL_6_Web_DevelopmentBeginning PHP 6, Apache, MySQL 6 Web Development (Wrox – 2009) – Timothy Boronczyk, Elizabeth Naramore, Jason Gerner, Yann Le Scouarnec, Jeremy Stolz

Cartea originala a fost evident: “Beginning PHP, Apache, MySQL Web Development” – Michael K. Glass, Yann Le Scouarnec, Elizabeth Naramore, Gary Mailer, Jeremy Stolz, Jason Gerner

Au iesit Michael K. Glass si Gary Mailer, iar in locul lor a intrat Timothy Boronczyk.

PHP a fost un limbaj foarte la moda in perioada respectiva, iar PHP6 a fost foarte asteptat.

Cum se poate totusi asta? Cum se poate sa existe atatea carti de la edituri importante pentru un limbaj de programare care nu a existat? Raspunsul este simplu: lacomie.

Exista doua explicatii posibile: ori autorul a incercat sa acapareze piata cu o noua versiune, ori editura a vrut sa forteze nota, in speranta de a capta piata. Probabil speranta era ca in momentul cand ar fi aparut, ar fi avut cartile deja disponibile pentru livrare.

Acesta este un alt motiv pentru care nu era un plan bun ca versiunea PHP NG sa devina PHP6, ar fi insemnat sa apara o versiune de PHP si sa aiba deja o serie de carti scrise, ba chiar scrise de cativa ani.

Pun pariu ca atunci cand s-a votat intre PHP6 si PHP7 erau niste editori plini de speranta.

In continuare, va urez lectura placuta!

Written by Claudiu Persoiu

22 February 2016 at 9:11 PM

Posted in PHP

Tagged with ,

Yet another PHP 20 blog…

with 2 comments

PHP 20 party

Acum 20 de ani, Rasmus Lerdorf a anuntat aparitia unui nou tool, numit PHP.

Eu am intalnit PHP in 2004, dornic sa fac paginile mele HTML mai dinamice. Cineva mi-a recomandat PHP pentru ca era foarte simplu si usor de folosit. Pentru ca instalarea parea destul de complicata, am folosit PHP Triad. In cateva minute am fost gata sa-mi incep experimentele si am fost cucerit de feedbackul instant oferit.

Pe atunci eram student si cursurile erau bazate pe Pascal si C/C++. Nu-mi placea Pascal pentru ca era deja depasit, iar C avea un sistem complicat de lucru cu memoria si in loc sa ma preocup de gandirea logica, trebuia sa ma preocup de alocarea de resurse.

Acest limbaj nou pentru mine avea sintaxa asemanatoare cu C, dar fara bataia de cap a managementului de resurse. Eliminand acest impediment, am reusit sa-mi dezvolt gandirea logica si chiar sa devin un programator mai bun in general, nu doar in PHP.

In perioada respectiva, PHP nu era considerat un limbaj “serios” de programare, mai degraba unul pentru incepatori. La unul din primele interviuri la care am mers, angajatorul mi-a spus pe un ton cicalitor: “PHP este o jucarie, haide la noi si o sa inveti programare adevarata in ceva serios, cum este FoxPro!” Acela a fost unul din momentele care m-au ambitionat sa ma fac programator PHP.

11 ani mai tarziu, inca pot spune ca este limbajul meu de suflet si ca probabil nu as fi avut o cariera ca programator fara el.

Care a fost prima ta interactiune cu PHP?

Written by Claudiu Persoiu

8 July 2015 at 3:02 PM

Posted in PHP

Tagged with

Collecting Hack

without comments

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:

 

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:

<?hh

function listVector($vector) {
     echo 'Listing array: ' . PHP_EOL;
     for($i = 0; $i < count($vector); $i++) {
          echo $i . ' - ' . $vector[$i] . PHP_EOL;
     }
}

$array = array(1, 2, 3);

listVector($array);

// eliminarea unui element din array
unset($array[1]);

listVector($array);

Rezultatul va fi:

Listing array:
0 - 1
1 - 2
2 - 3
Listing array:
0 - 1

Notice: Undefined index: 1 in ../vector.hh on line 6
1 -

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:

<?hh
… 
$vector = Vector{1, 2, 3}; 

listVector($vector); 

// eliminarea unui element din vector
$vector->removeKey(1);

listVector($vector);

Asa cum am anticipat, rezultatul este:

Listing array:
0 - 1
1 - 2
2 - 3
Listing array:
0 - 1
1 - 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:

<?hh 

$vector = Vector{1,2,3,4}; 

// va functiona pentru ca cheia nr 1 exista 
$vector->set(1, 2);

// nu va functiona pentru ca inca nu exista cheia 4
$vector->set(4, 5);

// nu va functiona din acelasi motiv
$vector[4] = 5;

// pentru a adauga un element nou se pot folosi doar metode care nu specifica cheia
$vector[] = 5;

// sau
array_push($vector, 5);

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

var_dump($vector[$unsetKey]);

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

var_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:

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

Scoaterea elementelor din vector se face folosind:

$vector->remove($key);

Sau, pentru scoaterea ultimului element:

$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:

<?hh 

$map = Map{0 => 'a', 1 => 'b', 3 => 'c'};

array_push($map, 'd');

array_unshift($map, 'e');

var_dump($map);

Va genera urmatorul rezultat:

Warning: Invalid operand type was used: array_push expects array(s) or collection(s) in ../map.hh on line 5

Warning: array_unshift() expects parameter 1 to be an array, Vector, or Set in ../map.hh on line 7
object(HH\Map)#1 (3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [3]=>
  string(1) "c"
}

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:

<?hh 

$map = Map{0 => 'a', 1 => 'b', 3 => 'c'};

// adaugarea unui element folosind sintaxa de array
$map['new'] = 'd';

// adaugarea unui element folosind metoda structurii
$map->set('newer', 'e');

var_dump($map);

Rezultatul va fi:

object(HH\Map)#1 (5) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [3]=>
  string(1) "c"
  ["new"]=>
  string(1) "d"
  ["newer"]=>
  string(1) "e"
}

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:

unset($map[$key]);

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

$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:

$map->contains($key);

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

$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:

<?hh
$set = Set{'a', 'b', 'c'}; 

foreach($set as $key => $val) {
     echo $key . ' - ' . $val . PHP_EOL;
}

Rezultatul va fi:

a - a
b - b
c - 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:

<?hh

$set = Set{'a', 'b', 'c'};

array_push($set, 'd');

array_unshift($set, 'e');

$set[] = 'f';

var_dump($set);

Vom avea un rezultat similar cu cel de la vectori:

object(HH\Set)#1 (6) {
  string(1) "e"
  string(1) "a"
  string(1) "b"
  string(1) "c"
  string(1) "d"
  string(1) "f"
}

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

<?hh

$set = Set{'a', 'b', 'c'};

echo $set['a'];

Va genera eroarea:

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

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

<?hh 

$set = Set{'a', 'b', 'c', 'd'}; 

array_pop($set); 

array_shift($set); 

$set->remove('b');

var_dump($set);

Rezultatul va fi:

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

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”:

$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:

<?hh 

$pair = Pair{'a', 'b'}; 

foreach($pair as $key => $val) {
     echo $key . ' - ' . $val . PHP_EOL;
}

Rezultatul va fi:

0 - a
1 - 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:

<?hh 

$vector = Vector{'a', 'b', 'c', 'd', 'e'}; 

// eliminarea elementului cu valoarea 'a' 
$result = $vector->filter($val ==> $val != 'a');

// eliminarea fiecarui al doilea element folosind cheia
$result2 = $vector->filterWithKey(($key, $val) ==> ($key % 2) == 0);

var_dump($vector);
var_dump($result);
var_dump($result2);

Rezultatul va fi:

object(HH\Vector)#1 (5) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
  [3]=>
  string(1) "d"
  [4]=>
  string(1) "e"
}
object(HH\Vector)#3 (4) {
  [0]=>
  string(1) "b"
  [1]=>
  string(1) "c"
  [2]=>
  string(1) "d"
  [3]=>
  string(1) "e"
}
object(HH\Vector)#5 (3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "c"
  [2]=>
  string(1) "e"
}

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:

<?hh 

$vector = Vector{'a', 'b', 'c'}; 

$vector = $vector->toImmVector();

// eliminarea elementului cu valoarea 'a'
$result = $vector->filter($val ==> $val != 'a');

var_dump($vector);
var_dump($result);

Rezultatul va fi:

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

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:

<?hh 

$pair = Pair{'a', 'b'}; 

// eliminarea elementului cu valoarea 'a' 
$result = $pair->filter($val ==> $val != 'a');

var_dump($result);

Structura rezultata va fi:

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

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”:

<?hh 

$vector = Vector {'a', 'b', 'c'}; 

$result = $vector->map($val ==> $val . $val);

$result2 = $vector->mapWithKey(($key, $val) ==> str_repeat($val, 1 + $key));

var_dump($vector);
var_dump($result);
var_dump($result2);

Rezultatul va fi:

object(HH\Vector)#1 (3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
}
object(HH\Vector)#3 (3) {
  [0]=>
  string(2) "aa"
  [1]=>
  string(2) "bb"
  [2]=>
  string(2) "cc"
}
object(HH\Vector)#5 (3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(2) "bb"
  [2]=>
  string(3) "ccc"
}

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:

<?hh 

$pair = Pair{'a', 'b'}; 

$result = $pair->map($val ==> $val . $val);

var_dump($result);

Va avea ca rezultat:

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

Conversie

Unele elemente pot fi convertite in alte tipuri:

din \ catre Vector Map Set Pair Array
Vector x x x x
Map x x x x
Set x x x
Pair x x x x
Array x x x x

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:

(Map{})->add(Pair {'a', new stdClass()})
    ->toSet();

Va genera eroarea:

Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Only integer values and string values may be used with Sets' in …

2. 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:

$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.

Written by Claudiu Persoiu

30 May 2014 at 11:50 AM

Posted in PHP

Tagged with , , , , , , ,

Limbajul de programare Hack, apocalipsa PHP?

without comments

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:

<?hh 

function a($a): void {
     return true;
}

echo 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:

$ touch .hhconfig

Apoi se ruleaza:

$ 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:

../test.php:4:9,12: Invalid return type
../test.php:3:17,20: This is void
../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:

function a(int $a): void {
     return true;
}

echo a('a');

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

Fatal 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:

<?hh 

$sqr = $x ==> $x * $x;

echo $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:

$add = $x ==> $y ==> $x + $y;

$result = $add(1);

echo $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:

// variabila in scope-ul curent
$z = 5;

$addZ = $x ==> $x + $z;
// schimbat variabila in scope-ul curent
$z = 6;

// efectuat adunare
echo $addZ(1) . PHP_EOL;

Rezultatul o sa fie… 6!

Echivalentul in PHP ar fi:

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

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:

<?hh 

class a {         
     public function __construct(public string $x) {}         
     public function __toString() { 
          return $this->x; 
     }
}

// variabila in scope-ul curent
$z = new a('Claudiu');

$addZ = $x ==> $x . ' ' . $z . '!';

// schimbat variabila care se va folosi la concatenare
$z->x = 'World';

// rulat concatenare
echo $addZ('Hello') . PHP_EOL;

Rezultatul va fi:

Hello 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.

<?hh 

// definirea unei structuri 
newtype Circle = shape('radius' => int, 'b' => int);

// functie care foloseste tipul structurii de mai sus
function areaCircle(Circle $param) {
     return M_PI * $param['radius'] * $param['radius'];
}

// o serie de shape-uri care folosesc structura
$circle = shape('radius' => 10);
$cilinder = shape('radius' => 10, 'height' => 15);

// o structura care nu ar trebui sa functioneze cu Circle
$sqr = shape('side' => 10);

echo areaCircle($circle) . PHP_EOL;
echo areaCircle($cilinder) . PHP_EOL;
echo areaCircle($sqr) . PHP_EOL;

Outputul este:

314.15926535898
314.15926535898

Notice: Undefined index: radius in /home/brand/test.hh on line 6

Notice: Undefined index: radius in /home/brand/test.hh on line 6
0

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!

Written by Claudiu Persoiu

29 April 2014 at 10:15 PM

Posted in PHP

Tagged with , ,

PHP 5.6 awesomeness!

with 2 comments

Nici nu a inceput bine anul si o noua versiune de PHP se pregateste de lansare. La data cand scriu acest blog, este in alpha 2. Se poate descarca de aici: snaps.php.net.

Sunt o serie de imbunatatiri interesante, dar astazi voi vorbi doar despre 3 dintre ele: constant scalar expressions, variadic functions si arguments unpacking.

Constant scalar expressions

Aceasta prima imbunatatire este si singura care nu avea un echivalent inainte de aceasta versiune. Iar, cand spun un echivalent, ma refer doar la clase.

Pana acum, constantele definite folosind cuvantul cheie “const” nu permiteau nici un fel de expresie, se putea folosi doar o valoare scalara, ex:

const INT_CONST = 1;

const STRING_CONST = "string";

const HEREDOC_CONST = <<<'EOT'
nowdoc
EOT;

Evident, mai este si varianta mai interesanta, care permite setarea de constante cu valori dinamice:

define('DYN_CONST', $variable);

Partea proasta este ca acest tip de constanta nu se poate defini pentru o clasa, deoarece pentru aceasta operatiune se poate folosi doar const.

Acum insa se poate folosi:

const ONE = 1;
const TWO = ONE * 2;
const STR = "string of one and two :" . ONE . TWO;

Si, daca asta nu este suficient, exista varianta:

define('FLAG', true);

const EXP = FLAG ? ONE : TWO;

Practic poti seta dinamic valori  pentru o constanta a unei clase! De exemplu, poti seta direct intr-o astfel de constanta tipul de mediu in care se afla utilizatorul, dev sau prod.

Variadic functions

Aceasta este imbunatatirea care imi place cel mai mult, desi are si un echivalent in versiunile mai vechi.

In prezent, daca vrei sa ai o functie cu un numar variabil de parametri, poti face:

function variableParameters () {
     $params = func_get_args();
     foreach ($params as $parameter) {
          echo $parameter . PHP_EOL;
     }
}

variableParameters(1);
variableParameters(1, 2);
variableParameters(1, 2, 3);

Sunt cateva probleme, mai mult sau mai putin evidente, la o astfel de abordare:
1. Din semnatura functiei nu este clar ca accepta mai multi parametri, dimpotriva, pare ca nu accepta nici un parametru;
2. func_get_args poate sa fie apelata oriunde in functie. Daca este pe prima linie, o sa fie evident scopul; daca este pe linia 20 din functie, o sa fie greu de reperat si va genera confuzie.

O alternativa este sa punem un numar de parametri, dar nici asta nu o sa evidentieze comportamentul variabil.

Aici intervine noua abordare:

function variableParameters (...$params) {
     foreach ($params as $parameter) {
          echo $parameter . PHP_EOL;
     }
}

In aceasta noua varianta, este evident ce se intampla cu parametrii functiei. Nu trebuie sa intelegi daca si cati parametri primeste functia, este clar ca acestia au un numar variabil!

In general, cand caut o functie, eu ma uit la definitia ei in IDE inainte sa ma uit la documentatia ei, mai ales ca documentatia de multe ori nici nu exista.

Arguments unpacking

Problema care incearca sa fie rezolvata in acest mod este: ai o functie cu parametri multiplii, iar acestia trebuie trimisi in mod dinamic.

Cum spuneam si mai sus, exista moduri alternative de a rezolva aceasta problema. Sa luam functia din exemplul trecut:

function variableParameters () {
     $params = func_get_args();
     foreach ($params as $parameter) {
          echo $parameter . PHP_EOL;
     }
}

Si acum sa zicem ca este un numar variabil de parametri, iar acestia sunt stocati intr-un array. Ca sa-i pasam nu avem foarte multe solutii:

$params = ['param1', 'param2', 'param3'];

call_user_func_array("variableParameters", $params);

Rezultatul va fi:

param1
param2
param3

In PHP 5.6 vom putea folosi cele 3 puncte, similar cu exemplul de la “Variadic functions”, doar ca aplicati invers. In loc de parametrii pe care ii primeste functia, sunt parametrii care se trimit catre aceasta:

variadicParameters(...$params);

Poate pentru un exemplu de acest fel nu este clar, dar sa zicem ca este un numar fix de parametri pentru functie:

function twoParams($a, $b) {
     echo $a . $b . PHP_EOL;
}

$params = ["Hello", "PHP 5.6!"];

twoParams(...$params);

Chiar daca nu este ceva ce nu se putea face in versiunile anterioare, acum este mult mai elegant.

Iar, ca sa concluzionam, cele doua exemple:

function variableParameters (...$params) {
     foreach ($params as $parameter) {
          echo $parameter . PHP_EOL;
     }
}

variableParamerers(...["cool", "parameter", "unpacking"]);

Cred ca prin aceste mici schimbari de nuanta, PHP face tranzitia de la “the PHP way”, la “the best way”, preluand din alte limbaje.

Written by Claudiu Persoiu

22 February 2014 at 10:17 PM

Posted in PHP

Tagged with ,

Nu PHP 6 nu este aici… dar cum ramane cu 2013?

without comments

Aceasta este o retrospectiva a ultimului an.

In caz ca inca se mai intreba cineva, nu, PHP 6 nu a aparut si nici nu va aparea prea curand, probabil.

De ce este relevant? De cand am inceput acest blog am avut la final de an un post legat de PHP 6 si faptul ca acesta nu a fost lansat. In 2008 era o intrebare populara, dar nimeni nu mai crede asta acum, asa ca voi incheia acest subiect acum. Sa revenim la anul care s-a incheiat.

Aproape de jumatatea anului a fost lansata versiunea PHP 5.5, aceasta aducand in plus functionalitati cum ar fi: finally , generators si multe alte inbunatatiri.

Ca in 5.4, nu sunt functionalitati definitorii pentru limbaj. In aceasta noua versiune chiar sunt lucruri care pot fi inlocuite cu usurinta, dar daca sunt prezente, sunt bine venite.

Chiar daca PHP da dovada de multa dinamica in ultima vreme, cred ca in acest an cuvintele cheie au fost HTML5 si JavaScript.

HTML5 are parte de multe imbunatatiri, iar componente mai vechi incep sa creasca in popularitate. Firmele incep sa investeasca in jocuri care functioneaza in browser folosing WebGL. Chiar si jocuri mai vechi sunt portate catre platforma, folosind tehnologii cum ar fi asm.js.

Si, pentru ca am vorbit de jocuri, mi se pare foarte interesant cum doar acum 5-7 ani jocurile bazate pe JavaScript erau destul de simpliste, iar acum sunt comparabile cu cele de pe PC sau console.

Cred ca revolutia web, pe care multi o asteptau, incepe sa prinda avant. In sfarsit Web-ul este o platforma in adevaratul sens al cuvantului si JavaScript un limbaj cu adevarat apreciat.

Succesul se datoreaza tuturor partilor, nu mai este vorba doar de ECMA sau doar de producatorii de browsere, acum este o adevarat dinamica. Revolutia Web este in plina desfasurare!

Cand vine vorba de backend, lumina reflectoarelor a fost asupra Node.js. Acesta incepe sa devina un jucator important. Au aparut frameworkuri noi si nu mai este o platforma folosita predominant de hackeri dornici sa exploreze tehnologii noi, ci si de companii mari, cum ar fi PayPal, LinkedIn si Yahoo, oferind un vot de incredere pentru acesta. Cred ca Node.js incepe sa-si gaseasca locul si o nisa de piata, iar eu, un fan JavaScript, nu pot sa fiu decat incantat.

Un avantaj al Node.js este ca nu trebuie sa ai grija mai multor versiuni de JavaScript, asa cum este necesar in browser. Asta permite folosirea ultimelor facilitati ECMA in mod liber, un mediu in care poti dezvolta JavaScript fara dureri de cap.

Tehnologic vorbind, a fost un an foarte interesant pentru web development.

In final, va doresc tuturor un 2014 extraordinar de bun!

Written by Claudiu Persoiu

19 January 2014 at 11:10 PM

Posted in Diverse

Tagged with , , ,

Codul epic din filme

without comments

In filmele unde sunt prezenti si hackeri, apare cod sursa care curge in rauri pe ecran. Pare important, pare sa fie un geniu in calculatoare care se pregateste sa revolutioneze ceva.

Te-ai intrebat ce este codul acela epic din filme? John Graham-Cumming a facut o colectie de filme si codul sursa folosit in acestea: http://moviecode.tumblr.com/.

Written by Claudiu Persoiu

5 January 2014 at 12:07 PM

Posted in Diverse

Appcelerator Titanium – cateva impresii

without comments

Nota: Titanium si PhoneGap sunt doua platforme pentru dezvoltarea de aplicatii hibride pentru mobil. Aceste aplicatii nu sunt scrise in limbajul de programare nativ telefonului, dar pot fi distribuite pe mai multe platforme mobile.

Recent, am publicat pe Github cea mai noua si extraordinara platforma de teste, Just-Quizzing pe numele ei. Am facut-o ca sa o folosesc eu personal, dar pentru ca am gasit cativa colegi care au considerat-o utila, am facut-o publica.

In versiunea initiala foloseam SL4A pentru a publica aplicatia pe telefonul meu mobil cu Android. Aveam nevoie de un mod in care sa folosesc aplicatia cand sunt in miscare si nu am acces la Intenet. Din pacate nu exista actualizare automata pentru teste. Am sperat ca SL4A va avea o directie mai clara in timp, dar platforma si-a pierdut din elanul initial, iar eu am decis sa scriu o aplicatie mobila.

Am avut de ales intre PhoneGap si Titanium. In trecut am folosit PhoneGap pentru ca marimea aplicatiei era prea mare in Titanium, dar am zis sa ii mai dau o sansa. In 2011, cand am mai scris despre Titanium, marimea unei aplicatii de baza era aproximativ 4M. In ziua de azi nu mi se mai pare chiar atat de mare, desi este maricica.

Perspectiva va fi in special pentru Android, desi aplicatia a fost facuta sa fie compatibila si cu iPhone.

Am folosit SDK 3.1.3, fara framework-ul Alloy.

Alloy are si el curba lui de invatare si am vrut sa o evit. Scopul aplicatiei era sa fie o versiune portabila a testelor de pe server si nu am vrut sa fac o investitie foarte mare de timp.

Timpul total de dezvoltare a fost putin mai mult de o saptamana.

Prima parere

Lucrurile nu merg chiar asa cum te astepti, nu ai foarte multa flexibilitate. Din timpul total alocat, mai mult de un sfert am incercat sa fac un “flyout menu”, asa cum au aplicatiile ca: Facebook, Google Plus si Youtube. A fost un dezastru total! Singurele variante care chiar pareau sa mearga au fost folosirea unui modul extern sau folosirea widgetul-ui din Alloy.

Se pare ca la conversia dintre coordonatele relative, unde utilizatorul a atins elementul curent, la punctul efectiv, unde esti pe ecran, exista o discrepanta mare si este imposibil sa faci un efect decent de deschidere a meniului. Intr-un final am renuntat total la acest efect.

Viteza nu este chiar atat de buna cand vine vorba de randare de elemente. Sincer, ma asteptam la o viteza mai buna. Exista mici trucuri care se pot face, de exemplu sa preincarci view-urile inainte sa le afisezi, dar pentru asta trebuie sa interpretezi cam ce va face utilizatorul in continuare, lucru care nu este posibil mereu.

Un alt elemente care m-a deranjat este ca la apasarea butonului de meniu pe Android nu poti pune o actiune anume, sa zicem sa deschida meniul lateral de care vorbeam anterior. In PhoneGap de exemplu, nu se va deschide nici un meniu, acesta trebuie construit din HTML de la zero.

Cand au aparut, Titanium se laudau ca poti dezolta o data si distribui pe mai multe platforme. Acum am avut surpriza ca nu mai au aceasta abordare. In Kitchen Sink, aplicatia care demonstreaza facilitatile platformei, fiecare tip de platforma initializeaza aplicatia in fisierul ei. Unul dintre motive este ca design-ul se face dinamic daca nu vrei sa folosesti Alloy, nu prin fisiere de layout.

Printre primele lucruri pe care le-am incercat cu Titanium a fost sa vad cat este marimea unei aplicatii simple de “Hello World”. Impachetata, aplicatia ocupa ~8.5M, instalata pe telefon ~16M. Nu stiu ce parere aveti voi, dar mie mi se pare foarte mult! Ciudat este ca aplicatia mea finala ocupa ~8.4M impachetata si ~16M instalata, aproape identic cu aplicatia originala. Motivul este simplu, imaginile puse de mine ocupa cu cativa kb mai putin, rezultand in final o aplicatie putin mai mica decat aceea de la care am pornit.

Dar de ce ocupa o aplicatie Titanium atat de mult?

Am avut de cautat pana am gasit raspunsul. In 2011, cand am incercat sa ma documentez, nu am gasit decat ca sunt impachetate toate librariile chiar daca sunt necesare sau nu si din acest motiv este atat de mare. Nu asta era cauza! Intre timp, am aflat adevaratul motiv. Aplicatia ruleaza folosind un “bridge” intre Android si JavaScript. Codul JavaScript nu este “compilat”, asa cum reiese din prezentarile initiale, ci pur si simplu interpretat.

Codul JavaScript este interpretat folosind unul din motoarele disponibile in aplicatie (V8 si Rhino) si apeleaza componentele care construiesc elementele grafice native.

Problema este la interpretoare (engine). Acestea sunt destul de mari si sunt practic prezente in fiecare aplicatie. Si, de parca nu erau destul de mari, sunt si 3, fiecare cu scopul lui:

  • V8 – pentru versiuni de Android noi (dupa Gingerbread 2.3);
  • Rhino – pentru versiuni vechi de Android (inainte de Gingerbread 2.3);
  • x86 – pentru procesoare de tip Intel.

Aceste 3 engine-uri ocupa in total, dezarhivate, 19M pe calculatorul meu. Deci, fara sa eliminam o parte din ele nu avem cum sa scadem dimensiunea.

O metoda prin care cei de la Appcelerator vor sa scada dimensiunea apk-ului este sa renunte la Rhino, dar in acest mod se va pierde si compatibilitatea cu versiuni mai vechi de Android.

Comunitate

Exista o comunitate foarte activa. Pe forumuri si platforme Q/A este plin de intrebari si raspunsuri! Trebuie sa recunosc ca am fost impresionat din acest punct de vedere. Unele intrebari sunt relativ vechi, chiar si de 3 ani de zile.

Curba de invatare

Pentru o saptamana si aproape jumatate, din care mai bine de un sfert am cautat cum sa fac un efect de miscare al unui view, care pana la final nu a functionat, eu zic ca a mers destul de repede!

Recunosc, m-am mai jucat acum 3-4 ani cu el pentru cateva zile si chiar mi-am amintit anumite lucruri, cum ar fi ca erau elemente de tip window, view si label.

Faptul ca gasesti usor raspunsuri la intebarile de pe Stackoverflow, adunate in cativa ani, dar si ca exista o documentatie destul de bine organizata a ajutat foarte mult.

De asemenea si pe Youtube exista cateva tutoriale utile.

Mediul de dezoltare

Pentru primele versiuni nu exista un IDE, aplicatiile erau scrise cu un editor la alegere, apoi impachetate si testate folosind platforma.

Acum exista un IDE care are la baza Eclipse. Numele acestuia este Titanium Studio. Acesta are un autocomplete destul de reusit, care ajuta in cele mai multe cazuri. Are si cateva lucruri care nu merg prea bine, cum ar fi faptul ca mie uneori nu mi-a mai mers syntax highlight, fara sa-mi indice unde este problema. De asemenea, administrarea proiectelor mi se pare un pic ciudata si am avut cateva probleme la importul si exportul de proiecte.

Nu exista implicit o unealta vizuala de editare a elementelor din fereastra. Atat Xcode cat si ADT permit editarea de elemente cu drag & drop. Se pare ca exista si unelte de acest tip, dar nu sunt gratuite.

Emulatoarele nu sunt foarte configurabile. Partea buna este ca nu trebuie sa-ti bati capul, selectezi sistemul de operare si tipul de display si Titanium va configura automat un emulator. Partea proasta este ca poate mi-ar placea sa am un management al resurselor mai clar.

Un alt dezavantaj este ca uneori aplicatia pur si simplu moare pana porneste emulatorul, iar daca incerci din nou va incerca sa mai porneasca un emulator fara succes, caz in care trebuie inchis emulatorul, rulat Project clean si apoi incercat din nou, cu grija sa nu ratam momentul cand se poate debloca ecranul, sau scenariul de la inceput se va repeta.

Pentru iPhone nu merg log-urile cand vine vorba de OS X Mavericks.

Parti bune

Se invata relativ usor.

Documentatia este destul de bine realizata, iar acolo unde ceva nu este clar, sigur a mai intebat altcineva aceeasi intrebare.

Exista o comunitate destul de mare.

IDE-ul este usor de folosit.

Este usor de vazut cam ce este posibil in aplicatia Kitchen Sink.

Aplicatia nu arata ca o pagina web intr-un WebView!

Parti rele

Aplicatia ocupa foarte mult spatiu (16M pe telefon).

Elementele grafice sunt doar niste subseturi din platformele suportate.

Nu este foarte rapid, din cauza faptului ca avem codul intepretat si nu compilat, ca sa poata interactiona direct cu OS-ul.

Nu exista un editor vizual.

Exista probleme de integrare cu emulatoarele, atat pentru Android cat si pentru iPhone.

Concluzie

Daca esti un cunoscator al limbajului JavaScript, ai nevoie repede de o aplicatie si vrei sa foloseasca elemente grafice native, atunci probabil Titanium este pentru tine.

Daca vrei performanta, probabil trebuie sa te orientezi spre altceva.

Eu nu am suficienta experienta cu SDK-ul Android cat sa pot construi aceasta aplicatie in timpul care l-am avut, acesta a fost compromisul meu.

Sincer, nu sunt sigur daca PhoneGap era o optiune mai buna sau nu, vorbind de cazul meu paticular. Astazi exista multe librarii de JavaScript facute special sa emuleze elementele grafice native intr-o aplicatie PhoneGap. Diferenta nu este neaparat vizibila si, pana la urma, uneori poate aplicatia chiar nu trebuie sa arate ca o aplicatie standard, poate o interfata complet diferita este mai potrivita.

Written by Claudiu Persoiu

24 December 2013 at 1:13 PM

Posted in JavaScript

Tagged with , ,

Construind o noua generatie de programatori intr-o societate de consum

without comments

Motivat de articolul lui Rober Martin – Hoards Of Novices, am decis sa scriu si eu un articol pe un subiect similar.

Nu vreau sa scriu despre nevoia angajatorilor de a angaja juniori, ci despre de ce acesti juniori nu se ridica la nivelul asteptarilor, iar pentru final, despre ce am putea face pentru o mai buna pregatire.

Piata software este intr-o continua expansiune. Software-ul este modul in care comandam calculatorului ce sa faca. Astazi, dispozitivele din jur au procesoare, software si aplicatii, de la telefoane, ceasuri, televizoare si pana la masini de spalat si frigidere. Toate aceste dispozitive au nevoie de programe si programatori ca sa dezolte aplicatii pentru ele.

Cu aceste premize ajungem la criza software. S-a ajuns la concluzia ca avem nevoie de software mai repede pentru a rezolva aceasta criza. Acesta a fost un subiect important in anii ’60, dar cu timplul lumea nu i-a mai dat importanta.

Pentru a rezolva aceasta problema au aparut limbaje de nivel inalt si framework-uri. Limbajele de nivel inalt fac dezoltarea si intretinerea unei aplicatii mult mai simpla. In acest mod programatorii se indeparteaza foarte mult de “metal”, de hardware-ul efectiv, lucrand cu notiuni mult mai usor de manipulat.

Intr-o lume a limbajelor de nivel inalt (Java, C#, PHP, Python, JavaScript etc.) este mult mai usor si mai rapid sa compui o aplicatie.

Si totusi, desi modul de dezoltare al aplicatilor devine mai simplu, calitatea programatorilor este si ea in scadere.

O societate de consum

Avem nevoie de scoala pentru o slujba mai buna.

Pentru ca nevoia de studii reprezinta astazi o nevoie generala, scoala in sine se dilueaza. Principiile educationale in mare parte nu au suferit schimbari fundamentale de cand educatia a devenit disponibila tuturor. Rezultatul procesului de invatare este examenul, pentru ca asa se determina nivelul cunostintelor. Si mai presus, un rezultat mediocru ne permite sa avansam, fara sa demonstreze ca baza evaluata este prezenta.

Trecerea la nivelul urmator se face print-o examinare partiala, nu trebuie sa stapanesti 100% din notiuni, ci doar 50-60%. Nu este neaparat clar daca in celalate 40-50% se afla notiuni importante.

Aceasta problema a educatiei este mai mult sau mai putin o problema generala si sunt putini cei care chiar incearca abordari diferite.

In general, eu nu consider scoala un sistem definitoriu de stabilire a cunostinelor, mai ales astazi, cand avem acces la un volum atat de mare de alternative.

Cand studentii termina scoala, ei nu au toate notiunile pentru a lucra efectiv in industrie, ceea ce nu este atat de anormal. Scoala trebuie sa ofere doar o baza generala. De exemplu, in invatamantul superior pot sa-mi amintesc cel putin 8-9 limbaje de programare invatate. Efectiv au fost mai multe, dar nu am tinut o evidenta detaliata. Este clar ca nu ai cum sa cunosti atatea limbaje de programare la nivelul la care sa produci. Pe de alta parte, ai o idee de abordare, care te poate ajuta sa stabilesti o directie in care vrei sa aprofundezi.

Aceasta este cheia, sa aprofundezi! Pentru asta fiecare are abordarea lui, aici poti sa-ti alegi singur calea, fie cursuri, carti, proiecte practice sau toate la un loc. Prin aprofundare ajungi la nivelul la care angajatorii nu doar te accepta, dar te vaneaza!

De multe ori, pasiunea inlocuieste total studiile. Am cunoscut mai multe persoane care, desi nu au studiat informatica, sunt acum profesionisti in ea.

Partea buna este ca multa lume aprofundeaza de placere si sfatuiesc pe oricine citeste aceste randuri sa caute placerea in ce fac. Aceasta este cea mai buna motivatie.

Educatie alternativa intr-o societate de consum

Pentru ca metoda traditionala de invatamant nu este tocmai suficienta, sa vorbim de cateva metodele alternative:

  • carti
  • cursuri
  • tutoriale
  • articole/bloguri

Carti
Cartile in mod traditional sunt cea mai buna sursa de informatii (cel putin pana la aparitia Internetului). Dar calitatea nu este garantata!

Acum 8-9 ani am incercat sa cumpar o carte pentru JavaScript. Selectia nu era foarte mare asa ca am incercat sa analizez fiecare carte in parte.

La final am fost dezamagit de alegerea facuta pentru ca in loc sa ma invete JavaScript, cartea ma invata cum sa fac efecte speciale pe pagini (foarte populare in perioada respectiva).

In cazul meu particular, am gasit raspunsul mult mai tarziu intr-o prezentare a lui Douglas Crockford. Acesta spunea ca majoritatea cartilor de JavaScript sunt de acest fel si a recomandat o singura carte in afara de cartea scrisa de el, JavaScript: The Definitive Guide.

Cauza este simpla, lumea este mult mai atrasa de carti care promit sa te invete un limbaj sau tehnologie intr-un numar limitat de lectii sau zile. Vrem totul acum, dar studiul are nevoie de timp, trebuie sa intelegi notiunile, nu doar sa le treci in revista intr-un mod rapid.

In general, ca sa determini calitatea unei carti ar trebui sa cauti review-uri. In ziua de astazi este foarte usor, eu prefer Amazon.com dar nu numai. Asa poti determina daca este ce cauti.

Uneori si o perspectiva rapida este utila, mai ales daca nu ai alt mod de abordare pentru subiect, dar in general orice subiect abordat rapid nu-ti ofera o perspectiva generala, ci doar o introducere usoara.

Cursuri

Sunt multe cursuri, atat in clasa cat si on-line. La fel ca si in cazul cartilor, este greu sa determini calitatea cursului.

Cursurile promit multe, dar de multe ori nu trateaza in detaliu subiectele, iar la final chiar daca ai impresia ca ai invatat multe, cand vine vorba de aplicat realizezi ca orice variatie de la materialele cursului te pune in dificultate.

Ca si in cazul cartilor, referintele sunt foarte importante! Din pacate pentru cursuri nu sunt la fel de multe ca pentru carti.

Incearca sa vezi subiectele abordate si detaliul de abordare. Sau uneori poti gasi mai repede referinte pentru profesor decat pentru curs.

Tutoriale

In special pe Internet sunt foarte multe tutoriale care promit sa te invete un domeniu, dar nu reusesc sa te invete cum sa realizezi exemplul lor. La final nu poti realiza decat mici variatiuni de la exemplul initial. De multe ori, cel care face tutorialul are cele mai bune intentii, dar este greu sa faci un transfer de informatii.

Pentru cele care sunt gratuite este foarte simplu sa determini daca abordarea este potrivita sau nu pentru nevoile privitorului. Incearca sa privesti cateva episoade si vezi daca la final ai inteles cum functioneaza componenta respectiva. Daca poti doar replica, atunci poate mai ai de cautat.

Partea buna este ca sunt foarte multe si ai de unde alege in general. De exemplu, la un limbaj de programare poti vedea in referinta oficiala cam ce ar trebui sa inveti, apoi in tutorial vezi daca ai inteles punctele din referinta si ai o idee ce fac.

La variantele comerciale este mult mai greu, pentru ca de multe ori ai doar un preview introductiv, insuficient pentru a-ti forma o parere. In aceste cazuri ar trebui sa cauti review-uri.

Bloguri si articole

Partea buna aici este ca investitia in timp este relativ mica. E simplu sa-ti formezi o parere la final.

Dezavantajul este ca unele articole nu se actualizeaza o data cu tehnologia. Trebuie sa te asiguri ca exemplele functioneaza pe versiunea folosita de tine. Din experienta proprie pot spune ca acest lucru este greu si necesita mult timp. De exemplu, unele articole care inca mai atrag cititori pe acest blog sunt scrise acum cativa ani si, daca nu mai folosesc tehnologiile respective, nu mai sunt tentat sa le tin la curent.

Cum sa invatam mai bine

Cauta referinte pentru materialele care presupun o investitie de timp si/sau bani: carti, cursuri sau tutoriale.

Atunci cand te hotarasti sa abordezi un subiect, incearca sa vezi ce materiale recomanda altii. Internetul este plin de materiale de diferite grade de dificultate.

Cand te simti stapan pe un subiect, testeaza-ti cunostintele. Construieste o aplicatie, urmareste subiectul pe platforme de Q/A sau, de ce nu, scrie un tutorial pentru altii. Intelegi mult mai bine un subiect cand il descrii altora.

Exerseaza! Este foarte important sa folosesti ce inveti sau vei uita mai repede decat crezi. Contribuie la proiecte open-source, incearca sa-ti faci proiecte personale sau incearca sa adaptezi proiectele altora la nevoile tale. Github este o unealta forte buna pentru a gasi si publica proiecte.

Este putin mai greu la inceput sa intelegi codul altuia, dar in industrie este imperativ ca sa poti colabora cu altii.

Invata lucruri noi tot timpul. Tehnologia se schimba, la fel cum se schimba si perspectiva asupra ei. De exemplu, AJAX a aparut la sfarsitul anilor “90, dar perspectiva asupra cum acesta se poate folosi s-a schimbat dramatic in anii urmatori, chiar daca tehnologia nu s-a schimbat mult timp. La fel a fost si cu JavaScript, desi a apatur la inceputul anilor “90,  abia dupa anii 2000 a inceput sa fie considerata o unealta utila, inainte era folosita in special pentru efecte speciale.

Mult timp, PHP a fost considerat un limbaj util doar pentru proiecte mici. Astazi, este limbajul preferat de giganti ai internetului cum ar fi Facebook si Yahoo!. O data cu popularitatea si abordarea asupra lui a fost schimbata pentru o performanta si scalabilitate mai buna.

Concluzie

Sistemul educational nu ofera performanta de care angajatorii au nevoie. Asta creeaza o discordanta intre asteptarilor angajatorilor si cele ale absolventilor, iar asta nu este doar o problema a informaticii.

Din pacate si materialele alternative uneori promit lucruri nerealiste, unii studiaza tehnologii si limbaje de programare luni de zile, iar altii promit rezultate dupa doar cateva zile sau chiar ore.

Din fericire, traim intr-o lume a informatiei si putem gasi nu doar materiale ci si pareri despre acestea.

Printr-o mai buna pregatire, sansele de angajare cresc considerabil, rezultand intr-o satisfactie mai mare de ambele parti.

Written by Claudiu Persoiu

17 December 2013 at 11:18 PM

Posted in Diverse