Despre unelte și alte nebunii

August 30th, 2008 Alex

Când eram mai mic și se vroia să fiu redus la tăcere, aveam o glumă preferată … „acum tac, gata am tăcut, nu mai zic nimic, am aruncat cheia, sunt silențios …” :) Nu prea mă pot abține.

M-am jucat în ultimul timp cu .NET și sunt chiar incitat de posibilitățile platformei, care este compusă practic dintr-o mașină virtuală, câteva compilatoare și o colecție de biblioteci de cod. Pentru un obsedat de limbaje ca mine, îmi plac următoarele:

  • F# - un dialect ML în mare parte compatibil cu Ocaml, cu plugin de VS 2008, iar odată cu ultima versiune a apărut și F# Developer Center
  • IronPython și IronRuby sunt 2 interpretoare funcționale ce pot fi folosite în Silverlight (exemplu)
  • C# 3.0 care a devenit un limbaj interesant (vezi tutorial programare funcțională)
  • DLR - o colecție de optimizări pentru interpretarea eficientă a limbajelor dinamice + un metaobject protocol ce ar putea permite comunicarea între 2 limbaje dinamice … cum ar fi apelul de metode scrise în IronPython din cadrul IronRuby.

Îmi plac limbajele de programare, și cred că este un fetiș, dar nu prea-mi pasă :) Momentan mă joc cu F# și mi se pare extrem de cool, și cu un design mai curat decât Scala, care pare a fi o struțo-cămilă deloc reușită.

Dar oricum, după cum spunea Steve Jobs: „real artists ship”. Și „code talks, bullshit walks”, sau cum era? :) Degeaba folosești limbajul zeilor dacă ești incompetent.

Posted in compilers, programming | No Comments »

Obsesie pentru limbaj

April 5th, 2008 Alex

Timp de 5 luni am fost departe de casă, apartamentul meu fiind trecut printr-un dureros proces de renovare.
Asta a presupus o separare drastică a timpului liber de comoditățile cu care eram obișnuit, printre care și accesul la Internet, iar la servici întotdeauna se găsesc lucruri mai bune de făcut. Suntem totuși fericiți, eu și soția mea iubită, că totul s-a terminat și că suntem în sfârșit acasă.

Desigur, o parte din motivul pentru care nu sunt prea activ pe blog ține de abilitatea mea de a-mi exprima sentimentele în cuvinte. De multe ori simt o anumită idee, sau o anumită concluzie ca urmare al unui șir de evenimente ce au dus la observarea unui șablon, dar în lipsa unui limbaj adecvat sunt incapabil de multe ori să pun lucrurile în perspectivă și prefer să tac din gură. Fără un limbaj bogat procesele cognitive nu funcționează la capacitate maximă. Fără un limbaj adecvat nu ai ordine în idei și o astfel de idee pe care nu o poți exprima în mod eficient nu o poți folosi în construcții mai complexe (nu scalează).

Și ca o paranteză, vă rog să-mi scuzați articolul kilometric, dar n-am reușit să-mi exprim aceste gânduri într-un mod mai succint ;)

Este interesantă astfel paralela care poate fi trasată între programare și comunicarea dintre oameni. Programarea propriu-zisă este procesul prin care comunici unui calculator ideile. Iar cea mai mare problemă din informatică ține de managementul complexității, și dacă exită o determinată, printre colecțiile uriașe de cunoștințe empirice pe care le avem, este eterna complexitate a proiectelor ce crește de multe ori exponențial.

Programarea este cunoaștere.

Ideile sunt într-adevăr exprimate în limbaje străine oamenilor obișnuiți, dar acele limbaje sunt necesare deoarece limbajul natural are o gramatică non-deterministă și este nevoie de inteligență umană pentru a-l înțelege. De fapt, dacă ar fi să definim inteligența umană, am putea-o defini drept capabilitatea de a înțelege și de a comunica folosind limbajul natural (iar mulți oameni de știință sunt de părere că am evoluat din maimuțe odată cu dezvoltarea acestui mijloc eficient de a comunica). Desigur, și un cățeluș este un suflet, și un cățeluș comunică, dar limbajul său este rigid, se naște cu el și nu poate defini noi cuvinte decât foarte greu (există și excepții … Bella, fetița mea rottweiler, își scurură urechile când vrea afară, și-mi citește starea de spirit de cum mă vede, dar desigur, Bella este fata mea).

Practic poți păcăli teoria evoluției deoarece nu este nevoie de mii de generații ca organismul să se adapteze mediilor noi în care trăiești. Poți pur și simplu învăța de la alți oameni experiențe, greșeli, tehnici, și chiar și sentimente. Dacă te-ai ars cu focul, copiii tăi o vor învăța de la tine (deși câteodată este inevitabil pentru copii să repete aceleași greșeli, dar nu mai se pot scuza că n-au știut).

