ZuriHac: toiminnallisen ohjelmoinnin harjoittelua

Tämän vuoden kesäkuussa pienessä sveitsiläisessä Rapperswilin kaupungissa järjestettiin tapahtuma ns ZuriHac. Tällä kertaa se kokosi yhteen yli viisisataa Haskellin ystävää aloittelijoista kielen perustajiin. Vaikka järjestäjät kutsuvat tätä tapahtumaa hackathoniksi, se ei ole konferenssi tai hackathon perinteisessä mielessä. Sen muoto eroaa perinteisistä ohjelmoijista. Saimme tietää ZuriHacista tuurilla, osallistuimme siihen ja nyt pidämme velvollisuutemme kertoa epätavallisesta löydöstä!

ZuriHac: toiminnallisen ohjelmoinnin harjoittelua

meistä

Tämän artikkelin ovat laatineet kaksi Pietarin kansallisen tutkimusyliopiston kauppakorkeakoulun "Soveltava matematiikka ja informatiikka" -ohjelman 3. vuoden opiskelijaa: Vasily Alferov ja Elizaveta Vasilenko. Intohimo toiminnalliseen ohjelmointiin meillä molemmilla alkoi D. N. Moskvinin luentosarjasta yliopiston 2. vuonna. Vasily osallistuu tällä hetkellä Google Summer of Code -ohjelmaan, jossa hän toteuttaa algebrallisia kuvaajia Haskellissa projektiryhmän ohjauksessa. Levä. Elizaveta sovelsi hankittuja funktionaalisia ohjelmointitaitoja kurssityössä, joka oli omistettu yhtenäistämisen vastaisen algoritmin toteuttamiseen ja myöhempään soveltamiseen tyyppiteoriassa.

Tapahtuman muoto

Kohdeyleisönä ovat avoimen lähdekoodin projektien omistajat, ohjelmoijat, jotka haluavat osallistua niiden kehittämiseen, toiminnallisen ohjelmoinnin tutkijat ja yksinkertaisesti Haskelliin intohimoiset ihmiset. Tänä vuonna kehittäjät yli viidestäkymmenestä avoimen lähdekoodin Haskell-projektista eri puolilta maailmaa kokoontuivat tapahtumapaikkaan - HSR Hochschule für Technik Rapperswiliin - keskustelemaan tuotteistaan ​​ja saamaan tuoreita ihmisiä kiinnostumaan niiden kehityksestä.

ZuriHac: toiminnallisen ohjelmoinnin harjoittelua

Kuva Twitteristä ZuriHac

Kaava on hyvin yksinkertainen: sinun on kirjoitettava etukäteen muutama ehdotus projektistasi ja lähetettävä ne järjestäjille, jotka julkaisevat tiedot projektistasi tapahtumasivulla. Lisäksi ensimmäisenä päivänä hankkeiden tekijöillä on kolmekymmentä sekuntia aikaa kertoa hyvin lyhyesti lavalta, mitä he tekevät ja mitä pitää tehdä. Sitten kiinnostuneet etsivät tekijöitä ja kysyvät yksityiskohtaisesti tehtävistä.

Meillä ei ole vielä omia avoimia projekteja, mutta haluamme todella osallistua olemassa oleviin, joten rekisteröidyimme vakituisiksi osallistujiksi. Kolmen päivän aikana työskentelimme kahden kehittäjäryhmän kanssa. Osoittautuu, että koodin ja live-viestinnän yhteinen tutkimus tekee projektin tekijöiden ja avustajien välisestä vuorovaikutuksesta erittäin tuottavaa - ZuriHacissa pystyimme ymmärtämään meille uusia alueita ja pystyimme auttamaan kahta täysin erilaista tiimiä suorittamalla kummassakin yhden tehtävän. hankkeista.

