Në qershor të këtij viti, në një qytet të vogël zviceran, Rapperswil, u mbajt për herë të dhjetë një ngjarje e quajtur . Këtë herë, mbi pesëqind dashamirës të Haskellit, nga fillestarë deri te baballarët e gjuhës, u mblodhën. Megjithëse organizatorët e quajnë këtë ngjarje një hackathon, ajo megjithatë nuk është një konferencë apo hackathon në kuptimin tradicional. Formati i saj është ndryshe nga programet e zakonshme për programuesit. Ne e mësuam për ZuriHac për një rast të shkëlqyer, morëm pjesë në të dhe tani e konsiderojmë detyrë tonë të tregojmë për këtë zbulim të veçantë!

Rreth nesh
Ky artikull Ă«shtĂ« pĂ«rgatitur nga dy studentĂ« tĂ« vitit tĂ« tretĂ« tĂ« programit "Matematika e aplikuar dhe Informatika" nĂ« HSE â ShĂ«n Petersburg: Vasili Alfjov dhe Jelizaveta Vasilenko. TĂ« dy filluam pasionin tonĂ« pĂ«r programimin funksional nga njĂ« cikĂ«l leksionesh tĂ« D. N. Moskvinit nĂ« vitin e dytĂ« tĂ« universitetit. Aktualisht, Vasili po merr pjesĂ« nĂ« programin Google Summer of Code, nĂ« kuadĂ«r tĂ« cilit po punon nĂ« implementimin e grafikĂ«ve algjebrikĂ« nĂ« Haskell nĂ«n udhĂ«heqjen e ekipit tĂ« projektit . Jelizaveta e aplikoi njohuritĂ« e fituara nĂ« programimin funksional nĂ« punimin e saj tĂ« kursit, i kushtuar realizimit tĂ« algoritmit tĂ« anti-unifikimit me aplikim tĂ« mĂ«tejshĂ«m nĂ« teorinĂ« e tipeve.
Formati i ngjarjes
AudiencĂ« e synuar pĂ«rfshin pronarĂ«t e projekteve me burim tĂ« hapur, programuesit qĂ« duan tĂ« kontribuojnĂ« nĂ« zhvillimin e tyre, studiuesit e programimit funksional dhe thjesht entuziastĂ«t e Haskellit. KĂ«tĂ« vit, nĂ« vendin e mbajtjes â universiteti HSR Hochschule fĂŒr Technik Rapperswil â u mblodhĂ«n zhvillues nga mĂ« shumĂ« se pesĂ«dhjetĂ« projekte tĂ« hapura nĂ« Haskell nga e gjithĂ« bota, pĂ«r tĂ« treguar pĂ«r produktet e tyre dhe pĂ«r tĂ« tĂ«rhequr njerĂ«z tĂ« rinj nĂ« zhvillimin e tyre.

Foto nga Twitter
Schemi është shumë e thjeshtë: duhet të shkruani paraprakisht disa fjali për projektin tuaj dhe t'ia dërgoni organizatorëve, të cilët do ta publikojnë informacionin për projektin tuaj në faqen e ngjarjes. Për më tepër, në ditën e parë autorët e projekteve kanë tridhjetë sekonda për të treguar shumë shkurtimisht nga skena se çfarë po bëjnë dhe çfarë duhet të bëhet. Më pas, njerëzit e interesuar e gjejnë autorët dhe pyesin për detajet.
Ne ende nuk kemi projekte tĂ« hapura tĂ« veta, por shumĂ« dĂ«shirojmĂ« tĂ« kontribuojmĂ« nĂ« ato ekzistuese, kĂ«shtu qĂ« u regjistruam si pjesĂ«marrĂ«s tĂ« zakonshĂ«m. GjatĂ« tre ditĂ«ve punuam me dy grupe zhvilluesish. Doli se studimi i sĂ« bashku nĂ« kod dhe komunikimi tĂ« gjallĂ« e bĂ«n bashkĂ«punimin midis autorĂ«ve tĂ« projektit dhe kontributorĂ«ve shumĂ« produktiv â nĂ« ZuriHac arritĂ«m tĂ« kuptojmĂ« fusha tĂ« reja pĂ«r ne dhe mundĂ«m tĂ« ndihmojmĂ« dy ekipe krejt tĂ« ndryshme, duke mbyllur njĂ« detyrĂ« nĂ« secilin projekt.
Përveç praktikës së çmuar, në ZuriHac gjithashtu u mbajtën disa leksione dhe workshop-e. Dy leksione na mbetën veçanërisht në mendje. Në leksionin e parë, Andrey Mokhov nga universiteti i Newcastle-t foli për funksionet aplikative selektive - një klasë tipesh që duhet të bëhet ndërmjetëse midis funksioneve aplikative dhe monadave. Në leksionin tjetër, një nga bashkuesit e Haskellit, Simon Peyton Jones, foli për mënyrën si funksionon nxjerrja e tipeve në kompilatorin GHC.

