Sel aasta juunis toimus Šveitsi väikeses linnas Rapperswilis juba kümnendat korda üritus nimega . Seekord kogunes sinna üle viiesaja Haskell'i sõbra, alates algajatest kuni keele asutajateni. Kuigi korraldajad nimetavad seda üritust hackathoniks, ei ole see siiski klassikalises mõttes konverents või hackathon. Selle formaat erineb traditsioonilistest programmeerijate üritustest. Me saime ZuriHac'ist teada õnneliku juhuse läbi, osalesime selles ja nüüd peame kohuseks rääkida sellest erakordsest leidust!

Meist
Selle artikli koostasid kaks 3. kursuse tudengit NII VSHE - Peterburi rakendatud matemaatika ja informaatika programmist: Vasili Alfjorov ja Elizaveta Vasilenko. Meie kummagi huvi funktsionaalse programmeerimise vastu algas D. N. Moskvin'i loengusari teisel ülikooli aastal. Praegu osaleb Vasili Google Summer of Code programmis, mille raames tegeleb algebraliste graafide realiseerimisega Haskell'i keeles projekti meeskonna juhendamisel. . Elizaveta kasutas funktsionaalse programmeerimise oskusi oma kursusetöös, mis puudutab anti-unifikatsiooni algoritmi realiseerimist, millele järgnes rakendamine tüüpiteoorias.
Ürituse formaat
Sihtgrupiks on avatud lähtekoodiga projektide omanikud, programmeerijad, kes soovivad nende arengus osaleda, funktsionaalse programmeerimise uurijad ja lihtsalt Haskellist inspireeritud inimesed. Sel aastal toimus üritus HSR Hochschule für Technik Rapperswilis, kus kogunes arendajaid üle viiekümne Haskell'i avatud projekti kogu maailmast, et rääkida oma toodetest ja köita uusi inimesi nende arengusse.

Twitterist foto
Schema on väga lihtne: tuleb ette valmistada paar lauset oma projekti kohta ja saata need korraldajatele, kes postitavad teabe teie projekti kohta ürituse lehele. Lisaks on esimesel päeval projektide autoritel kolmkümmend sekundit, et lavalt väga lühidalt rääkida, millega nad tegelevad ja mida on vaja teha. Seejärel otsivad huvitatud inimesed autori üles ja küsivad detailide kohta.
Meil pole praegu oma avatud projekte, kuid tahame väga panustada juba olemasolevatesse, seetõttu registreerisime end tavaliste osalejatena. Kolme päeva jooksul tegutsesime kahe arendajagrupiga. Selgus, et koodi ühisõpe ja otsekontakt muudab projekti autorite ja kaastöötajate koostöö väga produktiivseks – ZuriHacis suutsime aru saada meile uudsetest valdkondadest ja aitasime kahes täiesti erinevas meeskonnas, lahendades igas projektis ülesande.
Lisaks väärtuslikule praktikale kanti ZuriHacis üle mitmeid loenguid ja töötube. Meelde jäid eriti kaks loengut. Esimeses rääkis Andrei Mohov Newcastle'i ülikoolist selektiivsetest aplikaatorfunktsioonidest — tüüpperekonnast, mis peaks jääma vahepeale aplikaatorfunktsioonide ja monaadide vahel. Teises loengus rääkis üks Haskelliga seotud asutajatest, Simon Peyton Jones, sellest, kuidas toimub tüüpide järeldamine GHC kompilaatoris.

Simon Peyton Jonesi loeng. Foto Twitterist
Hakatoni ajal toimunud töötubasid jagati kolme kategooriasse osalejate ettevalmistustaseme põhjal. Osalejatele, kes liitusid projektide arendamisega, pakuti ka ülesandeid, mis olid märgitud keerukuse tasemega. Väheste, kuid ühtse funktsionaalse programmeerimise kogukond võtab rõõmuga uusi liikmeid. Siiski oli vajalik, et oleksime käinud ülikooli funktsionaalse programmeerimise kursusel, et mõista Andrei Mohovi ja Simon Peyton Jonesi loenguid.
N nii tavaliste osalejate kui ka projektide autorite jaoks on üritusele registreerimine tasuta. Esitasime osalemise taotlused juuni alguses, pärast mida viidi meid suhteliselt kiiresti ootejärjekorrast kinnitatud osalejate nimekirja.
Ja nüüd räägime projektidest, mille arenduses me osalesime.
Pandoc
on universaalne tekstidokumendi konverter, tegelikult — mis tahes formaadist mis tahes formaati. Näiteks docx-st pdf-ks või Markdown-ist MediaWiki-ks. Selle autor, John MacFarlane, on Berkeley California ülikooli filosoofia professor. Üldiselt on Pandoc üsna tuntud ja mõned meie tuttavad olid üllatunud, kui teada said, et Pandoc on kirjutatud Haskellis.

