Az elmúlt hónapban végre rávettem magam, hogy belevessem magam a funkcionális programozás világába.
Úgy mondhatnám, hogy még az út elején vagyok, mert 1 hónap nem túl sokra ha csak néhány nap tanulgatja az ember, de arra bőven elég, hogy beszámoljak az élményeimről.

Persze jöhet a kérdés minek a tanulni funkcionális paradigmát, ha majdnem mindenhol objektum orientált paradigma a meghatározó. Erre a válasz pedig a fejlődés, ami programozás világában a legfontosabb tulajdonság. Eddigi tapasztalataim alapján 4 nagy mérföld kő van, amivel jó ha találkozik az ember fejlesztőként:

  1. Első Hello World program futtatása.
  2. Valamilyen OOP nyelv elsajátítsa.
  3. Nagyobb projekt fejlesztése vagy/és egy könyvtár megírása.
  4. FP nyelv megtanulása.
Belegondolva ezek a lépések számomra egymás következményei voltak. Ezt a 4. mérföldkövet azért tartom fontosnak, mert kirángat a megszokott közegből és rákényszerít, hogy új dolgokat tanuljak és a megszokott dolgokra is új szemmel nézzek.

Ezelőtt is voltak kísérleteim FP nyelv tanulásával, de valahogy mindig elbuktam vele vagy egyszerűen csak nem érdekelt tovább, de most rávettem magam hogy azért is belevettem magam.
A legfontosabb különbség a korábbi próbálkozásaimhoz képest, hogy most volt időm és egy jó könyvem a témában.

Programozási nyelvnek Haskell-t választottam, mert az egyik legnépszerűbb tisztán funkcionális nyelv és nem is beszélve, hogy a nyelv 1990-ben jelent meg, ami azt jelenti, hogy nagyon érett és stabil. A nyelv egyik erőssége, hogy 20+ év alatt össze tudtak dobni egy 1-2 könyvet. :D

Régebben próbálkoztam a Scala megtanulásával, ami egy hibrid nyelv, ami keresztezi az funkcionális és objektum orientált paradigmát, de ezzel az a gond, hogy FP megtanulása tekintetében egy rossz választás, mivel egy hibrid nyelv és nem kényszeríti ki a funkcionális paradigmát hiszen ott van az objektum orientált része. Nem is beszélve, hogy nem találtam hozzá jó tanuló anyagot.
Kipróbáltam az online Scala kurzust és a hivatalos Scala könyvet is, de egyszerűen túl unalmasak voltak és ezért hagytam is az egészet.

A jó könyv, amit találtam pedig a Learn you Haskell for good, amit már nagyon régóta végig akartam olvasni, de valahogy sosem értem rá, de mostanában végre sikerült végig olvasnom. A könyv nagyszerűsége az egyszerűsége és hogy mókás játékos módon közelíti meg a tanulás kérdését. Na és persze a legjobb benne, hogy online ingyenesen elolvasható.

Haskell közösségben különlegességnek számít ez a könyv, mivel maga a kemény magja a közösségnek nagyon tudományos szemléletű, ami szerintem nagyon szembe tűnő más nyelvekkel szemben. Aki már olvasott posztokat r/haskell subredit-en az tudja, hogy miről beszélek. Ahelyett, hogy blog posztot írnának egy nyelvi érdekességről, helyette inkább egy tudományos papírt publikálnak pdf formában, amiben persze benne van a levezetés, ami megmutatja, hogy miért is működik ez az dolog.



Bennem a könyv olvasása közben 3 érzés tudatosult Haskellel szemben:

  1. Csodálatos, hogy milyen szép és rövid megoldásai lehetnek egy adott problémának.
  2. Értem a dolgot, de akkor is elég furán működik
  3. Nem igaz, hogy 3 sor kódot nem tudok megérteni vagy 2 napja
A könyv első fele elég gyorsan elment, mivel azokat már elég jól ismertem, habár még így is meggyűlt a gondom Haskell típus rendszerének megértésével. A neheze csak ezek után jött, ami nem volt más mint a funktor-ok megértése. Azért nehéz, mert igazából ez az első alkalom, amikor az olvasót megcsapja úgy igazán a matematika szele és nem valami kellemes érzés. :D

A könyvnek nagyon jó a félépítése, mert az alapoktól indul és mindig egymásra épülve adagolja az új tudást. Közben arra is figyel, hogy megértsük, hogy miért kellet a nyelvbe az a bizonyos nyelvi elem. Egy nyelv megértésénél nagyon fontos, hogy megértsük, hogy miért van benne az, ami benne van, mert ellenkező esetben akár rosszul is használhatjuk azt a bizonyos nyelvi elemet. Ennek ellenére is biztos, hogy  fog nehéz pillanatokat átélni az olvasó, mert ez még is csak egy teljesen más paradigma.

Funkcionális paradigmát azért hívják így, mert benne minden egy funkciónak tekinthető, ahogy egy objektum orientált nyelvben pedig minden egy objektumnak tekinthető. Ez akkor eset le nekem amikor láttam, hogy az összeadás is csak egy funkció. Összeadás olyan funkció, aminek 2 bemenete van és a kimenete a két összeadott bementi érték.

