ZuriHac: praktikuojame funkcinį programavimą

Šių metų birželį mažame Šveicarijos miestelyje Rapperswil vyko renginys, vadinamas ZuriHac. Šį kartą jis subūrė daugiau nei penkis šimtus Haskell mylėtojų – nuo ​​pradedančiųjų iki kalbos pradininkų. Nors šį renginį organizatoriai vadina hakatonu, tai nėra konferencija ar hakatonas klasikine prasme. Jo formatas skiriasi nuo tradicinių programuotojų. Apie ZuriHac sužinojome per laimę, jame dalyvavome, o dabar laikome savo pareiga papasakoti apie neįprastą radinį!

ZuriHac: praktikuojame funkcinį programavimą

apie mus

Šį straipsnį parengė du Sankt Peterburgo Nacionalinio mokslo universiteto Aukštosios ekonomikos mokyklos „Taikomosios matematikos ir informatikos“ programos III kurso studentai: Vasilijus Alferovas ir Elizaveta Vasilenko. Aistra funkciniam programavimui mums abiem prasidėjo nuo D. N. Moskvino paskaitų ciklo 3-ame universiteto kurse. Vasilijus šiuo metu dalyvauja „Google Summer of Code“ programoje, kurioje, vadovaujamas projekto komandos, diegia algebrinius grafikus Haskell. Alga. Įgytus funkcinio programavimo įgūdžius Elizaveta pritaikė kursiniuose darbuose, skirtuose antivienifikacijos algoritmo įgyvendinimui, vėliau taikant tipo teorijoje.

Renginio formatas

Tikslinė auditorija – atvirojo kodo projektų savininkai, programuotojai, norintys dalyvauti jų kūrime, funkcinio programavimo tyrinėtojai ir tiesiog aistringi Haskell žmonės. Šiais metais kūrėjai iš daugiau nei penkiasdešimties atvirojo kodo Haskell projektų iš viso pasaulio susirinko į renginio vietą – HSR Hochschule für Technik Rapperswil – pasikalbėti apie savo produktus ir paskatinti naujus žmones domėtis jų plėtra.

ZuriHac: praktikuojame funkcinį programavimą

Nuotrauka iš Twitter ZuriHac

Schema labai paprasta: reikia iš anksto parašyti keletą pasiūlymų apie savo projektą ir nusiųsti juos organizatoriams, kurie informaciją apie Jūsų projektą paskelbs renginio puslapyje. Be to, pirmąją dieną projektų autoriai turi trisdešimt sekundžių labai trumpai nuo scenos pasakyti, ką daro ir ką reikia padaryti. Tada susidomėję žmonės ieško autorių ir detaliai teiraujasi apie užduotis.

Savo atvirų projektų dar neturime, bet labai norime prisidėti prie jau esamų, todėl užsiregistravome nuolatiniais dalyviais. Per tris dienas dirbome su dviem kūrėjų grupėmis. Pasirodo, kad bendras kodo ir tiesioginio bendravimo tyrimas daro projekto autorių ir bendradarbių sąveiką labai produktyvią – „ZuriHac“ galėjome suprasti sritis, kurios mums buvo naujos, ir galėjome padėti dviem visiškai skirtingoms komandoms, kiekvienoje atlikdami po vieną užduotį. projektų.

Be vertingos praktikos, ZuriHac taip pat buvo skaitomos kelios paskaitos ir meistriškumo kursai. Ypač prisimename dvi paskaitas. Pirmajame iš jų Andrejus Mokhovas iš Niukaslio universiteto kalbėjo apie selektyviuosius taikomuosius funktorius – tipų klasę, kuri turėtų tapti tarpine tarp taikomųjų funktorių ir monadų. Kitoje paskaitoje vienas iš Haskell įkūrėjų Simonas Peytonas Jonesas kalbėjo apie tai, kaip tipo išvados veikia GHC kompiliatoriuje.

ZuriHac: praktikuojame funkcinį programavimą

Simono Peytono Džounso paskaita. Nuotrauka iš Twitter ZuriHac

Hakatono metu vykusios meistriškumo pamokos buvo suskirstytos į tris kategorijas, priklausomai nuo dalyvių pasirengimo lygio. Dalyviams, prisijungusiems prie projektų kūrimo, pasiūlytos užduotys taip pat buvo pažymėtos sudėtingumo lygiu. Nedidelė, bet draugiška funkcinių programuotojų bendruomenė mielai priima naujokus į savo gretas. Tačiau norint suprasti Andrejaus Mokhovo ir Simono Peytono Joneso paskaitas, labai pravertė funkcinio programavimo kursas, kurį lankėme universitete.

Registracija į renginį nemokama tiek nuolatiniams dalyviams, tiek projektų autoriams. Dalyvavimo paraiškas pateikėme birželio pradžioje, po to greitai buvome perkelti iš laukiančiųjų sąrašo į patvirtintų dalyvių sąrašą.