Încet, încet am ajuns la concluzia că cea mai importantă calitate a unui inginer (excluzând ambiția, calitate cu care probabil te naști) NU este folosirea eficientă a uneltelor, și nici învățarea perpetuă de lucruri noi, deși sunt calități destul de importante. Cea mai importană este capabilitatea de exprimare cât mai eficientă a ideilor.

Și ca să pun aceste vorbe în contextul profesiei mele … cu toți simțim asta mai ales când suntem cocoșați de complexitatea unui proiect ce a avut parte de alegeri neinspirate, sau poate o auzim de la alții, dar cred că este nevoie de o oarecare maturitate să o recunoști …

Modularizarea este banală și de multe ori ineficientă, mult mai scalabilă este abstractizarea meta-lingvistică (vezi [1])

Când am început să simt acest adevăr, prima reacție a fost să caut un limbaj de programare mai eficient, mai “enterprise”, mai popular. Eram în liceu și programam mici joculețe în Pascal. Eram total nemulțumit [2] în primul rând datorită restricțiilor impuse de compilator, și prima reacție a fost să învăț C++, deși n-am văzut nici o lumină când transformarea s-a încheiat. O a doua revoltă a fost odată cu trecerea de la PHP la Java, deoarece PHP îmi dădea impresia de jucărie, sau de la Java la Python, într-o încercare de reconciliere cu limbajele dinamice, încercând să-mi regăsesc latura pragmatică.

Există din păcate programatori ce nu reușesc să vadă valoarea limbajelor de programare. Și acești programatori formează o majoritate semnificativă.
Iar din anumite perspective au dreptate să o facă …

  1. un editor de texte deștept poate alina durerea cauzată de folosirea unui limbaj rigid pentru un domeniu pentru care nu a fost proiectat, cazurile cele mai populare fiind C++, Java și C#, iar mulți speră ca într-o zi un IDE le va alina probleme probabil prin citirea gândurilor :) (pentru o părere în acest sens vezi [3]).
  2. Tehnologiile informatice evoluează extrem de rapid, și ce este nou astăzi poate fi depășit peste un an
  3. Un limbaj nou vine cu paradigme noi (de cele mai multe ori, exceptând clonele cu mici variații), și este mai greu de învățat decât un framework nou
  4. Paradigmelor noi nu le observi oricum utilitatea decât după o perioadă de folosire în probleme reale

As long as our hypothetical Blub programmer is looking down the power continuum, he knows he’s looking down. Languages less powerful than Blub are obviously less powerful, because they’re missing some feature he’s used to. But when our hypothetical Blub programmer looks in the other direction, up the power continuum, he doesn’t realize he’s looking up.

(Beating the Averages, Paul Graham [4])

Practic, un limbaj prea diferit de limbajele cu care ești obișnuit are potențialul de a te face să te simți incompetent (vezi plângerile celor ce au încercat Haskell). Și nimeni nu suportă asta.

Și din păcate toată lumea a devenit obsedată de rezultate și câștiguri rapide, de comoditizare, de ieftin și debarasabil, în timp ce adolescenții sunt orbiți de poveștile oamenilor ce au câștigat la Loto, sau de poveștile adolescentelor ce se mai cuplează cu câte un Irinel și cu prețul demnității au parte de succes fără efort (sau cel puțin așa se vede din exterior).

Și vorbind de aparențe, îmi aduc aminte de filmulețele demonstrative ale framework-ului ASP.NET [5]. Și sincer, câtă strălucire, câtă ușurință … trei click-uri, și țaca-paca ai un website complet. Și cât de naiv am fost să cred asta. Pentru că odată ce te apuci de mult subestimatele “probleme reale”, observi cât de non-standard și de problematic este mecanismul de postback, sau cât de rigide sunt componentele standard, sau cât de complex este pipeline-ul prin care se răspunde la un request (lovindu-te de problema abstracțiilor prea ambițioase [6]), sau cât de departe este ASP.NET de paradigmele și șabloanele de proiectare standard folosite în aplicațiile web uzuale, sau cât de rar este folosit ASP.NET pentru proiecte populare, deși tehnologia are deja 7 ani vechime (singura excepție semnificativă fiind MySpace). OK, știu că a mai evoluat, și că ultima versiune în sfârșit vine cu MVC (wow), poate sunt un pic rău, dar tot nu m-aș mai atinge de ASP.NET odată ce m-am fript.

În spusele lui Erik Naggum (vorbind de Haskell vs Lisp) …

If you have a language that is good at demonstrating such things, maybe it has been optimized for demonstrations? At least one really huge software company has made the bulk of its earnings on its ability to demonstrate to other people … what they could do.

From the Latin word “imponere”, base of the obsolete English “impone” and translated as “impress” in modern English, Nordic hackers have coined the terms “imponator” (a device that does nothing but impress bystanders, referred to as the “imponator effect”) and “imponade” (that “goo” that fills you as you get impressed with something — from “marmelade”, often referred as “full of imponade”, always ironic).

Erik Naggum, comp.lang.lisp

Un alt exemplu de regresie în industria IT este obsesia programarilor de a mapa modelul de reprezentare a datelor relaționale în obiecte. SGBD-urile relaționale au multe defecte, iar sistemul relațional de reprezentare a datelor (tabelar), deși cu multe defecte, ne este mai intuitiv decât programarea orientată pe obiecte (cred că și un copil de 5 ani poate pricepe un tabel). Este însă o oarecare prăpastie între obiectele din OOP și datele din sistemul relațional, agravată de necesitatea programatorilor de a învăța SQL. Oh, da. Deși SQL-ul este cea mai utilă abstractizare meta-lingvistică pe care o cunosc, mulți programatori sunt mai mult decât fericiți să folosească metode și clase Java, prost concepute aș mai adăuga, pentru interogări.

De ce ar a vrea cineva să folosească Hibernate sau DB4O, în loc de SQL, cumva îmi scapă.

Adică, dacă vrei validarea automată a tipurilor de date, nu este mai bine să folosești un limbaj mai flexibil?
Dacă vrei să treci facil la MySQL, de la Oracle, nu poți scrie un compilator? Atât teoria [7], cât și uneltele necesare [8] sunt valabile de câțiva zeci de ani, iar uneltele curente au evoluat atât de mult încât este posibilă scrierea unui parser pentru un limbaj relativ complex în câteva ore, cu tot cu teste unitare.

Și da, când vine vorba de compilatoare există un șoc inițial, cauzat de concepte nefamiliare majorității. Și nerăbdarea cu care vrei să aplici aceste tehnici este un dezavantaj.

the clumsiness of people who have to engage their brain at every step is unbearably painful to watch, at least to me, and that’s what the novice-friendly software makes people do, because there’s no elegance in them, it’s just a mass of features to be learned by rote. however, this suits people a hell of a lot better than setting out at age 6 to become a great ballet dancer and
achieving their goal 20 years later after every tendon and muscle and joint has been asked to perform just a little bit more than nature ever intended over and over and over again. to most people, this is insanity. but in reality, it’s art, and it’s the _art_ in what we do that makes us human.

once you have attained that level of effortless and carefree performance, you forget the pain.

Learning Emacs, by Erik Naggum [11]

La ce se reduce totul?

Eu am acceptat abstractizarea meta-lingvistică drept o alternativă la modularizare. Mi-a luat ceva timp, și am trecut prin durere căutând ceva timp limbajul perfect, mediul de dezvoltare perfect, etc… Voi lăsa însă la o parte mănușile și voi îmblânzi dragonul [7].

Limbajele de programare nu sunt nici zei ce trebuie idolatrizați, dar nici efecte secundare ce trebuiesc suportate în așteptarea unui IDE mai bun. Sunt doar unelte de abstractizare a complexității.

Cred că abstractizarea meta-lingvistică este explicată mai bine în cursul 6.001 de la MIT [9], acompaniat de celebra referință Structure and Interpretation of Computer Programs [1].
Deasemenea, vezi … Growing a Language, de Guy Steele [10].

Bibliografie

  1. SICP, chapter 4
  2. Pasiune de copil, si o alegere personala (lexoft.eu)
  3. It’s the IDE, dummy
  4. Beating the Averages
  5. ASP.NET tutorials
  6. Leaky Abstractions, Joel Spolsky
  7. Compilers, the Red Dragon book ;)
  8. Antlr, Bison, Flex
  9. Structure and Interpretation of Computer Programs (Video Lessons)
  10. Growing a Language, Guy Steele
  11. Learning Emacs, Erik Naggum

Posted in compilers, passion, rant | 4 Comments »

Durere și limbaje de programare

February 13th, 2008 Alex

Iubesc limbajele dinamice, și apreciez din ce în ce mai mult Python. Nu este atât de cool ca Ruby, dar își face mai bine treaba (d.p.m.d.v), fiind concis și bine documentat, iar bibliotecile și uneltele valabile sunt bestiale (vorbind de unelte bestiale, încearcă IPython - consolă python cu auto-completion, printre altele).

Mai mult decât atât, din experiență proprie pot afirma cu o oarecare certitudine că Python are cele mai multe și mai bune bindings-uri pentru biblioteci externe, neegalat momentan de restul plutonului, iar pentru bibliotecile unde stă mai prost (e.g. Aspell) există întotdeauna CTypes sau Boost.Python.

Limbajele dinamice sunt perfecte pentru exploratory programming, acolo unde specificațiile sau soluția problemei nu se cunosc. Și sincer să fiu, astfel de probleme sunt exact motivul pentru care am ales să fiu programator și încerc din răsputeri să stau departe de probleme ce au devenit o comoditate. Desigur, dacă vrei să rezolvi o problemă ce a fost deja rezolvată, cum ar fi să implementezi un shopping cart, poți oricând copia funcționalitățile unui sistem deja făcut, și-ți poți permite să creezi design-ul de la început, îți poți permite să adaugi pe parcurs constrângeri modulelor, îți poți permite să definești o ierarhie rigidă de clase, îți poți permite să folosești Java. Dar folosind un limbaj rigid ca Java pentru explorarea unei probleme nerezolvate este ca și când ți-ai alege cu atenție cămașa înainte de a pleca într-un safari … o pierdere de timp.

Dar limbaje ca C++ și ca Java nu pot fi evitate … lăsând la o parte așa zisa siguranță oferită de tipizarea variabilelor, late-binding-ul limbajelor dinamice suferă de performanță. Și până una-alta, dacă vrei performanță brută, și nu-ți poți permite să arunci bani asupra problemei (cum ar fi construirea unei ferme de calculatoare și paralelizarea prelucrării prin MapReduce), nu prea ai ce face și de voie/nevoie trebuie să folosești un limbaj static ce poate fi compilat într-un mod eficient.

Am descoperit Scala, un limbaj static cu o sintaxă flexibilă ce combină OOP-ul cu concepte funcționale, iar compilatorul poate genera bytecode Java sau dotNet. Cu alte cuvinte în Scala se pot refolosi biblioteci scrise în Java, fiind un limbaj pentru JVM.

Scala repară practic tot ce este în neregulă cu Java. De exemplu nu mai există diferențe între primitive și obiecte, tipul Int fiind o clasă normală, iar literarii integer fiind instanțe ale clasei Int. Scala mai este capabil de closures (cu o sintaxă mai flexibilă ca cea din Ruby, dar la fel de light). Iar multe elemente din syntactic-sugar-ul limbajului pot fi redefinite tot în Scala. De exemplu blocurile While ar putea fi definite astfel …

def WhileAlex (p: => Boolean) (s: => Unit) = {
if (p) { s; WhileAlex(p)(s) }
}

Iar noua construcție ar putea fi folosită la fel ca un while normal …

val i = 0
WhileAlex (i < 10) {
println(i)
i += 1
}

Deasemenea, că tot vorbeam de exploratory programming, Scala este capabil de type-inference (compilatorul își poate da seama de tipul unei variabile în majoritatea cazurilor fără asistența programatorului), printre alte bunătăți, cum ar fi pattern-matching, sau mixins (traits, cum sunt denumite în Scala), iar prin implicit conversion poți avea ceva similar cu extension-methods din C# 3.0, sau cu clasele deschise din Ruby. Iar cireașa de pe tort sunt bineînțeles Actorii din Scala, ce pot fi folosiți pentru programare concurentă folosind aceași paradigmă cu cea din Erlang.

Și am menționat oare că există și un framework web scris în Scala? Este în stadiu alpha, dar arată destul de bine;)

Singura problemă cu Scala este documentația oficială (un pic cam peste nivelul unui programator neobișnuit cu concepte funcționale). O bună introducere pentru programatori de Java am găsit însă aici: Roundup Scala for Java Refugees

Un alt blog ce tratează Scala ar mai fi: http://alblue.blogspot.com/search/label/scala

Bineînțeles, mai există Wiki, plus documentația oficială. Iar Scala poate fi downloadat de pe website-ul oficial.

Posted in compilers, scala, technology | 3 Comments »

Links (27-11-2007)

November 27th, 2007 Alex

N-am mai postat link-uri de mult. Internet acasă nu mai am, și mi-e mai dificil pe moment (pot în schimb scrie articole uriașe și extrem de plictisitoare când n-am ce face :) ).

Compilatoare

Theory of Computation [aduni.org]
- curs foarte bun de limbaje formale / automate (înregistrări video de la cursuri / seminarii).

Let’s Build a Compiler, by Jack Crenshaw
- tutorial pentru construcția unui compilator … poate fi de ajutor la studierea cărții dragonului.

Design and Implementation of Object-Oriented Virtual Machines
- curs despre design-ul și implementarea de mașini virtuale pentru limbaje OOP

Basics of Compiler Design
- curs de teoria compilării

JVM Languages [googlegroups]
- grup de discuții despre implementarea de limbaje ce rulează deasupra la JVM (orientat mai mult pe limbaje dinamice)

Posted in compilers, links | 3 Comments »