Szerintem mégis a legfontosabb fogalom, amit meg kell érteni az a rekurzív funkció fogalma és annak működése.
Azért fontos, mert a nyelveben nincs alapból for vagy while ciklus, hanem helyette rekurzív függvényekkel lehet ezeket megvalósítani és ezért nem is fontos, hogy benne legyenek. Már ebből is látszik, hogy máshogy kell funkcionális nyelvekhez viszonyulni.
Rekurzív függvényeknek a lényege, hogy az adott problémát felbontsunk alap és rekurzív esettre. Ha megértjük azt, hogy hogyan kell ezt csinálni, akkor gyakorlatilag már tudjuk is, hogy mi az a rekurzív funkció.

Másik nagyon fontos dolog pedig, hogy a nyelvben minden egy kifejezés vagyis vissza kell valami adnia. Ez elég érdekes lehet, mivel objektum orientált nyelvekben utasításokat is találhatunk, amiknek nem kell visszaadni semmit és általában  inkább beállítanak valamilyen értéket. Ez azt is jelenti, hogy Haskell-ben nincs void függvény, vagyis olyan függvény, amit semmit sem ad vissza.
Másik következménye, hogy Haskell-ben nehezebb nagy függvényeket írni, mivel nincsenek utasítások és mindenek vissza kell valami értéket adnia.
Ebből következik a következő érdekesség is egyben.

Haskell utolsó általam emlitett érdekessége, hogy meglévő változó értékét nem lehet módosítani vagyis a változók módosíthatatlanok alapból. A változó módosítását ezért csak úgy lehet megoldani, hogy egy új változót kreálunk a régi alapján. Ez a módszer nem új keletű, mivel objektum orientált nyelvek nagy részében ugyanígy működik a String objektum.
Azért elsőre kicsit fura lehet, hogy a kocsi színének a megváltoztatását nem festéssel, hanem egy új autó elkészítésével érjük el.

Elég furcsának tűnhet, hogy módosítás helyett mindenből újat csinálunk, de ennek van egy nagyon jó tulajdonsága, ami a side effect mentesség. A side effect nem más, mint amikor egy globális változónak az értéke hatással van egy általunk megírt metódusra. Emiatt fordulhat elő, hogy két azonos metódus hívás különböző eredményt add vissza ha globális változóra támaszkodik. Haskell-nek pontosan az egyik célja, hogy ilyen ne fordulhasson elő és minden azonos metódus hívás azonos eredményt adjon vissza és ne legyenek benne meglepetések a programozó számára.

Ezekből is látszik, hogy Haskell kikényszeríti a programozóból, hogy a problémákat felbontsa kisebb megvalósítható részekre, függvényeket egyszerűre készítse és  hogy ezek  a megírt függvények kiszámíthatóan viselkedjenek. Ha az olvasó is ráveti magát Haskell tanulásra, akkor észreveheti, hogy a nyelv megváltoztatja azt is, hogy más nyelvekben hogyan programozunk. Az már biztos, hogy az ember ezek után már jobban oda figyel arra, hogy kerülje a side effect-et és lehetőleg egyszerű metódusokat írjon, amiknek csak egyetlen egy feladatuk van.

Funkcionális programozás ugyan azt kényszeríti ki, mint a TDD(Teszt vezérelt fejlesztés), vagyis hogy jobb és egyszerűbben tesztelhető kódot írjunk. Ezért bárkinek csak ajánlani tudom, hogy vesse bele magát bármelyik funkcionális nyelv megtanulásába, mivel segít egy jobb és szebb kód megírásában.

Bevallom őszintén elég nehéz volt megírnom ezt a bejegyzést, mert annyi mindenről lehetne mesélni még így is, hogy alig foglalkoztam Haskellel, de mégis a bejegyzés megírása után kétes érzéseim keletkeztek a nyelvvel kapcsolatban.

Egyfelől a nagyon sokat tanultam magáról a programozásról a nyelv tanulása közben és csodálom, hogy milyen röviden és elegánsan megoldásokat lehet a nyelvvel készíteni.
Viszont a kétely is feléledt bennem, hogy menyire használnám a nyelvet tényleges valós problémák megoldására vagy egyáltalán menyire lehetséges ez egyáltalán. Ami olyan nagyszerűvé teszi a nyelvet az annyira ellene is játszik elterjedése szempontjából.

Számomra Haskell olyan mint a vim. Nagyon sok időt és gyakorlást kell belefektetni, hogy igazán produktív legyen vele az ember, de akik átélték ezt a tűz keresztséget azok mondák, hogy megérte.
Én személy szerint még olyan nyelveket fogok előnybe részesíteni, ami alapból OOP, de már megjelenek bennük a funkcionális paradigmák.(Dart, Java8)
Habár úgy nézz ki, hogy gőz erővel tartunk a hibrid nyelvek világába, szóval nem lesz nehéz dolgom ilyen nyelveket találnom és használnom.

Meglepetésként pedig jöjjön egy pokoli jó szám: