ZuriHac: harjutame funktsionaalset programmeerimist.

Sel aastal juuni alguses toimus Šveitsi väikeses linnas Rapperswilis juba kümnendat korda üritus nimega ZuriHac. Seekord kogunes rohkem kui viissada Haskell'i armastajat, alates algajatest kuni keele asutajateni. Kuigi korraldajad nimetavad seda üritust hackathoniks, ei ole see siiski konverents ega klassikaline hackathon. Selle formaat erineb traditsioonilisest programmeerimisest. Me saime ZuriHaci kohta teada õnneliku juhuse läbi, osalesime selles ning nüüd peame enda kohuseks rääkida sellest ebatavalisest leidmisest!

ZuriHac: harjutame funktsionaalset programmeerimist.

Meist

Selle artikli koostasid kaks 3. kursuse üliõpilast Programmi «Rakendatud matemaatika ja infotehnoloogia» HSE - St. Peterburg: Vasily Alferov ja Elizaveta Vasilenko. Meie mõlema huvi funktsionaalse programmeerimise vastu algas D. N. Moskvin'i loengute seeriast ülikooli teisel aastal. Praegu osaleb Vasily Google Summer of Code'i programmis, mille raames tegeleb algebraliste graafide rakendamisega Haskell'i keeles projekti meeskonna juhendamisel. Alga. Elizaveta rakendas oma omandatud funktsionaalse programmeerimise oskusi kursusetöös, mis on pühendatud anti-unifitseerimise algoritmi rakendamisele ja selle järgnevale kasutamisele tüüpide teoorias.

Sündmuse formaat

Sihtgrupiks on avatud lähtekoodiga projektide omanikud, programmeerijad, kes soovivad nende arenduses osaleda, funktsionaalse programmeerimise uurijad ja lihtsalt Haskelli entusiastid. Sel aastal kogunes ülikoolis HSR Hochschule für Technik Rapperswil arendajaid rohkem kui viiekümnest avatud Haskelli projektist üle kogu maailma, et rääkida oma toodetest ja huvitada uusi inimesi nende arendamisel.

ZuriHac: harjutame funktsionaalset programmeerimist.

Foto Twitterist ZuriHac

Schema on väga lihtne: peate ette kirjutama mõned laused oma projekti kohta ja saatma need korraldajatele, kes panevad teabe teie projekti kohta ürituse lehele. Lisaks on esimesel päeval projektide autoritel igaühel kolmkümmend sekundit, et väga lühidalt lavalt rääkida, millega nad tegelevad ja mida tuleb teha. Seejärel otsivad huvi tundnud inimesed autorid üles ja küsivad põhjalikult ülesannete kohta.

Meil ei ole veel enda avatud projekte, kuid soovime väga panustada juba olemasolevatesse, nii et registreerime end kui tavalised osalejad. Kolme päeva jooksul töötasime koos kahe arendajate grupiga. Selgus, et koodi koos uurimine ja otsekontakt muudab projekti autorite ja panustajate koostöö väga produktiivseks – ZuriHac'il suutsime uutes valdkondades selgusele jõuda ja aidata kahte täiesti erinevat meeskonda, lahendades igas projektis ühe ülesande.

Lisaks väärtuslikule praktikale toimusid ZuriHac'is mitmed loengud ja töötoad. Meelde jäid eelkõige kaks loengut. Esimene neist oli Andrei Mohovilt Newcastle'i ülikoolist, kes rääkis selektiivsetest rakenduslikest funktoritest — tüübid, mis peaksid olema vahepealne klass rakenduslike funktorite ja monaadide vahel. Teisel loengul rääkis üks Haskelli asutajatest, Simon Peyton Jones, kuidas GHC kompilaatori tüüpide järeldamine toimub.

ZuriHac: harjutame funktsionaalset programmeerimist.

Simon Peyton Jonesi loeng. Foto Twitterist ZuriHac

Hakkatooni jooksul toimunud töötoad jagunesid kolme kategooriasse, sõltuvalt osalejate valmistumisastmest. Ülesanded, mis pakuti projektide arendusele liitunud osalejatele, olid samuti märgistatud keerukuse tasemega. Väike, kuid ühtehoidev funktsionaalsete programmeerijate kogukond on rõõmuga valmis uusi liikmeid vastu võtma. Siiski, et André Mohovi ja Simon Peyton Jonesi loengutest paremini aru saada, tuli ülikoolis läbitud funktsionaalse programmeerimise kursus kasuks.

Nii tavaliste osalejate kui ka projektide autorite jaoks on üritusele registreerimine tasuta. Me esitasime osalemiseks taotlused juuni alguses, pärast mida viidi meid suhteliselt kiiresti ootenimekirjast kinnitatud osalejate nimekirja.

Ja nüüd räägime projektidest, milles me oleme osalenud.

Pandoc

Pandoc on universaalne tekstidokumentide konverter, sisuliselt — igast vormingust igasse. Näiteks docx-st pdf-i või Markdown-ist MediaWiki-sse. Selle autor on John MacFarlane — Berkeley Ülikooli filosoofia professor. Üldiselt on Pandoc üsna tuntud, ja mõned meie tuttavad olid üllatunud, kui kuulsid, et Pandoc on kirjutatud Haskellis.

ZuriHac: harjutame funktsionaalset programmeerimist.

Dokumendivormingute loetelu, mida Pandoc toetab. Veebisaidil on ka terve graafik, kuid see pilt ei mahuks artiklisse.

Loomulikult ei toeta Pandoc otse konverteerimist iga formaadi paari vahel. Suure hulga transformatsioonide toetamiseks kasutatakse standardset arhitektuurilist lahendust: kõigepealt tõlgitakse kogu dokument spetsiaalsesse sisemisse vahe vormingusse ning seejärel genereeritakse selle põhjal dokument teises formaadis. Sisemist esitust kutsuvad arendajad "AST", mis tähendab Abstract Syntax Tree ehk abstraktne süntaksipuu. abstraktne süntakspuu. Vaadata sisemist esitust on väga lihtne: selleks tuleb lihtsalt määrata väljundformaadiks "native".

$ cat example.html
<h1>Tere, maailm!</h1>

$ pandoc -f html -t native example.html
[Header 1 ("hello-world",[],[]) [Str "Tere,",Space,Str "Maailm!"]]

Lugejad, kes on vähemalt natuke töötanud Haskelliga, võivad juba selle väikese näite põhjal oletada, et Pandoc on kirjutatud just Haskellis: selle käsu väljund on Pandoci sisemiste struktuuride esitus stringina, 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 loend. Näiteks on kõige ülemisel tasemel ühe elemendiga loend — esimese taseme pealkiri atribuutidega “hello-world”,[],[]. Selle pealkirja sees on peidetud loend stringist “Hello,”, tühi ruum ja stringist “World!”.

Nagu näha, ei erine sisemine esitus oluliselt HTML-ist. See esindab puu struktuuri, kus igas sisemises sõlmes edastatakse teavet nende järglaste vormindamise kohta, ning lehtedes asub dokumendi sisu.

Konkreetse rakenduse tasemel on kogu dokumendi tüüp määratletud järgmiselt:

data Pandoc = Pandoc Meta [Block]

Siin on Block just need sisemised tipud, millest eelnevalt rääkisime, ja Meta on dokumendi metaandmed, nagu pealkiri, loomise kuupäev, autorid — erinevates formaatides on see erinev ning Pandoc püüab sellist teavet võimalikult palju säilitada, kui formaadist formaati tõlkida.

Peaaegu kõik Block tüüpi konstruktorid — näiteks Header või Para (paragраф) — aktsepteerivad argumentidena atribuutide ja madalama taseme tipude loendi — tavaliselt Inline. Näiteks Space või Str on Inline tüüpi konstruktorid, samuti muutub HTML-silt
oma spetsiaalseks Inline'iks. Me ei näe mõtet tuua nende tüüpide täielikku määratlust, kuid tasub märkida, et selle leiate siit siit.

Huvitav, et Pandoc tüüp on monoid. See tähendab, et on mingi tühi dokument ning dokumente saab omavahel liita. Seda on mugav kasutada Reader'ite kirjutamisel — dokumenti saab jagada osadeks omavolilise loogika järgi, igaüks eraldi analüüsida ja seejärel kõik kokku liita üheks dokumendiks. Selle käigus koguneb metaandmed kõigist dokumendi osadest korraga.

Konverteerimisel, näiteks LaTeX'ist HTML'i, teisendab esmalt spetsiaalne moodul, mida nimetatakse LaTeXReader, sisenddokumendi AST-ks, seejärel teine moodul, mida nimetatakse HTMLWriter, muundab AST-i HTML-iks. Sellise arhitektuuri tõttu ei pea kirjutama ruutfunktsiooni konversioone — piisab, kui kirjutada iga uue formaadi jaoks Reader ja Writer, ning kõik võimalike paaride konversioonid hakkavad automaatselt töötama.

