Back to site
Since 2004, our University project has become the Internet's most widespread web hosting directory. Here we like to talk a lot about web servers, web development, networking and security services. It is, after all, our expertise. To make things better we've launched this science section with the free access to educational resources and important scientific material translated to different languages.

Zašto više volim Scheme od Haskell-a


        Pre nego što naoštrite svoje tastature i krenete da bacate kiselinu na mene kao kaznu za naslov, dopustite mi da istaknem da nisam napisao ovaj tekst da bih blatio Haskell (ozbiljan sam), zapravo ja ga volim. Haskell me je upoznao sa algebarskim tipovima podataka, specifičnim jezicima domain-a, uparivanjem modela (pattern matching), kao i sa mnogim drugim konstrukcijama programiranja koje se čine kao izgubljena ruka ili noga u drugim jezicima, ali Haskell se uporno opire svakom mom pokušaju da u njemu napišem koristan kod. Scheme-u nedostaju skoro sve Haskell-ove inovacije u korist minimalističke fleksibilnosti, ali on meša praktičnost i funkcionalnu lepotu, što ga čini Haskell-om za ljudska bića.

        Prošlog vikenda, počeo sam da pišem prototip za aplikaciju iskopavanja podataka (data mining). Počeo sam u Haskell-u; on je brz , elegantan, i jednom kada ste iskoristili Parsec modul, teško je zamisliti pisanje parser-a bez njega. Moj prvi korak bio je da izvučem podatke iz jednostavnog XML fajla. Ovo je jednostavan zadatak sa ruby: download-ujete xml parser, pročitate uputstvo i, možda deset minuta kasnije, imate podatke u memoriji, spremne za rad. Posle frustrirajućih sat vremena sa mojom Haskell verzijom, i dalje sam se mučio da shvatim monadni API potreban za rad sa XML parser-om i odustao sam. Ovo je oduvek bio moj problem sa Haskell-om; prelep je, ali je beskoristan za hakovanje (hacking). Scheme nema Haskell-ovu bogatu standardnu biblioteku, niti efikasan prevodilac (compiler), ali on poseduje Haskell-ovu uglađenost i, što je još važnije, kodiranje u njemu predstavlja radost.

        Koliko god da je Haskell-ova čisto funkcionalna osnova elegantna i privlačna, ona zabranjuje jednostavne, ali presudne, nečiste zadatke kao što su pisanje u fajlovima i komuniciranje preko mreža. Monad-i - Haskell-ov odgovor na ovaj nedostatak - su malo više od nestabilne štake; oni omogućavaju onima koji kodiraju da napišu uspešan software u Haskell-u, ali to nije ni intuitivno ni lako.

        Ukoliko želite da ispravite grešku (debug) funkcije u Haskell-u, ne možete da ubacite printf da prekontrolišete njen unutrašnji rad, osim ukoliko ta funkcija nije baš na IO Monad. Ovo je ozbiljna prepreka Haskell-ovoj mogućnosti korišćenja o kojoj se retko diskutuje, zato što možete popraviti samo ono što vidite, pa, ako ne možete da prekontrolišete unutar funkcije, ne možete je ni popraviti. Sa druge strane, Scheme žrtvuje malo čistoće da biste mogli da tresnete (display) u svoj kod i da saznate šta se dešava. Siguran sam da se Haskell-ov programer/progamerka upravo sada drže za glavu dok se pitaju kako sam mogao da propustim nedoličnost ovakvog ponašanja u lenjom, dobro optimizovanom jeziku sa debugger-om. Oni bi bili u pravu, ali nemogućnost ispravljanja grešaka na ovaj način je cena koju nisam spreman da platim zarad Haskell-ove akademske čistoće.

        Drugi problem sa Monad-ima je vezan za njihovu veliku snagu - oni su sinonimni sa Domain Specific Languages. Glavni slogan (mission statement) za specifične jezike domain-a je predivan - ne pišite složeni program da rešite svoj problem, pišite jednostavan program na programskom jeziku koji ste dizajnirali samo za taj zadatak. Već sam pomenuo najbolje korišćenje DSL/Monad-a - Haskell-ov parsec modul. Sa Parsec-om, Haskell-ova funkcija da raščlanjuje (to parse) fajl je identična Backus Naur Form opisu raščlanjujuće gramatike (parse grammar) - može li to biti jasnije? Kažu da je imitacija najveći oblik priznanja, i svaka funkcija raščlanjivanja koju sam napisao izvan Haskell-a od upoznavanja Parsec-a je samo obična fotokopija Parsec-a u izabranom jeziku. Uspeh Parsec-a i njemu sličnih, ispunio je Hackage (Haskell-ovo skladište modula) stotinama DSL-ova koji pokrivaju svaki zadatak koji vam padne na pamet.

        Da, bukvalno stotinama. Stotinama malih programskih jezika, jedan za BNF raščlanjivanje, jedan za raščlanjivanje xml-a, jedan za kreiranje PDF-ova, svaki savršeno odgovarajući za svoj zadatak. Svaki je različit i svaki ima svoju sopstvenu krivu učenja. Zamislite običan zadatak kao što je raščlanjivanje XML fajla, njegovo mutiranje u skladu sa nekim JSON koji ste skinuli sa web API-ja i zatim pisanje u PDF. U Ruby-ju ili sličnom jeziku orijentisanom na objekat, očekujete da nađete tri API-ja/dragulja, sve sa sličnom sintaksom orijentisanom na objekat, ali kad bi tri Haskell DSL-a dizajnirana za tri različita zadatka delila sintaksu, to bi značilo da su njihovi autori propustili da ih optimizuju za te zadatke, dakle umesto pet minuta sa API dokumentacijom, imate sate DSL tutorijala pred sobom, pre nego što budete mogli da počnete sa radom. Ova tanana razlika je ono što stavlja Haskell na akademsku stranu i stvara podele. Sa Haskell-om fokus je na jeziku, a ne na problemima koje rešavate pomoću jezika.

        Scheme je jednostavan sa namerom, zapravo mislim da kompetentnom programeru ne bi trebalo više od sat vremena da se upozna sa sintaksom, ali on je jednostavan na način koji ga čini fleksibilnim, a ne sputanim. Uzmite na primer metaprogramiranje obrazaca (template). Iako je stvaranje obrazaca (templating) manje korisno u dinamičnim jezicima, Lisp hakeri su godinama imali pristup template-ima kroz makro sistem, ali Haskell, kao i C++, zahteva jezičku ekstenziju da bi ih omogućio.

        Istorijska uloga Scheme-a kao jezika inovacije je igrala veliku ulogu zašto sam ga izabrao za moje iPad razvojno okruženje Lisping . Pri reinvenciji kodiranja na ekranima na dodir (touchscreens), dozvoljavanjem korisniku da menja drvo sintakse (syntax tree), izgledalo je odgovarajuće da se izabere jezik povezan sa tako puno novih tehnologija tokom svoje istorije.

        Bilo bi nepošteno ne istaći da, uprkos svoje korisnosti hakerima, Scheme deli Haskell-ovu neprikladnost za produkcioni kod. Razlika je u tome što je Scheme ograničen svojom minimalističnom standardnom bibliotekom, a ne nedostatkom u jeziku, i, da bi ste završili posao, možete ga “unaprediti” (upgrade) do sintaksički sličnog, ali u višoj kategoriji, rođaka kao što je Common Lisp, ili Clojure.

        Ne kažem da je Scheme bolji od Haskell-a. Programski jezici su alatke i uvek bi trebalo da izaberete najbolju alatku za posao, ali ja mislim da njegova ograničenost čini Haskell lošim izborom za hakere. Naučite sve što možete iz njegove funkcionalne lepote, i vodite kampanju da se njegove najbolje karakteristike dodaju vašem izabranom jeziku, ali to je sve što će Haskell ikada biti za mene, platonski ideal programskog jezika, koji osvetljava put u budućnost, ali je sam po sebi nemoguć za korišćenje.

        EDIT: hvala onima koji su istakli postojanje Debug.Trace, ali ja sam pokušao da iskažem svoju frustraciju činjenicom da nisam mogao da privremeno ubacim mali ‘nečisti’ kod da prodrma ponašanje i pomogne pri otklanjanju grešaka.

        Postavljeno 09 Apr 2012




Published (Last edited): 11-12-2012 , source: http://slidetocode.com/2012/04/09/why-i-prefer-scheme-to-haskell/