iPhone şi Palm Pre din perspectiva maimuței programatoare

Tocmai am apucat să arunc primul ochi succint peste documentația SDK-ului Palm Pre. Bine, ştiu că Palm Pre pierde din start. Nu e cool. Dacă ai tricou cu De puta madre 69 şi ai Palm Pre, nu eşti cool, ai doar un gadget de care toată lumea pare să mai fi văzut. Dacă ai iPhone eşti cel mai tare de la tine de la bloc. Dar totuşi am câteva gânduri de scris pe tastatură despre asta.

Mai întâi, lucrul extrem de plăcut la SDK-ul Palm Pre este că e uşor de învățat şi de început. Objective-C e scârbos. Arată ca o rață cu testicule legate de guşă şi picioare de hipopotam. Nu-i nici chiar C, nici chiar Smalltalk, şi în consecință te simți ca şi când IDE-ul C face mişto de tine şi te pune să scrii cod Smalltalk şi iners. CocoaTouch e un framework monstruos. Până scrii un HelloWorld trebuie să treci prin vreo 100 de pagini de documentație, din care jumătate numai ca să pricepi cum se foloseşte InterfaceBuilder şi de ce.

Palm Pre foloseşte HTML, CSS şi JavaScript. Pentru mine asta e destul de naşpa, fiindcă nu pot nicicum să înghit programarea web la nivelul ăsta, nu cu instrumentele de dezvoltare de la ora actuală. Parcă am revenit la a scrie aplicații Motif, doar că arată mai frumos şi nu trebuie să fiu atent la managementul memoriei — în rest e la fel de incomod şi de enervant. Avantajul e că pot să reciclez cunoştințele pe care le am deja, ceea ce în cazul CocoaTouch nu e cazul. Practic, e ca să înveți sa foloseşti eficient Palm Pre, trebuie doar să absorbi câteva convenții, să te uiți câteva ore pe exemple şi sa parcurgi succint documentația. Asta înseamnă să foloseşti tehnologii standard, iar ideea este, din punctul meu de vedere, salutară. Ca să înveți CocoaTouch trebuie s-o iei de la Adam (cu coastele deținute integral), pe când în cazul Palm Pre, majoritatea viitorilor dezvoltatori ştiu inclusiv cum să o învețe pe Eva să facă sex anal.

Al doilea lucru care mi se pare eminamente superb la Palm Pre este că platforma de dezvoltare nu este exclusiv OS X pe procesoare Intel şi ultima versiune punct. Adică, dacă ai un PowerMac G5 dual care încă se ține excelent, şi vrei să scrii programe IpodTouch, poți să-l vinzi şi să iei juma’ de iMac pentru că nu se poate — instrumentele respective nu există. Nu pentru că ar fi imposibil per se, ci pentru că nu vrea Apple (la fel ca majoritatea lucrurilor pe care nu le poți face cu produsele lor). Nu mai vorbesc de oropsiții care vor să facă asta şi n-au decât calculatoare cu Windows.

Ba mai mult, mi se pare foarte util şi faptul că platforma respectivă nu e legată de un anume IDE. Mă calcă pe nervi când cineva face asta. XCode e un IDE foarte bun, nimic de zis, dar sunt mai productiv cu Emacs. Nu pentru că Emacs e mai tare, pentru că e extensibil sau pentru că are o jumătate de chiuvetă în plus, ci pentru că îl folosesc dinainte ca Xcode măcar să apară. Blow me, Apple.

Singura chestie prohibitivă pentru mine e că, momentan, Palm n-a pus la dispoziție un SDK nativ. Nu e vorba numai de faptul că ideea de a scrie aplicații web prefăcându-te că ai la dispoziție tehnologie desktop mi se pare abjectă, ci de performanță în sine. De exemplu, visez de mai multă vreme să scriu un emulator (ca lumea) pentru, să zicem, C64, pe care să-l am cu mine pe un dispozitiv portabil. Pe iPod nu se poate pentru ca Apple nu vrea (şi evident respinge aplicațiile respective, deci it’s a no go). Folosind JavaScript presupun că se poate, dar ideea e că nu vreau să ruleze chiar ca C64 şi sa încarce un joc în cinci minute.

Oricum, vroiam să spun doar atâta: în stilul tipic pentru ultimii doi-trei ani de evoluție a celor de la Apple, Palm le-au dat o lecție excelentă despre cum se tratează dezvoltatorii. Desigur că pe băieții din Cupertino îi interesează foarte puțin asta, fiindcă piața lor e atât de mare încât, în calitate de code monkey, suport cu stoicism faptul că, la fiecare release al programelor lor, urinează pe mine de undeva din stratosferă (din păcate asta e o atmosferă întreținută de restul audienței Apple, care nu numai că suportă cu stoicism, dar aplaudă entuziasm când respectivii se pişă pe ei, cam ca adolescenții cu aere intelectuale la concertele lui Tudor Chirilă). Dar pe mine mă interesează asta, fiindcă SDK-ul Palm Pre chiar îmi face viața de primată mai uşoară.

Cel mai întârziat răspuns ever — despre programarea funcțională în România

Dintr-un motiv necunoscut mie, s-ar părea că n-am primit alertele de la comentariile din ultima vreme. Aşa că va trebui să-i răspund Oanei după… hmm… o lună și jumătate :) . O să răspund în ditai postul în caz că mai interesează pe cineva subiectul, şi în speranța că în felul ăsta o să ajungă şi la Oana :-) .

Deci, Oana întreba:

Buna.Stiu ca postul e mai vechi si poate ca subiectul nu mai e printre preocuparile tale actuale,dar dupa ce-am rascolit putin rezultatele google legate de subiect,pari o persoana in masura sa-mi spuna parerea sa despre care sunt perspectivele unui programator in programarea functionala.
Eu stiu Scheme(basics) si ma intereseaza Haskell.Se aude ca Haskell ar fi
cel mai productiv limbaj functional utilizat in Inteligenta artificiala, prelucrari multimedia, Retele Petri,motoare de baze de date , analize statistice si financiare-ar parea sa aiba multe aplicatii.Concret,considerand toate vorbele de lauda ca adevarate,este el apreciat?Cat este de cautat(e posibil sa devina popular candva?)….exista programatori in Romania care folosesc mare parte din facilitatile limbajului sau doar … il folosesc pe alocuri.?
(la inceput de drum)eu sunt in cautarea unui limbaj care sa-mi placa ,care sa imi mentina interesul , sa-l stapanesc foarte bine si sa-l folosesc practic(nu doar din pura placere) ,iar pana acum programarea functionala ma tenteaza cel mai tare.
Astept raspunsul tau cu nerabdare . Multumesc pentru posturile tale legate de subiect(celealte nu le-am citit…inca)!

Vis-a-vis de asta am următoarele lucruri de zis:

  1. Şi eu sunt de părere că Haskell ar fi, la ora actuală, cea mai bună alegere, în sensul că este activ dezvoltat, are cel puțin un compilator bun, este portabil şi are un număr mare de biblioteci. Problema principală cred că e legată de documentație, fiindcă nu e prea bine adaptată unei audiențe formate din oameni practici. De asemenea, stai departe de Real World Haskell, e o introducere fără prea mult simț pedagogic și de pe la capitolul 8 o să te întrebi cum naiba poate cineva să învețe rahatul ăla. Scheme e de asemenea o alegere bună, din aceleași motive (minus documentația care e de mult mai bună calitate), dar așteaptă-te la coșmaruri legate portabilitate. De asemenea, vei lua cunoștință cu situația în care vei reinventa cel puțin o roată, fiindcă există mai multe implementări majore, fiecare având în plus ceva față de oricare celelalte dar având în minus cel puțin un feature util. Mie unuia cel mai practic limbaj din domeiu mi se pare Common Lisp (în principiu datorită macro-urilor și a facilităților de programare imperativă), dar comunitatea CL a avut grijă să zădărnicească aproape orice încercare de utilizare practică.
  2. Din câte știu, nu există nicio firmă din România care să folosească Haskell sau Scheme pentru proiecte serioase (a se citi: pentru care să te plătească). Dealtfel în general limbajele astea sunt folosite azi aproape exclusiv pentru SF-uri ca cele menționate de tine mai sus (analiză financiară, inteligență artificială, data mining ș.a.m.d.). Desigur, lucrul ăsta nu e surprinzător ținând cont că un număr mare de firme din România abia încep să afle că există și alte tehnologii decât PHP şi MySQL.
  3. Ca părere personală: programarea funcțională nu cred că e o paradigmă cu aplicabilitate largă. E perfect adecvată câtorva domenii, dar în mare parte nu mi se pare o soluție e scară largă. Eu unul am o problemă cu o paradigmă care spune că anumite operații (între care incidental intră cele de I/O :-D ) sunt nocive pentru programare și ar trebui evitate. Totuși, cred că integrarea facilităților de programare funcțională în cadrul limbajelor imperative actuale (un drum pe care Python, de exemplu, e de mai multă vreme și pe care, dacă nu mă înșel, a intrat nu demult și C#), e o soluție mult mai utilă și mult mai expresivă.

Când user-friendly e prea user-friendly

Post-ul de față este între altele un exercițiu de diplomație, pentru că am alergat după problema asta vreo oră şi ceva. Nu sunt enervat, doar respir ceva mai repede :-) .