Leksioni i Simon Peyton Jones. Foto nga Twitter
Workshop-et që u mbajtën gjatë hackathon-it ishin të ndara në tri kategori në varësi të nivelit të përgatitjes së pjesëmarrësve. Detyrat që iu ofruan pjesëmarrësve që u bashkuan në zhvillimin e projekteve gjithashtu kishin shenjat e nivelit të vështirësisë. Një komunitet i vogël, por i bashkuar i programuesve funksionalë pranon me kënaqësi të rinjtë në radhët e tij. Megjithatë, për të kuptuar leksionet e Andrey Mokhov dhe Simon Peyton Jones, na u deshën shumë njohuritë e marra nga kursi i programimit funksional në universitet.
Si për pjesëmarrësit e zakonshëm ashtu edhe për autorët e projekteve, regjistrimi për ngjarjen është falas. Ne dërguam aplikimet tona për pjesëmarrje në fillim të qershorit, pas së cilës u kaluam shumë shpejt nga lista e pritjes në listën e pjesëmarrësve të konfirmuar.
Tani do të tregojmë për projektet ku morëm pjesë.
Pandoc
Ă«shtĂ« njĂ« konvertues universale i dokumenteve tekstuale, nĂ« thelb â nga çdo format nĂ« çdo format. PĂ«r shembull, nga docx nĂ« pdf, ose nga Markdown nĂ« MediaWiki. Autori i tij, John MacFarlane, Ă«shtĂ« profesor filozofie nĂ« Universitetin e KalifornisĂ« nĂ« Berkeley. NĂ« tĂ« vĂ«rtetĂ«, Pandoc Ă«shtĂ« mjaft i njohur, dhe disa nga miqtĂ« tanĂ« u habitĂ«n kur mĂ«suan qĂ« Pandoc Ă«shtĂ« shkruar nĂ« Haskell.

