[rosedu-general] Pure mathematics and programming

Adrian Scoica adrian.scoica at gmail.com
Fri Nov 4 12:42:48 EET 2011


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


More information about the rosedu-general mailing list