O dabar kalbėsime apie projektus, kuriuos kuriant dalyvavome.

„Pandoc“

„Pandoc“ yra universalus tekstinių dokumentų konverteris iš bet kokio formato į bet kurį. Pavyzdžiui, iš docx į pdf arba iš Markdown į MediaWiki. Jos autorius Johnas MacFarlane'as yra Kalifornijos universiteto Berklio filosofijos profesorius. Apskritai, Pandoc yra gana žinomas, ir kai kurie mūsų draugai nustebo, kai sužinojo, kad Pandoc parašyta Haskell.

ZuriHac: praktikuojame funkcinį programavimą

„Pandoc“ palaikomų dokumentų formatų sąrašas. Svetainėje taip pat yra visas grafikas, tačiau ši nuotrauka netelpa į straipsnį.

Žinoma, „Pandoc“ neteikia tiesioginio kiekvienos formatų poros konvertavimo. Norint palaikyti tokią didelę transformacijų įvairovę, naudojamas standartinis architektūrinis sprendimas: pirmiausia visas dokumentas verčiamas į specialų vidinį tarpinį atvaizdavimą, o tada iš šio vidinio atvaizdavimo sugeneruojamas kitokio formato dokumentas. Kūrėjai vidinį atstovavimą vadina „AST“, kuris reiškia abstrakčią sintaksės medį arba abstraktus sintaksės medis. Galite pažvelgti į tarpinį vaizdą labai paprastai: tereikia nustatyti išvesties formatą į „gimtoji“

$ cat example.html
<h1>Hello, World!</h1>

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

Skaitytojai, bent šiek tiek dirbę su Haskell, jau iš šio mažo pavyzdžio gali daryti prielaidą, kad Pandoc parašyta Haskell: šios komandos išvestis yra Pandoc vidinių struktūrų eilutės atvaizdas, sukurtas taip, kaip tai paprastai daroma. Pavyzdžiui, Haskell, standartinėje bibliotekoje.

Taigi, čia matote, kad vidinis vaizdas yra rekursinė struktūra, kurios kiekviename vidiniame mazge yra sąrašas. Pavyzdžiui, viršutiniame lygyje yra vieno elemento sąrašas - pirmojo lygio antraštė su atributais „hello-world“,[],[]. Šioje antraštėje yra paslėptas eilutės „Labas“ sąrašas, po kurio yra tarpas ir eilutė „Pasaulis!“.

Kaip matote, vidinis vaizdas nedaug skiriasi nuo HTML. Tai medis, kuriame kiekvienas vidinis mazgas pateikia tam tikrą informaciją apie savo palikuonių formatavimą, o lapuose yra tikrasis dokumento turinys.

Jei pereisime iki įgyvendinimo lygio, viso dokumento duomenų tipas apibrėžiamas taip:

data Pandoc = Pandoc Meta [Block]

Čia „Block“ yra būtent aukščiau paminėtos vidinės viršūnės, o „Meta“ yra metainformacija apie dokumentą, pvz., pavadinimas, sukūrimo data, autoriai – skirtingiems formatams tai skiriasi, o „Pandoc“ stengiasi, jei įmanoma, išsaugoti tokią informaciją verčiant iš formato į formatu.

Beveik visi bloko tipo konstruktoriai - pavyzdžiui, antraštė arba pastraipa (pastraipa) - kaip argumentus imasi atributų ir žemesnio lygio viršūnių sąrašo - kaip taisyklė įterptoji. Pavyzdžiui, „Space“ arba „Str“ yra „Inline“ tipo konstruktoriai, o HTML žyma taip pat virsta savo specialia „Inline“. Nematome prasmės pateikti išsamų šių tipų apibrėžimą, tačiau atkreipkite dėmesį, kad jį galite rasti čia čia.

Įdomu tai, kad Pandoc tipas yra monoidas. Tai reiškia, kad yra kažkoks tuščias dokumentas ir kad dokumentai gali būti sukrauti. Tai patogu naudoti rašant Skaitytojus – galite suskaidyti dokumentą į dalis, naudodami savavališką logiką, išanalizuoti kiekvieną atskirai ir tada sudėti viską į vieną dokumentą. Tokiu atveju metainformacija bus renkama iš visų dokumento dalių vienu metu.

Konvertuojant, tarkime, iš LaTeX į HTML, pirmiausia specialus modulis, vadinamas LaTeXReader, konvertuoja įvesties dokumentą į AST, tada kitas modulis, vadinamas HTMLWriter, konvertuoja AST į HTML. Dėl šios architektūros nereikia rašyti kvadratinio konversijų skaičiaus – kiekvienam naujam formatui pakanka parašyti Reader ir Writer, ir bus automatiškai palaikomos visos galimos konversijų poros.