Lista e formateve të dokumenteve të mbështetura nga Pandoc. Në faqen e internetit ka gjithashtu një graf të plotë, por kjo imazh nuk përfshihet në artikull.
Natyrisht, në Pandoc nuk është realizuar konvertimi direkt për çdo çift formatesh. Për të mbështetur një numër të gjerë të transformimeve, përdoret një zgjidhje arkitektonike standarde: së pari, i gjithë dokumenti konvertohet në një përfaqësim të brendshëm të veçantë, dhe pastaj nga ky përfaqësim i brendshëm krijohet dokumenti në formatin tjetër. Përfaqësimi i brendshëm quhet nga zhvilluesit 'AST', që shënon Abstract Syntax Tree, ose . Të shikoni përfaqësimin e brendshëm është shumë e thjeshtë: për këtë mjafton të vendosni formatin e daljes 'native'
$ cat example.html
<h1>Përshëndetje, Botë!</h1>
$ pandoc -f html -t native example.html
[Header 1 ("hello-world",[],[]) [Str "Përshëndetje,",Space,Str "Botë!"]]
Lexuesit që kanë punuar, edhe pak, me Haskell-in, tashmë mund të supozojnë nga ky shembull të vogël që Pandoc është shkruar pikërisht në Haskell: dalja e kësaj komande është përfaqësimi i strukturave të brendshme të Pandoc-it në formë string-u, e krijuar në mënyrë të ngjashme me atë siç bëhet zakonisht në Haskell, për shembull, në bibliotekën standarde.
Pra, këtu mund të shihet se përfaqësimi i brendshëm është një strukturë recurse, ku çdo nyje e brendshme ka një listë. Për shembull, në nivelin më të lartë është një listë me një element - një titull të nivelit të parë me atributet 'hello-world',[],[]. Brenda këtij titulli është fshehur një listë e stringut 'Hello', hapësirës dhe stringut 'World!'.
Siç duket, përfaqësimi i brendshëm nuk dallon shumë nga HTML. Ai përbën një pemë, ku çdo nyje e brendshme jep disa informata në lidhje me formatimin e pasardhësve të saj, ndërsa në gjethet ndodhet përmbajtja e dokumentit.
Nëse zbret në nivelin e implementimit të caktuar, tipi i të dhënave për të gjithë dokumentin përcaktohet kështu:
data Pandoc = Pandoc Meta [Block]Këtu Block është pikërisht nyjet e brendshme për të cilat flitet më sipër, ndërsa Meta është meta-informacioni mbi dokumentin, si titulli, data e krijimit, autorët - për formate të ndryshme këto janë të ndryshme, dhe Pandoc përpiqet të ruajë këtë informacion sa më shumë të jetë e mundur gjatë konvertimit nga formati në format.
Gati të gjithë konstruktorët e tipit Block - për shembull, Header ose Para (paragrafi) - pranojnë si argumente atributet dhe listën e nyjeve me nivel më të ulët - Inline, në përgjithësi. Për shembull, Space ose Str janë konstruktore të tipit Inline, gjithashtu në tipin e veçantë Inline kthehet etiketa HTML. Ne nuk shohim ndonjë kuptim në dhënien e një përkufizimi të plotë të këtyre tipeve, megjithatë, vërejmë se mund të shikohet këtu .
ĂshtĂ« interesante qĂ« tipi Pandoc Ă«shtĂ« monoid. Kjo do tĂ« thotĂ« se ekziston ndonjĂ« dokument i zbrazĂ«t, dhe qĂ« dokumentet mund tĂ« mblidhen mes tyre. Kjo Ă«shtĂ« e dobishme gjatĂ« shkruarjes sĂ« Reader-ave - mund tĂ« ndahen dokumentet nĂ« pjesĂ« sipas logjikĂ«s sĂ« rastit, tĂ« analizohen secila veçmas, dhe pastaj tĂ« gjithçka tĂ« mblidhet nĂ« njĂ« dokument tĂ« vetĂ«m. NĂ« kĂ«tĂ« rast, meta-informacioni do tĂ« bashkohet nga tĂ« gjitha pjesĂ«t e dokumentit menjĂ«herĂ«.
Kur konvertohet, për shembull, nga LaTeX në HTML, së pari një modul të veçantë, i quajtur LaTeXReader, transformon dokumentin hyrës në AST, pastaj një modul tjetër, i quajtur HTMLWriter, konverton AST në HTML. Falë kësaj arkitekture nuk është e nevojshme të shkruhet një numër katror konvertimesh - mjafton të shkruhet për çdo format të ri një Reader dhe Writer, dhe të gjitha çiftet e mundshme të konvertimeve do të mbështeten automatikisht.
Natyrisht, një arkitekturë e tillë ka dhe disavantazhet e saj, të parashikuara prej kohësh nga specialistët në fushën e arkitekturës së softuerit. Problemi më i rëndësishëm është kostoja e ndryshimeve të bëra në pemën e sintaksës. Nëse ndryshimi është mjaft i rëndësishëm, do të duhet të ndryshohet kodi në të gjithë Reader-ët dhe Writer-ët. Për shembull, një nga sfidat me të cilat përballen zhvilluesit e Pandoc është mbështetje për formate komplekse të tabelave. Tani Pandoc mbështet vetëm tabelat më të thjeshta, me një titull, kolona dhe një vlerë në çdo qelizë. Për shembull, atributi colspan në HTML do të injorohet thjesht. Një nga arsyet për këtë sjellje është mungesa e një skeme të njëtrajtshme për paraqitjen e tabelave në të gjitha ose të paktën në shumë formate - për pasojë, nuk është e qartë se në çfarë forme duhet të ruhen tabelat në përfaqësimin e brendshëm. Por edhe pasi të zgjidhet një përfaqësim të caktuar, do të duhet të ndryshohet plotësisht të gjitha Reader-t dhe Writer-t që mbështesin punën me tabelat.
Gjuha Haskell u zgjodh jo vetĂ«m pĂ«r shkak tĂ« dashurisĂ« sĂ« madhe tĂ« autorĂ«ve pĂ«r programimin funksional. Haskell Ă«shtĂ« i njohur pĂ«r mundĂ«sitĂ« e tij tĂ« gjera nĂ« pĂ«rpunimin e teksteve. NjĂ« nga shembujt Ă«shtĂ« biblioteka â njĂ« bibliotekĂ« qĂ« aktivisht pĂ«rdor konceptet e programimit funksional â monoidet, monadat, aplikativet dhe funktorĂ«t alternativĂ« â pĂ«r tĂ« shkruar parserĂ« tĂ« pavarur. TĂ« gjithĂ« fuqinĂ« e Parsec mund ta shihni nĂ« HaskellWiki, ku shqyrtohet njĂ« parser i plotĂ« i njĂ« gjuhe tĂ« thjeshtĂ« imperativ. Natyrisht, Parsec pĂ«rdoret gjerĂ«sisht edhe nĂ« Pandoc.
Nëse e përshkruajmë shkurtimisht, monadat përdoren për parsing në vazhdo, kur fillimisht shkon një, e pastaj tjetra. Për shembull, në këtë shembull:
whileParser :: Parser Stmt
whileParser = whiteSpace >> statementFillimisht duhet tĂ« lexoni hapĂ«sirĂ«n, dhe mĂ« pas statement â i cili gjithashtu ka tipin Parser Stmt.
Funktorët alternativë përdoren për të kthyer mbrapsht në rast se parsing nuk ka funksionuar. Për shembull,
statement :: Parser Stmt
statement = parens statement sequenceOfStmtKëtu do të thotë se duhet të provoni të lexoni një statement në kuadrate, ose të provoni të lexoni disa statement-e një pas një.
Funktorët aplikativë përdoren kryesisht si shkurtime për monadat. Për shembull, le të themi se funksioni tok lexon një token (kjo është një funksion real nga LaTeXReader). Le të shohim një kombinim të tillë
const tok tokAi do të lexojë dy tokenë një pas tjetër dhe do të kthejë të parin prej tyre.
Për të gjitha këto klasa, në Haskell ekzistojnë operatorët e bukur simbolikë, që e bëjnë programimin e Reader-ve të duket si art ASCII. Thjesht shihni këtë kod të mrekullueshëm.
Detyrat tona ishin të lidhura me LaTeXReader. Detyra e Vasili ishte mbështetja e komandave mbox dhe hbox, të dobishme për shkruarjen e pakove në LaTeX. E përgjegjshmja e Jelizavetës ishte mbështetja e komandës epigraph, e cila mundëson formatimin e epigrafëve në dokumentet LaTeX.
Hatrace
Në sistemet operative të ngjashme me UNIX shpesh realizohet thirrja sistemike ptrace. Ajo është e dobishme për debugging dhe simulimin e ambienteve të programeve, duke lejuar ndjekjen e thirrjeve sistemike që bën programi. Për shembull, utilitarja shumë e dobishme strace e përdor pikërisht ptrace brenda saj.
Hatrace është një bibliotekë që ofron një ndërfaqe për ptrace në Haskell. E vërteta është se vetë ptrace është shumë i ndërlikuar dhe ta përdorësh atë drejtpërdrejt është mjaft e vështirë, veçanërisht nga gjuhët funksionale.
Hatrace, gjatë ekzekutimit, funksionon si strace dhe pranon argumente të ngjashme. Dallimi nga strace është se ajo është gjithashtu një bibliotekë, duke ofruar një ndërfaqe më të thjeshtë se thjesht ptrace.
Me ndihmĂ«n e hatrace kemi kapur njĂ« defekt tĂ« padĂ«shiruar nĂ« pĂ«rkthyesin Haskell GHC â kur vritet nĂ« njĂ« moment tĂ« papĂ«rshtatshĂ«m, ai gjeneron skedarĂ« objektiv tĂ« pasaktĂ« dhe nuk i rikompilon ata kur rilancohen. Skriptimi i thirrjeve sistemike lejonte garantimin e riprodhimit tĂ« gabimit nĂ« njĂ« ekzekutim, kur vrasjet rastĂ«sore riprodhonin gabimin pĂ«r rreth dy orĂ«.
Kemi shtuar nĂ« bibliotekĂ« ndĂ«rfaqet e thirrjeve sistemike â Jelizaveta shtoi brk, ndĂ«rsa Vasili shtoi mmap. Si rezultat i punĂ«s sonĂ«, mund tĂ« pĂ«rdoren mĂ« thjesht dhe me saktĂ«si argumentet e kĂ«tyre thirrjeve sistemike gjatĂ« pĂ«rdorimit tĂ« bibliotekĂ«s.
Burimi: habr.com