Dokumentide formaadid, mida Pandoc toetab. Veebisaidil on ka terve diagramm, kuid see pilt ei mahu artiklisse.
Kahjuks ei toeta Pandoc iga vormingu paari otse konversiooni. Laia valiku teisenduste toetamiseks kasutatakse standardset arhitektuurilahendust: kõigepealt konverteeritakse kogu dokument spetsiaalsesse sisemisse vahepealsesse esitusele ja seejärel genereeritakse selle sisemise esitusviisi põhjal dokument teises formaadis. Arendajad nimetavad sisemist esitust «AST» ehk abstraktne süntaksipuu. . Sisemise esitusviisi vaatamine on väga lihtne: selleks tuleb vaid määrata väljundi formaadiks «native».
$ cat example.html
<h1>Tere, maailm!</h1>
$ pandoc -f html -t native example.html
[Header 1 ("hello-world",[],[]) [Str "Tere,",Space,Str "Maailm!"]]
Lugijad, kes on vähemalt pisut töötanud Haskelliga, võivad selle väikese näite põhjal järeldada, et Pandoc on kirjutatud just Haskellis: selle käsu väljund on Pandoci sisemiste struktuuride esitus stringina, mis on loodud sarnaselt sellele, kuidas seda tavaliselt Haskellis tehakse, näiteks standardraamatukogus.
Nii et siin on näha, et sisemine esitus on rekursiivne struktuur, kus igas sisemises sõlmes on nimekiri. Näiteks ülemisel tasemel on ühe elemendi nimekiri - esimesse järku pealkiri atribuutidega “hello-world”, [], []. Selle pealkirja sees on peidetud nimekiri stringist “Hello,”, tühikust ja stringist “World!”.
Nagu näha, ei erine sisemine esitus palju HTML-ist. See esindab puu, kus iga sisemine sõlm edastab teavet oma järeltulijate vormindamise kohta, ja lehtedes on dokumendi sisu.
Kui minna konkreetse rakenduse tasemele, on kogu dokumendi andmetüüp määratletud järgmiselt:
data Pandoc = Pandoc Meta [Block]Siin on Block just need sisemised tipud, millest ülalpool räägiti, ja Meta on dokumendi metaandmed, nagu pealkiri, loomiskuupäev, autorid - eri formaadid sisaldavad erinevat teavet ja Pandoc püüab seda teavet võimalusel säilitada formaadi vahetamisel.
Peaaegu kõik Block-tüüpi konstructorid — näiteks Header või Para (paragraft) — võtavad argumentidena atribuudid ja madalama taseme tipud — tavaliselt Inline. Näiteks Space või Str on Inline-tüüpi konstructorid, samuti muutub HTML-element oma eriliseks Inline'iks. Me ei näe mõtet tuua välja nende tüüpide täpset määratlust, kuid märgime, et seda saab vaadata siin: .
Huvitav, et Pandoc'i tüüp on monoid. See tähendab, et olemas on mõni tühi dokument ja et dokumente saab omavahel liita. Seda on mugav kasutada Reader'ite kirjutamisel — dokumenti saab jagada osadeks, kasutada esitlust loogikaga, analüüsida iga osa eraldi ja siis kogu kokku panna üheks dokumendiks. Samuti koondatakse metaandmed otse dokumenti kõigist osadest.
Konverteerimisel näiteks LaTeX'ist HTML'isse, kõigepealt spetsiaalne moodul nimega LaTeXReader teisendab sisenddokumendi AST-ks, seejärel teine moodul nimega HTMLWriter teisendab AST'i HTML'iks. Sellise arhitektuuri tõttu ei pea kirjutama kvadratiivset arvu konversioone — piisab iga uue formaadi jaoks kirjutada Reader ja Writer ning kõik võimalikud konversioonipaarid hakkavad automaatselt toetama.
On selge, et sellisel arhitektuuril on ka oma puudused, mida on juba ammu ennustatud tarkvaraarhitektuuri spetsialistide poolt. Kõige olulisem on süntakspuidu muutmise kulu. Kui muudatus on piisavalt tõsine, tuleb muuta koodi kõigis Reader'ites ja Writer'ites. Näiteks üks Pandoc'i arendajate ees seisvaid ülesandeid on keeruliste tabeliformaatide toetamine. Praegu suudab Pandoc luua vaid kõige lihtsamaid tabeleid, millel on pealkiri, veerud ja väärtused igas lahtris. Näiteks HTML'is ignoreeritakse lihtsalt colspan atribuuti. Üks põhjusi sellise käitumise taga on, et puudub ühtne skeem tabelite esitamiseks kõigis või vähemalt paljudes formaatides — seega on ebaselge, millises vormis tuleb tabelid salvestada sisemises esitusviisis. Kuid isegi pärast konkreetse esitlusviisi valimist tuleb muuta absoluutset kõiki Reader'ite ja Writer'ite, mis toetavad tabelitega töötamist.
Haskell'i keel ei valitud mitte ainult autorite suurt armastust funktsionaalse programmeerimise vastu. Haskell on tuntud oma ulatuslike tekstide töötlemise võimaluste poolest. Üks näiteid on kirjasto — könylibibliok, mis kasutab aktiivselt funktsionaalse programmeerimise kontseptsioone — monoidid, monaadid, applicative ja alternatiivsed funtorid — suvaliste parserite kirjutamiseks. Terve Parsec'i vägi on nähtav HaskellWiki's, kus käsitletakse lihtsa imperatiivse programmeerimiskeele täiendavat parserit. Loomulikult kasutatakse Parsec'i aktiivselt ka Pandoc'is.
Lühidalt öeldes kasutatakse monaade järjestikuseks parsimiseks, kus alul käib üks, siis teine. Näiteks sellises näites:
whileParser :: Parser Stmt
whileParser = whiteSpace >> statementEsmalt tuleb lugeda tühik ja siis statement — mis on ka tüüp Parser Stmt.
Alternatiivseid funtoreid kasutatakse tagasiastumiseks, kui parsimine ebaõnnestub. Näiteks,
statement :: Parser Stmt
statement = parens statement sequenceOfStmtSee tähendab, et tuleb kas proovida lugeda statement'i sulgudes või järjest proovida lugeda mitut statement’i.
Applicative funtoreid kasutatakse peamiselt lühikeste teedena monaadide jaoks. Näiteks, oletame, et funktsioon tok loeb mingi token'i (see on reaalselt funktsioon LaTeXReader'ist). Vaatame sellist kombinatsiooni
const <$ tok tokSee loeb kaks token'it järjest ja tagastab neist esimesena.
Kogu selle klassi jaoks on Haskell'is olemas ilusad sümboolsed operaatorid, mis muudavad Reader'ite programmeerimise sarnaseks ASCII-art'iga. Ainult imetlege seda imelise koodi.
Meie ülesanded olid seotud LaTeXReader'iga. Vasja ülesanne oli toetada mbox ja hbox käske, mis on kasulikud LaTeX'i paketide kirjutamisel. Elizabeti vastutusala oli epigraph käsu tugi, mis võimaldab kujundada epigraafe LaTeX dokumentides.
Hatrace
UNIX-laadsetes operatsioonisüsteemides on sageli rakendatud süsteemikutsu ptrace. See on kasulik programmi keskkondade tõrgeteotsingul ja simuleerimisel, võimaldades jälgida süsteemikutsesid, mida programm teeb. Näiteks väga kasulik utiliit strace kasutab enda sees just ptrace'i.
Hatrace on Haskell'i ptrace'i liidese pakkuv teekond. Asi on selles, et ptrace ise on väga keeruline ja selle otsene kasutamine on üsna raske, eriti funktsionaalsetes keeltes.
Hatrace töötab käivitamisel strace'i sarnaselt ja võtab vastu sarnaseid argumente. Selle erinevus strace'ist on see, et see on ka teekond, mis pakub lihtsamat liidest kui lihtsalt ptrace.
Hatrace'i abil on juba tuvastatud üks ebameeldiv bug Haskell'i GHC kompilaatoris — kui see tapetakse vale hetkel, genereerib see vale objekti faile ja ei rekompileeri neid uuesti käivitamisel. Süsteemikõnede skriptimine võimaldas vea järjepidevat korrata ühe käivitamisega, kui juhuslikud tapmised kordasid viga umbes kahe tunni jooksul.
Me oleme liitnud teeki süsteemikõnede liideseid - Elizabeth lisas brk ja Vasili lisas mmap. Meie töö tulemusena on nende süsteemikõnede argumente lihtsam ja täpsem kasutada teegi kasutamisel.
Allikas: habr.com