Treaba e cam aşa: am zis să iau taurul de coarne şi să învăț să lucrez cu CocoaTouch, adică SDK-ul folosit la dezvoltarea aplicațiilor pentru iPhone şi iPod Touch. Seamănă leit cu Cocoa, doar că e adaptat unei platforme ceva mai limitate. Taurul are nişte coarne destul de insipide pentru mine din punct de vedere “istoric”: am lucrat cu OpenStep înainte ca Apple să schimbe instrumentele de dezvoltare, şi nici atunci prea mult. Ceea ce a ajuns Cocoa acum seamănă cu ce țineam eu minte, dar numai cât să mă înşele, fiindcă de fapt s-au schimbat cam toate detaliile. Dacă NeXT pusese la dispoziție un Developer’s Guide absolut excelent, Apple are o documentație pe care, după ce o lecturezi o zi întreagă, vii acasă şi-ți bați nevasta, copiii şi mai ales soacra, pentru că e foarte multă, foarte detaliată, foarte prost organizată şi foarte prost indexată.. Ceea ce înseamnă că poți găsi orice dacă ai timp să cauți. De asemenea, până nu demult, nu exista cam nicio carte decentă. Rezultatul e că eu învăț să folosesc CocoaTouch cu toate că n-am reuşit niciodată să folosesc Cocoa cum trebuie şi am uitat cam tot ce ştiam despre Openstep. Pentru mine, standardul în domeniu este Qt, care mi se pare un framework excelent în ciuda faptului că stă călare pe C++.

Unul dintre instrumentele cu care NeXT a rupt gura târgului atunci când a lansat NeXTStep este ceea ce astăzi a ajuns la Apple ca Interface Builder (Cocoa este de fapt fostul NeXTStep — în caz că se întreabă cineva ce-i cu NS-ul din fața tuturor claselor). Interface Builder-ul ăsta este, după cum îi spune şi numele, un program cu care poți desena interfețele — numai că face ceva mai mult de-atât, după cum o să explic imediat.

În cazul Qt, “traseul” uzual pentru realizarea interfeței este (sau ultima oară când am lucrat cu Qt, acum câteva luni, era), în mare, cam aşa: se porneşte prin a plasa butoanele, meniurile şi toate celelalte în Qt Designer. Qt Designer generează apoi (automat) o clasă care reprezintă interfața, clasa respectivă fiind însă “chioară” (constructorul ei nu inițializează conexiunile evenimentelor din interfață cu acțiunile din cod — fiindcă n-are de unde să ştie care-s alea). Pentru a realiza conexiunile respective, maimuța din fața tastaturii trebuie să scrie o clasă care o moşteneşte pe cea generată, în care să realizeze conexiunile necesare, să “numească” delegații ş.a.m.d.. Conexiunile se pot realiza şi automat, via nişte constrângeri legate de denumire a funcțiilor, dar când am folosit Qt prima dată (asta fiind, ce-i drept, acum vreo cinci ani) trebuiau făcute manual.

Prin comparație, treaba în cazul Xcode şi IB e mult mai simplă: obiectele din interfață care trebuie accesate prin cod sunt declarate punându-li-se IBOutlet în față, iar acțiunile la care evenimentele din interfață sunt conectate se declară punându-li-se IBAction în față; scrii clasa obiectului care joacă rol de controller (outlet-urile fiind între variabilele instanțelor respective, acțiunile aparținând controller-ului ca metode, strunjite evident în bunul spirit al MVC), după care IB “se prinde” automagic şi faci conexiunile respective prin cel mai tineresc drag’n'drop posibil.

Avantajul e că toată treaba durează puțin şi că metoda e fantastic de flexibilă. Practic, numai pe seama sus-pusei integrări, se sare peste o grămadă de etape (ceea ce am schițat mai sus e numai în linii mari şi am sărit peste câteva amănunte).

Dezavantajul vine pe urmă, dacă ai făcut vreo trăznaie. În cazul meu, trăznaia în cauză a fost aceea de a greşi clasa unui view controller. Mai exact, conectasem un view la un controller care nu era al lui (era vorba de acelaşi tip de view — un picker — doar că unul avea două “roți” şi celălalt — una singură). Inutil de spus că nu mergea. Mesajul de eroare?

*** Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[<DatePickerViewController 0x525a60> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key doublePicker.’

Din păcate, tot ce am înțeles din mesajul ăsta era că încercam să accesez valorile afisate de un DatePicker folosind cheia “doublePicker”, ceea ce mi se părea extrem de improbabil pentru că nu obişnuiesc să scriu programe când sunt beat mangă. Ok, să zicem că o exegeză mai atentă a textului m-ar fi convins că e vorba de altceva, dar tot nu e destul.

Problema cu care mă confrunt în momentul ăsta e că nu “văd” tot codul din spatele aplicației. E foarte tare faptul că o bună parte din cod e generată de IB şi de Xcode, dar eu nu sunt învățat să depanez altceva decât cod din ăla bătrânesc, cu text. Sursa problemei am găsit-o până la urmă, dar cu foarte mare greutate fiindcă era într-o fereastră din InterfaceBuilder.

Bineînțeles, vina e în principiu a mea, cu atât mai mult cu cât trecerea de la C şi ASM e foarte zgrunțuroasă pentru mine. Însă e interesant cum o parte din zgrunțul trecerii ăsteia vine din faptul că instrumentele cu care am de-a face au o paradigmă atât de diferită. Dacă aş fi făcut o greşeală de genul ăsta lucrând cu Qt, reflexul meu imediat ar fi fost să mă uit pe codul generat de Qt Designer şi moc, şi probabil că mi-ar fi luat cinci minute să mă prind de unde vine. Nu pentru că Qt e mai tare şi nici pentru că Apple sunt nişte capitalişti infecți, ci pentru că mintea mea e mai învățată cu liniile de cod decât cu imaginile. Pentru mine, nivelul ăsta de user-friendly e prea… user-friendly, şi trebuie să mă învăț :-) .

NewLisp: Primele impresii

Am avut de curând de încropit câteva scripturi rapide; nimic spectaculos — câteva operațiuni simple, executat câteva comenzi externe, uploadat nişte fişiere pe FTP, un frontend GUI fără pretenții (două butoane browse şi un buton Upload…), genul de lucru pentru care Python sau Bash ar fi arhisuficiente. Mai mult ca să văd cum se descurcă, am încercat NewLisp, cu care mai avusesem câteva contacte, şi a mers foarte bine. Pe scurt:

Ce-mi place

  • Documentația. E scurtă, simplă, la obiect, şi mai ales, pentru Dumnezeu, spune ceva din când în când. Comparativ cu Hyperspec, chestia asta e un rai — totul e explicat pe scurt, cu câteva exemple simple şi clasificat rezonabil. Prin comparație, e mai uşor să scrii tu o funcție decât să vezi dacă există ceva asemănător în Hyperspec.
  • Foarte uşor de distribuit. Bine, ASDF e foarte flexibil, dar asta numai pentru cine are LISP instalat. Pentru cine nu, se poate oricând distribui o imagine, care în cazul SBCL are câțiva MB pentru un amărât de Hello, world.
  • Toolkit-ul GUI. E bazat pe Java, e portabil şi arată rezonabil. Se foloseşte uşor. Prin comparație, CL are ceva echivalent — LTK, bazat pe Tk (a se citi: urât ca munca), documentat ca pe şervețele, lent (nu foloseşte vreun FFI, ci Wish) şi extrem de enervant. Mai există câteva binding-uri pentru Gtk, dar alea n-au documentație nici cât să umpli o fițuică, d-apoi un şervețel.
  • Portabil în limitele normalului. Standardul CL corespunde foarte bine realităților din anii ‘80 (lucru care se simte cel mai bine în modul cum construieşte pathname-urile). Realitățile din 2008 sunt, din păcate ce-i drept, mai puțin complexe.

Ce nu-mi place:

  • Câteva din tipurile de date din CL nu-s pe-aici, deci dacă îi era cuiva dor să implementeze ad-labam un hash table, acum e momentul.
  • Comparativ cu orice implementare CL, e leeeent. Bine, pentru scripting nu se simte, dar NewLisp se autodescrie ca fiind destinat calculelor ştiințifice. Nu ştiu ce calcule ştiințifice fac ăia, dar se poticneşte vizibil chiar şi la sarcini simple.
  • IDE extrem de stresant. Din fericire, se integrează suficient de bine cu SLIME pentru ceea ce se vrea.

Pagina oficială e aici.