Akivaizdu, kad tokia architektūra turi ir trūkumų, kuriuos jau seniai prognozavo programinės įrangos architektūros srities ekspertai. Svarbiausia yra sintaksės medžio pakeitimų kaina. Jei pakeitimas pakankamai rimtas, turėsite pakeisti kodą visuose skaitytojuose ir rašytojuose. Pavyzdžiui, vienas iš iššūkių, su kuriais susiduria Pandoc kūrėjai, yra sudėtingų lentelių formatų palaikymas. Dabar Pandoc gali sukurti tik labai paprastas lenteles su antrašte, stulpeliais ir reikšme kiekviename langelyje. Pavyzdžiui, HTML atributas colspan bus tiesiog ignoruojamas. Viena iš tokio elgesio priežasčių yra vieningos lentelių vaizdavimo visais ar bent jau daugeliu formatų schemos nebuvimas – atitinkamai neaišku, kokia forma lentelės turėtų būti saugomos vidiniame atvaizdavime. Bet net ir pasirinkus konkretų rodinį, reikės pakeisti absoliučiai visus skaitytuvus ir rašytojus, kurie palaiko darbą su lentelėmis.

Haskell kalba pasirinkta ne tik dėl didelės autorių meilės funkciniam programavimui. Haskell yra žinomas dėl savo plačių teksto apdorojimo galimybių. Vienas iš pavyzdžių yra biblioteka parsek yra biblioteka, kuri aktyviai naudoja funkcinio programavimo sąvokas – monoidus, monadus, taikomuosius ir alternatyvius funkcijoms – rašyti savavališkus analizatorius. Visą Parsec galią galima pamatyti pavyzdys iš HaskellWiki, kur analizuojamas visas paprastos privalomosios programavimo kalbos analizatorius. Žinoma, „Parsec“ taip pat aktyviai naudojamas „Pandoc“.

Trumpai apibūdinta, monados naudojamos nuosekliam analizavimui, kai pirmiausia atsiranda vienas dalykas, o paskui kitas. Pavyzdžiui, šiame pavyzdyje:

whileParser :: Parser Stmt
whileParser = whiteSpace >> statement

Pirmiausia reikia suskaičiuoti tarpą, o tada teiginį – kuris taip pat turi Parser Stmt tipą.

Jei analizė nepavyksta, atšaukimui naudojami alternatyvūs funkcininkai. Pavyzdžiui,

statement :: Parser Stmt
statement = parens statement <|> sequenceOfStmt

Reiškia, arba reikia pabandyti perskaityti teiginį skliausteliuose, arba pabandyti perskaityti kelis teiginius iš eilės.

Taikomieji funktoriai pirmiausia naudojami kaip monadų nuorodos. Pavyzdžiui, leiskite tok funkcijai nuskaityti tam tikrą žetoną (tai tikra LaTeXReader funkcija). Pažvelkime į šį derinį

const <$> tok <*> tok

Jis nuskaitys du žetonus iš eilės ir grąžins pirmąjį.

Visoms šioms klasėms Haskell turi gražius simbolinius operatorius, todėl Reader programavimas atrodo kaip ASCII menas. Tiesiog žavėkitės šiuo nuostabiu kodu.

Mūsų užduotys buvo susijusios su LaTeXReader. Vasilijaus užduotis buvo palaikyti mbox ir hbox komandas, naudingas rašant paketus LaTeX. Elizabeth buvo atsakinga už epigrafo komandos palaikymą, leidžiančią kurti epigrafus LaTeX dokumentuose.

Hatrace

Į UNIX panašios operacinės sistemos dažnai įgyvendina ptrace sistemos iškvietimą. Tai naudinga derinant ir imituojant programų aplinką, leidžiančią atsekti programos atliekamus sistemos iškvietimus. Pavyzdžiui, labai naudinga „strace“ programa viduje naudoja ptrace.

Hatrace yra biblioteka, kuri suteikia sąsają ptrace programoje Haskell. Faktas yra tas, kad pats ptrace yra labai sudėtingas ir gana sunku jį naudoti tiesiogiai, ypač iš funkcinių kalbų.

„Hatrace“ paleidžiama kaip „strace“ ir priima panašius argumentus. Ji skiriasi nuo strace tuo, kad tai taip pat yra biblioteka, kuri suteikia paprastesnę sąsają nei tik ptrace.

Hatrace pagalba jau užfiksavome vieną nemalonią GHC Haskell kompiliatoriaus klaidą – užmuštas netinkamu momentu, jis generuoja neteisingus objektų failus ir paleidus iš naujo jų nekompiliuoja. Scenarijų sudarymas pagal sistemos iškvietimus leido patikimai atkurti klaidą per vieną paleidimą, o atsitiktiniai nužudymai klaidą atkūrė maždaug per dvi valandas.

Į biblioteką įtraukėme sistemos skambučių sąsajas – Elizaveta pridėjo brk, o Vasilijus – mmap. Remiantis mūsų darbo rezultatais, naudojantis biblioteka galima paprasčiau ir tiksliau panaudoti šių sistemos iškvietimų argumentus.

Šaltinis: www.habr.com

Добавить комментарий