I juni i år, i den lille sveitsiske byen Rapperswil, en begivenhet kalt
om oss
Denne artikkelen ble utarbeidet av to tredjeårsstudenter på programmet "Anvendt matematikk og informatikk" ved National Research University Higher School of Economics - St. Petersburg: Vasily Alferov og Elizaveta Vasilenko. Lidenskapen for funksjonell programmering for oss begge begynte med en serie forelesninger av D. N. Moskvin på 3. året på universitetet. Vasily deltar for tiden i Google Summer of Code-programmet, der han implementerer algebraiske grafer i Haskell under veiledning av prosjektteamet
Eventformat
Målgruppen er eiere av åpen kildekode-prosjekter, programmerere som ønsker å delta i deres utvikling, funksjonelle programmeringsforskere og folk som rett og slett brenner for Haskell. I år har utviklere fra mer enn femti åpen kildekode Haskell-prosjekter fra hele verden samlet seg på stedet – HSR Hochschule für Technik Rapperswil – for å snakke om produktene deres og få ferske folk interessert i utviklingen deres.
Bilde fra Twitter
Opplegget er veldig enkelt: du må skrive noen forslag om prosjektet ditt på forhånd og sende dem til arrangørene, som vil legge ut informasjon om prosjektet ditt på arrangementssiden. I tillegg har forfatterne av prosjektene den første dagen tretti sekunder på seg til veldig kort å fortelle fra scenen hva de gjør og hva som må gjøres. Så leter interesserte etter forfatterne og spør i detalj om oppgavene.
Vi har ikke egne åpne prosjekter ennå, men vi ønsker virkelig å bidra til eksisterende, så vi registrerte oss som faste deltakere. I løpet av tre dager jobbet vi med to grupper av utviklere. Det viser seg at felles studie av kode og live kommunikasjon gjør samspillet mellom prosjektforfattere og bidragsytere svært produktivt - på ZuriHac var vi i stand til å forstå områder som var nye for oss og var i stand til å hjelpe to helt forskjellige team, og fullførte en oppgave i hver av prosjektene.
I tillegg til verdifull praksis ble det også gitt flere forelesninger og masterklasser på ZuriHac. Vi husker spesielt to forelesninger. Ved den første av dem snakket Andrey Mokhov fra University of Newcastle om selektive applikative funksjoner – en klasse av typer som skulle bli mellomliggende mellom applikative funksjoner og monader. I et annet foredrag snakket en av grunnleggerne av Haskell, Simon Peyton Jones, om hvordan typeinferens fungerer i GHC-kompilatoren.
Foredrag av Simon Peyton Jones. Bilde fra Twitter
Mesterklassene som ble holdt under hackathonet ble delt inn i tre kategorier avhengig av treningsnivået til deltakerne. Oppgavene som ble tilbudt deltakere som ble med i utviklingen av prosjekter var også merket med en vanskelighetsgrad. Det lille, men vennlige fellesskapet av funksjonelle programmerere ønsker gladelig nykommere velkommen i sine rekker. For å forstå forelesningene til Andrei Mokhov og Simon Peyton Jones var imidlertid kurset i funksjonell programmering vi tok på universitetet svært nyttig.
Påmelding til arrangementet er gratis for både vanlige deltakere og prosjektforfattere. Vi sendte inn søknader om deltakelse i begynnelsen av juni, deretter ble vi raskt overført fra venteliste til listen over bekreftede deltakere.
Og nå skal vi snakke om prosjektene i utviklingen som vi deltok i.
pandoc
Liste over dokumentformater som støttes av Pandoc. Det er også en hel graf på siden, men dette bildet passer ikke inn i artikkelen.
Selvfølgelig gir ikke Pandoc direkte konvertering for hvert par formater. For å støtte et så bredt utvalg av transformasjoner, brukes en standard arkitektonisk løsning: først blir hele dokumentet oversatt til en spesiell intern mellomrepresentasjon, og deretter genereres et dokument i et annet format fra denne interne representasjonen. Utviklerne kaller den interne representasjonen "AST", som står for abstrakt syntakstre, eller
$ cat example.html
<h1>Hello, World!</h1>
$ pandoc -f html -t native example.html
[Header 1 ("hello-world",[],[]) [Str "Hello,",Space,Str "World!"]]
Lesere som i det minste har jobbet litt med Haskell, kan allerede fra dette lille eksemplet anta at Pandoc er skrevet i Haskell: utdataene fra denne kommandoen er en strengrepresentasjon av de interne strukturene til Pandoc, skapt i likhet med hvordan det vanligvis gjøres. i Haskell, for eksempel i standardbiblioteket.
Så her kan du se at den interne representasjonen er en rekursiv struktur, i hver interne node som det er en liste over. For eksempel, på toppnivået er det en liste over ett element - overskriften på første nivå med attributtene "hello-world",[],[]. Skjult inne i denne overskriften er en liste over strengen "Hallo", etterfulgt av et mellomrom og strengen "Verden!".
Som du kan se, er den interne representasjonen ikke mye forskjellig fra HTML. Det er et tre der hver intern node gir litt informasjon om formateringen av dens etterkommere, og bladene inneholder det faktiske innholdet i dokumentet.
Går vi ned til implementeringsnivået, er datatypen for hele dokumentet definert slik:
data Pandoc = Pandoc Meta [Block]
Her er Block nettopp de interne toppunktene nevnt ovenfor, og Meta er metainformasjon om dokumentet, som tittel, opprettelsesdato, forfattere – dette er forskjellig for ulike formater, og Pandoc prøver om mulig å bevare slik informasjon når man oversetter fra format til format.
Nesten alle konstruktører av Block-typen - for eksempel Header eller Paragraph (avsnitt) - tar attributter og en liste over toppunkter på lavere nivå som argumenter - Inline, som regel. For eksempel er Space eller Str konstruktører av Inline-typen, og HTML-taggen blir også til sin egen spesielle Inline. Vi ser ingen vits i å gi en fullstendig definisjon av disse typene, men merk at den finnes her
Interessant nok er typen Pandoc en monoid. Dette betyr at det er et slags tomt dokument, og at dokumenter kan stables sammen. Dette er praktisk å bruke når du skriver lesere - du kan dele et dokument i deler ved å bruke vilkårlig logikk, analysere hver enkelt separat og deretter sette alt sammen til ett dokument. I dette tilfellet vil metainformasjon samles inn fra alle deler av dokumentet samtidig.
Når du konverterer for eksempel fra LaTeX til HTML, konverterer først en spesiell modul kalt LaTeXReader inndatadokumentet til AST, deretter konverterer en annen modul kalt HTMLWriter AST til HTML. Takket være denne arkitekturen er det ikke nødvendig å skrive et kvadratisk antall konverteringer - det er nok å skrive Reader og Writer for hvert nytt format, og alle mulige par med konverteringer støttes automatisk.
Det er klart at en slik arkitektur også har sine ulemper, lenge spådd av eksperter innen programvarearkitektur. Det viktigste er kostnadene ved å gjøre endringer i syntakstreet. Hvis endringen er alvorlig nok, må du endre koden i alle lesere og skribenter. For eksempel er en av utfordringene Pandoc-utviklere står overfor å støtte komplekse tabellformater. Nå kan Pandoc bare lage veldig enkle tabeller, med en overskrift, kolonner og en verdi i hver celle. For eksempel vil colspan-attributtet i HTML ganske enkelt bli ignorert. En av grunnene til denne oppførselen er mangelen på et enhetlig opplegg for å representere tabeller i alle eller i det minste mange formater - følgelig er det uklart i hvilken form tabellene skal lagres i den interne representasjonen. Men selv etter å ha valgt en bestemt visning, må du endre absolutt alle lesere og forfattere som støtter arbeid med tabeller.
Haskell-språket ble valgt ikke bare på grunn av forfatternes store kjærlighet til funksjonell programmering. Haskell er kjent for sine omfattende tekstbehandlingsmuligheter. Et eksempel er biblioteket
Kort beskrevet, monader brukes til sekvensiell parsing, når en ting kommer først, og deretter en annen. For eksempel, i dette eksemplet:
whileParser :: Parser Stmt
whileParser = whiteSpace >> statement
Først må du telle mellomrommet, og deretter setningen - som også har typen Parser Stmt.
Alternative funksjoner brukes til å rulle tilbake hvis parsing mislykkes. For eksempel,
statement :: Parser Stmt
statement = parens statement <|> sequenceOfStmt
Betyr at du enten må prøve å lese setningen i parentes, eller prøve å lese flere setninger sekvensielt.
Applikative funksjoner brukes først og fremst som snarveier for monader. La for eksempel tok-funksjonen lese noen token (dette er en ekte funksjon fra LaTeXReader). La oss se på denne kombinasjonen
const <$> tok <*> tok
Den vil lese to tokens på rad og returnere den første.
For alle disse timene har Haskell vakre symbolske operatorer, som får Reader-programmering til å se ut som ASCII-kunst. Bare beundre denne fantastiske koden.
Våre oppgaver var relatert til LaTeXReader. Vasilys oppgave var å støtte mbox- og hbox-kommandoene, nyttige for å skrive pakker i LaTeX. Elizabeth var ansvarlig for å støtte epigraf-kommandoen, som lar deg lage epigrafer i LaTeX-dokumenter.
Hatrace
UNIX-lignende operativsystemer implementerer ofte ptrace-systemkallet. Det er nyttig i feilsøking og simulering av programmiljøer, slik at du kan spore systemanropene som programmet gjør. For eksempel bruker det svært nyttige strace-verktøyet ptrace internt.
Hatrace er et bibliotek som gir et grensesnitt for ptrace i Haskell. Faktum er at ptrace i seg selv er veldig sofistikert og det er ganske vanskelig å bruke det direkte, spesielt fra funksjonelle språk.
Hatrace kjører som strace ved oppstart og aksepterer lignende argumenter. Det skiller seg fra strace ved at det også er et bibliotek som gir et enklere grensesnitt enn bare ptrace.
Ved hjelp av hatrace har vi allerede fanget en ubehagelig feil i GHC Haskell-kompilatoren - blir drept i feil øyeblikk, genererer den feil objektfiler og kompilerer dem ikke på nytt når den startes på nytt. Skripting ved systemkall gjorde det mulig å reprodusere feilen på en pålitelig måte i én kjøring, mens tilfeldige drep reproduserte feilen på omtrent to timer.
Vi la til systemanropsgrensesnitt til biblioteket - Elizaveta la til brk, og Vasily la til mmap. Basert på resultatene av arbeidet vårt er det mulig å enklere og mer nøyaktig bruke argumentene til disse systemanropene når du bruker biblioteket.
Kilde: www.habr.com