-
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.
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.
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!
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!
-
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:
1const INT_CONST = 1; 2 3const STRING_CONST = "string"; 4 5const HEREDOC_CONST = <<<'EOT' 6nowdoc 7EOT;
Evident, mai este si varianta mai interesanta, care permite setarea de constante cu valori dinamice:
1define('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:
1const ONE = 1; 2const TWO = ONE * 2; 3const STR = "string of one and two :" . ONE . TWO;
Si, daca asta nu este suficient, exista varianta:
1define('FLAG', true); 2 3const 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:
1function variableParameters () { 2 $params = func_get_args(); 3 foreach ($params as $parameter) { 4 echo $parameter . PHP_EOL; 5 } 6} 7 8variableParameters(1); 9variableParameters(1, 2); 10variableParameters(1, 2, 3);
Sunt cateva probleme, mai mult sau mai putin evidente, la o astfel de abordare:
- Din semnatura functiei nu este clar ca accepta mai multi parametri, dimpotriva, pare ca nu accepta nici un parametru;
- 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:
1function variableParameters (...$params) { 2 foreach ($params as $parameter) { 3 echo $parameter . PHP_EOL; 4 } 5}
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:
1function variableParameters () { 2 $params = func_get_args(); 3 foreach ($params as $parameter) { 4 echo $parameter . PHP_EOL; 5 } 6}
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:
1$params = ['param1', 'param2', 'param3']; 2 3call_user_func_array("variableParameters", $params);
Rezultatul va fi:
1param1 2param2 3param3
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:
1variadicParameters(...$params);
Poate pentru un exemplu de acest fel nu este clar, dar sa zicem ca este un numar fix de parametri pentru functie:
1function twoParams($a, $b) { 2 echo $a . $b . PHP_EOL; 3} 4 5$params = ["Hello", "PHP 5.6!"]; 6 7twoParams(...$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:
1function variableParameters (...$params) { 2 foreach ($params as $parameter) { 3 echo $parameter . PHP_EOL; 4 } 5} 6 7variableParamerers(...["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.
-
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!
-
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/.
-
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.