Selge, et sellisel arhitektuuril on ka oma puudused, mida tarkvaraarhitektuuri spetsialistid on ammu ette näinud. Olulisem neist on muudatuste tegemise hind süntaktilises puus. Kui muutus on piisavalt tõsine, tuleb muuta koodi kõigis Reader'ites ja Writer'ites. Näiteks on üks Pandoci arendajate ees seisvaid ülesandeid keerukate tabelivormingute toimetamine. Praegu oskab Pandoc ainult kõige lihtsamaid tabeleid, mis sisaldavad päist, veerge ja väärtust igas lahtris. Näiteks HTML-i colspan atribuut jäetakse lihtsalt tähelepanuta. Üks põhjusi sellise käitumise taga on ühtse tabeliesituse skeemi puudumine kõigis või vähemalt paljudes formaatides — seega pole selge, millises vormis tuleks tabeleid hoida sisemises esitluses. Ent isegi pärast konkreetse esituse valimist tuleb muuta kõiki Reader'eid ja Writer'eid, mis toetavad tabelitega töötamist.

Haskell'i keel valiti mitte ainult autori suure armastuse tõttu funktsionaalse programmeerimise vastu. Haskell on tuntud oma laialdaste tekstide töötlemise võimaluste poolest. Üks näide on teek parsec — teek, mis kasutab aktiivselt funktsionaalse programmeerimise kontseptsioone — monoide, monade, apllikatiivseid ja alternatiivseid funktoreid — juhiste kirjutamiseks. Parsec'i täielikku võimu näeb näites HaskellWiki's, kus analüüsitakse lihtsa imperatiivse programmeerimiskeele täielikku parserit. Loomulikult kasutatakse Parsec'i aktiivselt ka Pandocis.

Lühidalt öeldes kasutatakse monade järjestikuseks parsimiseks, kus kõigepealt tuleb üks, seejärel teine. Näiteks sellises näites:

whileParser :: Parser Stmt
whileParser = whiteSpace >> statement

Esiteks tuleb lugeda tühikut, seejärel statement'i — mis on samuti tüüpi Parser Stmt.

Alternatiivset funktoreid kasutatakse tagasikäigu jaoks, kui parsimine ei õnnestunud. Näiteks,

statement :: Parser Stmt
statement = parens statement  sequenceOfStmt

See tähendab, et tuleb kas proovida lugeda statement 'itsekeskis', või järjest proovida lugeda mitut statement'i.

Аппликативные функторы используются в основном как короткие пути для монад. Например, пусть функция tok читает какой-то токен (это реальная функция из LaTeXReader). Посмотрим на такую комбинацию

const <$> tok <*> tok

Она прочитает два токена подряд и вернёт из них первый.

Для всех этих классов в Хаскелле существуют красивые символьные операторы, что делает программирование Reader’ов похожим на ASCII-арт. Только полюбуйтесь на этот замечательный код.

Наши задачи были связаны с LaTeXReader’ом. Задача Василия была в поддержке команд mbox и hbox, полезных при написании пакетов в LaTeX. В ответственности Елизаветы была поддержка команды epigraph, позволяющей оформлять эпиграфы в LaTeX документах.

Hatrace

В UNIX-подобных операционных системах часто реализован системный вызов ptrace. Он полезен при отладке и симуляции окружений программ, позволяя отслеживать системные вызовы, которые делает программа. Например, весьма полезная утилита strace использует внутри себя именно ptrace.

Hatrace on Haskell'i ptrace'i jaoks liidesed pakkuv teek. Tegelikult on ptrace üsna keeruline ning selle vahetu kasutamine on keeruline, eriti funktsionaalsetes keeltes.

Hatrace töötab käivitamisel nagu strace ja aktsepteerib sarnaseid argumente. Erinevus strace'ist seisneb selles, et see on ka teek, mis pakub lihtsamat liidest kui lihtsalt ptrace.

Hatrace'iga on juba avastatud üks tülikas bug Haskell'i kompilaatoris GHC — kui see tapetakse vale hetkel, genereerib see vale objekti faile ja ei kompileeri neid uuesti käivitamisel. Süsteemikutsumise skriptimine võimaldas viga kindlalt korrata ühe jooksu jooksul, kui juhuslikud tapmised tõid vea esile umbes kahe tunni jooksul.

Oleme teeki lisanud süsteemikutsumise liideseid — Elizaveta lisas brk ja Vasili lisas mmap. Meie töö tulemusena on võimalik süsteemikutsumise argumente kergemini ja täpsemalt kasutada, kasutades teeki.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster