2015 m. vasario 9 d., pirmadienis

Funkcinis programavimas?

Kol kas tik palengva įsisavimu funkcinio programavimo sąvoką.
Kiek suprantu, tai programavimas 1) be priskyrimo operatorių, 2) su visokiom anoniminėm f-cijom, lambdom, 3) rekursijom?
Jei reikėtų iš tešlos padaryti didelio raganosio formos sausainį, turint pradžioje tešlos gumulą, tai funkciškai programuojant, tas tešlos gumulas visaip tampomas (visas, ar tik jo dalis), bet visada lieka monolitinis, o programuojant struktūriškai tas gumulas plėšomas, iš jo formuojamos būsimo raganosio dalys, kurios kažkada - suklijuojamos.
Į funkcinį programavimą man panašu: 
* užklausos duomenų bazei;
* komandinės eilutės konvejeriai;

Patinka Ruby kalboje kad galima duomenį (ar jų paketą) keisti paeiliui iš kairės į dešinę parašytomis funkcijomis, primena konvejerio struktūrą. Pvz. gets().chomp.scan().gsub().... Patogu tai, kad duomuo po funkcijos panaudojimo dažniausiai nekeičiamas (nebent yra galimybė po funkcijos vardo prirašyti šauktuką), ko nėra Perl'e. Perl'e yra naujas regex'ų modifikatorius "r" - kaip tik nedestruktyvus - patogus keitimams, nekuriant nereikalingų kintamųjų.

Šiandien kažkiek valandų praleidau Project Euler svetainėje, mėgindamas spręsti matematinius uždavinius, o atsakymus išgauti Perl'u. Tai kai kurie uždavinių sprendimo priėjimas atrodo tinkamas spręsti funkciškai. Pvz. 42-ą užduotį sprendžiau taip:

$a{ $i += $_ } //= 1 for 1 .. 50;
print eval join '+', map { 0 + exists $a{ eval join '+', map /\w/ && -64+ ord $&, split/\B/ } } split /,/, <>

Čia buvau pasidaręs reikšmių hash'ą. O tada, visus nuskaitytus duomenis apdoroju funkcijomis paeiliui, nekurdamas kintamųjų, ir apdorojęs išvedu atsakymą. Neapsieičiau čia be "eval" funkcijos.

Panašiai uždavinys 30:

print eval join '+', map { $_ * ($_ == eval join '+', map $_ ** 5 , split // ) } 1 .. 1e6