Vreau sa scriu despre acest subiect de mai multa vreme, dar abia acum am fereastra si chef.
Ceea ce programam se imparte in doua categorii: a) Tool-uri tehnologice (de exemplu, shell-uri, programe de baza, drivere, module de kernel...) b) Algoritmi Eu voi vorbi aici de a doua categorie, care mi se pare nu neaparat mai challenging sau mai frumoasa, dar cu siguranta mai greu de pus pe "hartie" cand implementezi. Motivul? Majoritatea rationamentelor matematice frumoase sunt formalisme. Termenii fibonacci se scriu f(x) = f(x-1) + f(x-2), f(0) = 0 f(1) = 1. Porning de aici, notam cu un simbol si putem scrie ecuatii cu ei la nesfarsit fara sa ne facem griji de faptul ca nu incap in 32 biti, de rang, de recursivitatea exponentiala, etc... Cand scrii un algoritm pentru o masina fizica, lucrurile nu mai stau asa de simplu. Trebuie sa iti "incapsulezi" rationamentul in limitarile fizice ale arhitecturii, si sa scoti hack-uri oribile care sa profite de memorie, si alte trait-uri tehnologice. Asta inseamna sa iti poluezi limbajul in care scrii cu constructii sintactice care nu au legatura cu algoritmul, un lucru care mie mi se pare gresit deoarece amesteci doua niveluri de exprimare in acelasi limbaj. Limbajele imperative sufera masiv de chestia asta, si au aparut doua solutii care sa le adreseze: a) Limbajele functionale b) Metalimbajul Limbajele functionale sunt extrem de elegante, dar pierd putin contactul cu realitatea. Trebuie translatate in cod imperativ ca sa poata fi executate, deci apare cortina de fier a compilatorului prin care programatorul nu mai poate vedea decat ceea ce i se arata. Pe de alta parte, C++ a ales o cale mai... obscura si aspru criticata: Metalanguage. Sau cu alte cuvinte, extinderea limbajului astfel incat sa se poata descrie singur. Din pacate, Metalanguage este inca black magic si curba de invatare e aproape verticala, In template metaprogramming putem scrie functii care se folosesc de gramtica limbajului C++ si sunt complet libre de contrangeri fizice, urmand ca apoi sa "instantiem" respectivul cod cu specificati reale. De exemplu: template<class N> bool search(N key, Collection<N>& container); Metafunctia de mai sus poate fi scrisa profitand de structura _algebrica_ a tipurilor N si Collection, fara a tine cont de modul in care sunt reprezentate si operate. In momentul in care scrii in cod search<int>(1, v), faci fitting la grupul algebric peste ceva real: tipul "int". Dar asta nu e tot ceva abstract? Well..., da si nu. Metafunctiile si metaclasele sunt scrise in acelasi limbaj ca si codul concret. Atunci cand scrii in cod search<int>, de fapt compilatorul iti "genereaza" respectiva functie ca si cum ai fi scris-o tu de mana, deci practic este un nivel distinct in compilare si nu introduce overhead la runtime (!! foarte important asta !!). Mai mult, folosind TMP, poti traversa granita dintre compile-time si run-time, specificand inclusiv executia de cod in timpul instantierii (de exemplu, preprocesari :-??). In template metaprogramming am vazut cele mai frumoase si elegante implementari pentru lazy evaluation, function closures, si alte concepte ce tin de programarea functionala, despre care puteti citi aici[0]. C++0x o sa mai depaseasca o limitare a limbajului permitand function literals. Is this going in the right direction? Well, in mod clar implementarile nu mai sunt black box, ceea ce iti da un sentiment placut de control. Pe de alta parte, gramaticile devin rupte din iad (fun fact: g++ nu parseaza corect C++, m-am lovit de mai multe ori de asta). At the end of the day, totul tine de gustul personal al fiecaruia. Eu daca _chiar_ am nevoie de lazy eval si inchideri functionale, le prefer pe cele din Boost, altcineva ar putea prefera sa se orienteze spre alt limbaj... eventually, matematica este _unica_ stiinta reala. Restul e doar... stamp collecting. [0] - http://www.boostpro.com/mplbook/metafunctions.html _______________________________________________ http://lists.rosedu.org/cgi-bin/mailman/listinfo/rosedu-general