Arvokkaan harjoittelun lisäksi ZuriHacissa pidettiin myös useita luentoja ja mestarikursseja. Muistamme erityisesti kaksi luentoa. Ensimmäisessä niistä Andrey Mokhov Newcastlen yliopistosta puhui selektiivisistä applikatiivisista funktoreista - tyypeistä, joista pitäisi tulla välimuoto applikatiivisten funktorien ja monadien välillä. Toisella luennolla yksi Haskellin perustajista, Simon Peyton Jones, puhui siitä, kuinka tyyppipäätelmä toimii GHC-kääntäjässä.

ZuriHac: toiminnallisen ohjelmoinnin harjoittelua

Simon Peyton Jonesin luento. Kuva Twitteristä ZuriHac

Hackathonin aikana pidetyt mestarikurssit jaettiin kolmeen kategoriaan osallistujien koulutustason mukaan. Hankkeiden kehittämiseen osallistuneille osallistujille tarjotut tehtävät oli myös merkitty vaikeusasteena. Pieni mutta ystävällinen toimivien ohjelmoijien yhteisö toivottaa uudet tulokkaat iloisesti tervetulleiksi riveihinsä. Andrei Mokhovin ja Simon Peyton Jonesin luentojen ymmärtämiseksi yliopistossa suorittamamme toiminnallisen ohjelmoinnin kurssi oli kuitenkin erittäin hyödyllinen.

Tapahtumaan ilmoittautuminen on ilmaista sekä vakituisille osallistujille että projektin tekijöille. Jätimme osallistumishakemukset kesäkuun alussa, minkä jälkeen meidät siirrettiin nopeasti jonotuslistalta vahvistettujen osallistujien listalle.

Ja nyt puhumme projekteista, joiden kehittämiseen osallistuimme.

Pandoc

Pandoc on yleinen tekstiasiakirjojen muunnin, itse asiassa mistä tahansa muodosta mihin tahansa. Esimerkiksi docx:sta pdf-tiedostoon tai Markdownista MediaWikiin. Sen kirjoittaja John MacFarlane on filosofian professori Kalifornian yliopistossa Berkeleyssä. Yleisesti ottaen Pandoc on melko kuuluisa, ja jotkut ystävämme olivat yllättyneitä kuullessaan, että Pandoc on kirjoitettu Haskellilla.

ZuriHac: toiminnallisen ohjelmoinnin harjoittelua

Luettelo Pandocin tukemista asiakirjamuodoista. Sivustolla on myös koko kaavio, mutta tämä kuva ei sovi artikkeliin.

Pandoc ei tietenkään tarjoa suoraa muuntamista jokaiselle muotoparille. Näin monenlaisten muunnosten tukemiseksi käytetään arkkitehtonista tavanomaista ratkaisua: ensin käännetään koko dokumentti erityiseksi sisäiseksi väliesitykseen, jonka jälkeen tästä sisäisestä esityksestä luodaan dokumentti eri muodossa. Kehittäjät kutsuvat sisäistä esitystä "AST", joka tarkoittaa abstraktia syntaksipuuta tai abstrakti syntaksipuu. Voit katsoa väliesitystä hyvin yksinkertaisesti: sinun tarvitsee vain asettaa tulostusmuodoksi "natiivi"

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

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

Haskellin kanssa ainakin vähän työskennelleet lukijat voivat jo olettaa tästä pienestä esimerkistä, että Pandoc on kirjoitettu Haskellilla: tämän komennon tulos on Pandocin sisäisten rakenteiden merkkijonoesitys, joka on luotu samalla tavalla kuin se yleensä tehdään. Haskellissa, esimerkiksi vakiokirjastossa.

Joten tässä näet, että sisäinen esitys on rekursiivinen rakenne, jonka jokaisessa sisäisessä solmussa on luettelo. Esimerkiksi ylimmällä tasolla on luettelo yhdestä elementistä - ensimmäisen tason otsikosta, jonka attribuutit ovat "hello-world",[],[]. Tämän otsikon sisällä on luettelo merkkijonosta "Hei", jota seuraa välilyönti ja merkkijono "Maailma!".

Kuten näet, sisäinen esitys ei juurikaan eroa HTML:stä. Se on puu, jossa jokainen sisäinen solmu antaa tietoa jälkeläistensä muotoilusta ja lehdet sisältävät dokumentin todellisen sisällön.

Jos siirrymme toteutustasolle, koko asiakirjan tietotyyppi määritellään seuraavasti:

data Pandoc = Pandoc Meta [Block]

Tässä Block on juuri edellä mainitut sisäiset kärjet, ja Meta on metatietoa dokumentista, kuten otsikko, luontipäivä, tekijät - tämä on erilainen eri muodoissa, ja Pandoc yrittää mahdollisuuksien mukaan säilyttää tällaiset tiedot käännettäessä muotoa muoto.

Melkein kaikki Block-tyyppiset konstruktorit - esimerkiksi Otsikko tai Para (kappale) - ottavat argumentteina attribuutteja ja luettelon alemman tason pisteistä - yleensä Inline. Esimerkiksi Space tai Str ovat Inline-tyypin rakentajia, ja HTML-tunniste muuttuu myös omaksi erityiseksi Inline-tekstikseen. Emme näe mitään järkeä tarjota täydellistä määritelmää näistä tyypeistä, mutta huomaa, että se löytyy täältä täällä.

Mielenkiintoista on, että Pandoc-tyyppi on monoidi. Tämä tarkoittaa, että asiakirjassa on jonkinlainen tyhjä asiakirja ja asiakirjat voidaan pinota yhteen. Tätä on kätevä käyttää lukijaa kirjoitettaessa - voit jakaa asiakirjan osiin mielivaltaisella logiikalla, jäsentää jokaisen erikseen ja koota sitten kaiken yhdeksi asiakirjaksi. Tässä tapauksessa metatiedot kerätään dokumentin kaikista osista kerralla.

Kun muunnataan esimerkiksi LaTeX:stä HTML:ksi, ensin erityinen moduuli nimeltä LaTeXReader muuntaa syöteasiakirjan AST:ksi, sitten toinen moduuli nimeltä HTMLWriter muuntaa AST:n HTML:ksi. Tämän arkkitehtuurin ansiosta ei tarvitse kirjoittaa kvadraattista määrää muunnoksia - riittää, että kirjoitat Reader ja Writer jokaiselle uudelle muodolle, ja kaikkia mahdollisia muunnospareja tuetaan automaattisesti.

On selvää, että tällaisella arkkitehtuurilla on myös haittapuolensa, jotka ohjelmistoarkkitehtuurin asiantuntijat ovat jo pitkään ennustaneet. Merkittävin on syntaksipuun muutosten tekemisen kustannukset. Jos muutos on tarpeeksi vakava, sinun on vaihdettava koodi kaikissa lukijoissa ja kirjoittajissa. Esimerkiksi yksi Pandoc-kehittäjien kohtaamista haasteista on monimutkaisten taulukkomuotojen tukeminen. Nyt Pandoc voi luoda vain hyvin yksinkertaisia ​​taulukoita, joissa on otsikko, sarakkeet ja arvo jokaisessa solussa. Esimerkiksi HTML-koodin colspan-attribuutti yksinkertaisesti ohitetaan. Yksi syy tähän käyttäytymiseen on yhtenäisen kaavion puute taulukoiden esittämiseksi kaikissa tai ainakin useissa muodoissa - näin ollen on epäselvää, missä muodossa taulukot tulisi tallentaa sisäiseen esitykseen. Mutta vaikka olet valinnut tietyn näkymän, sinun on vaihdettava ehdottomasti kaikki lukijat ja kirjoittajat, jotka tukevat taulukoiden käyttöä.

Haskell-kieli valittiin paitsi tekijöiden suuren rakkauden vuoksi toiminnalliseen ohjelmointiin. Haskell tunnetaan laajoista tekstinkäsittelyominaisuuksistaan. Yksi esimerkki on kirjasto parsec on kirjasto, joka käyttää aktiivisesti funktionaalisen ohjelmoinnin käsitteitä - monoidit, monadit, aplikatiiviset ja vaihtoehtoiset funktorit - mielivaltaisten jäsentimien kirjoittamiseen. Parsecin koko teho näkyy esimerkki HaskellWikistä, jossa jäsennetään yksinkertaisen pakottavan ohjelmointikielen täydellinen jäsentäjä. Tietysti Parsecia käytetään aktiivisesti myös Pandocissa.

Lyhyesti kuvattuna, monadeja käytetään peräkkäiseen jäsentämiseen, kun yksi asia tulee ensin ja sitten toinen. Esimerkiksi tässä esimerkissä:

whileParser :: Parser Stmt
whileParser = whiteSpace >> statement

Ensin sinun on laskettava välilyönti ja sitten lauseke - jolla on myös Parser Stmt -tyyppi.

Vaihtoehtoisia funktioita käytetään palautukseen, jos jäsentäminen epäonnistuu. Esimerkiksi,

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

Tämä tarkoittaa, että sinun täytyy joko yrittää lukea lause suluissa tai yrittää lukea useita lauseita peräkkäin.

Applikatiivisia funktoreita käytetään ensisijaisesti monadien pikakuvakkeina. Esimerkiksi, anna tok-funktion lukea jotain merkkiä (tämä on todellinen funktio LaTeXReaderista). Katsotaanpa tätä yhdistelmää

const <$> tok <*> tok

Se lukee kaksi merkkiä peräkkäin ja palauttaa ensimmäisen.

Kaikille näille luokille Haskellissa on kauniit symboliset operaattorit, mikä saa Reader-ohjelmoinnin näyttämään ASCII-taiteelta. Ihaile vain tätä upeaa koodia.

Tehtävämme liittyivät LaTeXReaderiin. Vasilyn tehtävänä oli tukea mbox- ja hbox-komentoja, jotka ovat hyödyllisiä LaTeX-pakettien kirjoittamisessa. Elizabeth vastasi epigrafikomennon tukemisesta, jonka avulla voit luoda epigrafeja LaTeX-dokumentteihin.

Hatrace

UNIX-tyyppiset käyttöjärjestelmät käyttävät usein ptrace-järjestelmäkutsua. Se on hyödyllinen ohjelmaympäristöjen virheenkorjauksessa ja simuloinnissa, jolloin voit jäljittää ohjelman tekemiä järjestelmäkutsuja. Esimerkiksi erittäin hyödyllinen strace-apuohjelma käyttää ptracea sisäisesti.

Hatrace on kirjasto, joka tarjoaa käyttöliittymän ptraceen Haskellissa. Tosiasia on, että ptrace itsessään on erittäin hienostunut ja sitä on melko vaikea käyttää suoraan, varsinkin toiminnallisista kielistä.

Hatrace toimii kuten strace käynnistyksen yhteydessä ja hyväksyy samanlaiset argumentit. Se eroaa stracesta siinä, että se on myös kirjasto, joka tarjoaa yksinkertaisemman käyttöliittymän kuin pelkkä ptrace.

Hatracen avulla olemme jo havainneet yhden epämiellyttävän bugin GHC Haskell -kääntäjässä - väärällä hetkellä tapettuna se luo vääriä objektitiedostoja eikä käännä niitä uudelleen käynnistettäessä. Järjestelmäkutsujen komentosarja mahdollisti virheen luotettavan toistamisen yhdellä ajolla, kun taas satunnaiset tappamiset toistivat virheen noin kahdessa tunnissa.

Lisäsimme järjestelmäkutsuliitännät kirjastoon - Elizaveta lisäsi brk:n ja Vasily mmap. Työmme tulosten perusteella on mahdollista yksinkertaisemmin ja tarkemmin käyttää näiden järjestelmäkutsujen argumentteja kirjastoa käytettäessä.

Lähde: will.com

Lisää kommentti