ZuriHac: функциональ програмчлалын дадлага

Энэ оны 6-р сард Швейцарийн жижиг Rapperswil хотод нэгэн үйл явдал болжээ ZuriHac. Энэ удаад анхлан суралцагчаас эхлээд хэлийг үндэслэгч хүртэл таван зуу гаруй Хаскелл дурлагчдыг цуглуулсан. Хэдийгээр зохион байгуулагчид энэхүү арга хэмжээг хакатон гэж нэрлээд байгаа ч сонгодог утгаараа хурал, хакатон биш юм. Түүний формат нь уламжлалт програмистуудаас ялгаатай. Бид азаар ZuriHac-ийн талаар мэдэж, үүнд оролцсон бөгөөд одоо ер бусын олдворын талаар ярих нь бидний үүрэг гэж бодож байна!

ZuriHac: функциональ програмчлалын дадлага

Бидний тухай

Энэхүү нийтлэлийг Санкт-Петербург хотын Үндэсний судалгааны их сургуулийн Эдийн засгийн дээд сургуулийн “Хэрэглээний математик, мэдээлэл зүй” хөтөлбөрийн 3-р курсын хоёр оюутан Василий Алферов, Елизавета Василенко нар бэлтгэв. Бид хоёрын хувьд функциональ програмчлалын хүсэл эрмэлзэл нь их сургуулийн 2-р курст Д.Н.Москвины цуврал лекцээс эхэлсэн юм. Василий одоогоор Google Summer of Code хөтөлбөрт оролцож байгаа бөгөөд төслийн багийн удирдлаган дор Хаскелл хотод алгебрийн графикийг хэрэгжүүлж байна. Далайн ургамал. Елизавета олж авсан функциональ програмчлалын ур чадвараа нэгтгэх эсрэг алгоритмыг хэрэгжүүлэхэд зориулагдсан курсын ажилд ашигласан бөгөөд дараа нь төрлийн онолд ашигласан.

Үйл явдлын формат

Зорилтот үзэгчид бол нээлттэй эхийн төслүүдийн эзэд, тэдний хөгжилд оролцох хүсэлтэй програмистууд, функциональ програмчлалын судлаачид, Хаскеллд дуртай хүмүүс юм. Энэ жил HSR Hochschule für Technik Rapperswil-д дэлхийн өнцөг булан бүрээс нээлттэй эх сурвалжтай тав гаруй Haskell төслийн хөгжүүлэгчид цугларч, бүтээгдэхүүнийхээ талаар ярилцаж, шинэ хүмүүсийг тэдний хөгжлийг сонирхохоор болжээ.

ZuriHac: функциональ програмчлалын дадлага

Твиттерээс авсан зураг ZuriHac

Энэ схем нь маш энгийн: та төслийнхээ талаар хэд хэдэн саналыг урьдчилан бичиж, зохион байгуулагчдад илгээх хэрэгтэй бөгөөд тэд таны төслийн талаарх мэдээллийг үйл явдлын хуудсан дээр байрлуулах болно. Түүнчлэн эхний өдөр төслийн зохиогчид юу хийж байгаа, юу хийх ёстойгоо тайзнаас маш товчхон хэлэх гучин секундын хугацаатай. Дараа нь сонирхсон хүмүүс зохиогчдыг хайж, даалгаврын талаар дэлгэрэнгүй асуудаг.

Бидэнд өөрсдийн гэсэн нээлттэй төслүүд хараахан гараагүй байгаа ч одоо байгаа төслүүдэд хувь нэмрээ оруулахыг үнэхээр хүсч байгаа тул бид байнгын оролцогчоор бүртгүүлсэн. Гурван өдрийн турш бид хоёр хэсэг хөгжүүлэгчидтэй ажилласан. Код болон амьд харилцаа холбоог хамтран судлах нь төслийн зохиогчид болон хувь нэмэр оруулагчдын хоорондын харилцааг маш үр бүтээлтэй болгодог нь харагдаж байна - ZuriHac дээр бид бидний хувьд шинэ байсан хэсгүүдийг ойлгож, хоёр өөр багт тусалж, тус бүрдээ нэг даалгавар гүйцэтгэсэн. төслүүдийн.

Үнэ цэнэтэй дадлагаас гадна ZuriHac дээр хэд хэдэн лекц, мастер ангиуд уншсан. Бид ялангуяа хоёр лекцийг санаж байна. Тэдний эхнийх нь дээр Ньюкасл их сургуулийн Андрей Мохов сонгомол хэрэглээний функцүүдийн тухай ярьж байсан - хэрэглээний функцууд ба монадын хооронд завсрын байх ёстой төрлүүдийн анги. Өөр нэг лекц дээр Haskell-ийг үүсгэн байгуулагчдын нэг Саймон Пейтон Жонс GHC хөрвүүлэгч дээр төрлийн дүгнэлт хэрхэн ажилладаг талаар ярьсан.

ZuriHac: функциональ програмчлалын дадлага

Саймон Пейтон Жонсын лекц. Твиттерээс авсан зураг ZuriHac

Хакатон тэмцээний үеэр зохион байгуулагдсан мастер ангиудыг оролцогчдын бэлтгэлийн түвшингээс хамааран гурван төрөлд хуваасан. Төсөл боловсруулахад оролцсон оролцогчдод санал болгож буй даалгавруудыг мөн хүндрэлтэй гэж тэмдэглэсэн. Функциональ програмистуудын жижиг боловч найрсаг нийгэмлэг нь шинээр элсэгчдийг баяртайгаар угтан авдаг. Андрей Мохов, Саймон Пейтон Жонс нарын лекцийг ойлгоход бидний их сургуульд сурч байсан функциональ програмчлалын сургалт маш их хэрэгтэй байсан.

Тус арга хэмжээнд бүртгүүлэх нь байнгын оролцогчид болон төслийн зохиогчдод үнэ төлбөргүй байдаг. Бид 6-р сарын эхээр оролцох хүсэлтээ өгсөн бөгөөд үүний дараа биднийг хүлээлгийн жагсаалтаас баталгаажуулсан оролцогчдын жагсаалт руу хурдан шилжүүлсэн.

Одоо бид боловсруулахад оролцсон төслүүдийнхээ талаар ярих болно.

Пандок

Пандок Энэ бол текст баримт бичгийг ямар ч форматаас аль ч хэлбэрт шилжүүлэх бүх нийтийн хөрвүүлэгч юм. Жишээлбэл, docx-ээс pdf хүртэл, эсвэл Markdown-аас MediaWiki хүртэл. Зохиолч Жон МакФарлейн бол Беркли дэх Калифорнийн их сургуулийн философийн профессор юм. Ерөнхийдөө Пандок бол нэлээд алдартай бөгөөд манай зарим нөхөд Пандокийг Хаскелл хэлээр бичсэнийг мэдээд гайхаж байсан.

ZuriHac: функциональ програмчлалын дадлага

Pandoc дэмждэг баримт бичгийн форматын жагсаалт. Мөн сайт дээр бүхэл бүтэн график байгаа боловч энэ зураг нийтлэлд тохирохгүй байна.

Мэдээжийн хэрэг, Pandoc нь хос формат бүрт шууд хөрвүүлэх боломжийг олгодоггүй. Ийм олон төрлийн өөрчлөлтийг дэмжихийн тулд стандарт архитектурын шийдлийг ашигладаг: эхлээд бүх баримт бичгийг тусгай дотоод завсрын дүрслэл болгон хөрвүүлж, дараа нь энэ дотоод дүрслэлээс өөр форматтай баримт бичгийг үүсгэдэг. Хөгжүүлэгчид дотоод дүрслэлийг "AST" гэж нэрлэдэг бөгөөд энэ нь Abstract Syntax Tree буюу эсвэл хийсвэр синтакс мод. Та завсрын дүрслэлийг маш энгийнээр харж болно: гаралтын форматыг "уугуул" болгож тохируулахад л хангалттай.

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

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

Хаскеллтэй бага зэрэг ажиллаж байсан уншигчид энэ жижиг жишээн дээр Pandoc нь Хаскелл дээр бичигдсэн гэж аль хэдийн таамаглаж болно: энэ командын гаралт нь Pandoc-ийн дотоод бүтцийн хэлхээний дүрслэл бөгөөд үүнийг ихэвчлэн хэрхэн хийдэгтэй төстэй байдлаар бүтээгдсэн байдаг. жишээ нь Haskell-д, стандарт номын санд.

Эндээс дотоод дүрслэл нь дотоод зангилаа бүрт жагсаалт байдаг рекурсив бүтэц гэдгийг эндээс харж болно. Жишээлбэл, дээд түвшинд нэг элементийн жагсаалт байдаг - "сайн уу ертөнц",[],[] шинж чанаруудтай эхний түвшний толгой хэсэг. Энэ толгой хэсэгт "Сайн уу" гэсэн мөрийн жагсаалт, дараа нь хоосон зай, "Дэлхий!" гэсэн мөр нуугдсан байна.

Таны харж байгаагаар дотоод дүрслэл нь HTML-ээс тийм ч их ялгаатай биш юм. Энэ нь дотоод зангилаа бүр нь удамшлын форматын талаар зарим мэдээллийг өгдөг мод бөгөөд навчнууд нь баримт бичгийн бодит агуулгыг агуулдаг.

Хэрэв бид хэрэгжилтийн түвшинд очвол бүх баримт бичгийн өгөгдлийн төрлийг дараах байдлаар тодорхойлно.

data Pandoc = Pandoc Meta [Block]

Энд Блок нь дээр дурдсан дотоод оройнууд бөгөөд Мета нь гарчиг, үүсгэсэн огноо, зохиогчид гэх мэт баримт бичгийн талаархи мета мэдээлэл юм - энэ нь өөр өөр форматын хувьд өөр байдаг бөгөөд Pandoc нь форматаас орчуулахдаа боломжтой бол ийм мэдээллийг хадгалахыг хичээдэг. формат.

Блок хэлбэрийн бараг бүх бүтээгчид - жишээлбэл, Толгой эсвэл Параграф (догол мөр) - дүрмээр бол атрибутууд болон доод түвшний оройнуудын жагсаалтыг аргумент болгон авдаг. Жишээлбэл, Space эсвэл Str нь Inline төрлийн бүтээгчид бөгөөд HTML таг нь мөн өөрийн тусгай Inline болж хувирдаг. Бид эдгээр төрлүүдийн бүрэн тодорхойлолтыг өгөх нь утгагүй гэж үзэж байгаа боловч эндээс олж болно гэдгийг анхаарна уу энд.

Сонирхолтой нь Pandoc төрөл нь моноид юм. Энэ нь ямар нэгэн хоосон бичиг баримт байгаа гэсэн үг бөгөөд баримтуудыг давхарлаж болно. Уншигчид бичихдээ үүнийг ашиглахад тохиромжтой - та дурын логик ашиглан баримтыг хэсэг болгон хувааж, тус бүрийг тусад нь задлан шинжилж, дараа нь бүгдийг нэг баримт бичиг болгон нэгтгэж болно. Энэ тохиолдолд мета мэдээллийг баримт бичгийн бүх хэсгээс нэг дор цуглуулна.

LaTeX-ээс HTML рүү хөрвүүлэхдээ эхлээд LaTeXReader хэмээх тусгай модуль нь оролтын баримтыг AST болгон хувиргадаг, дараа нь HTMLWriter нэртэй өөр модуль нь AST-г HTML болгон хөрвүүлдэг. Энэхүү архитектурын ачаар дөрвөлжин тооны хөрвүүлэлт бичих шаардлагагүй - шинэ формат бүрт Reader болон Writer бичихэд хангалттай бөгөөд бүх боломжит хос хөрвүүлэлтийг автоматаар дэмжих болно.

Ийм архитектур нь програм хангамжийн архитектурын салбарын мэргэжилтнүүдийн эртнээс таамаглаж байсан сул талуудтай нь тодорхой юм. Хамгийн чухал нь синтакс модонд өөрчлөлт оруулах зардал юм. Хэрэв өөрчлөлт хангалттай ноцтой бол та бүх Уншигчид болон Зохиолчдын кодыг өөрчлөх шаардлагатай болно. Жишээлбэл, Pandoc хөгжүүлэгчдэд тулгардаг бэрхшээлүүдийн нэг бол нарийн төвөгтэй хүснэгтийн форматыг дэмжих явдал юм. Одоо Pandoc нь зөвхөн толгой, багана, нүд бүрт утга агуулсан маш энгийн хүснэгтүүдийг үүсгэх боломжтой. Жишээлбэл, HTML дэх colspan шинж чанарыг үл тоомсорлох болно. Энэ зан үйлийн нэг шалтгаан нь хүснэгтийг бүхэлд нь эсвэл наад зах нь олон форматаар дүрслэх нэгдсэн схем байхгүй байгаа явдал бөгөөд үүний дагуу хүснэгтүүдийг дотоод дүрслэлд ямар хэлбэрээр хадгалах нь тодорхойгүй байна. Гэхдээ тодорхой харагдацыг сонгосны дараа ч гэсэн хүснэгттэй ажиллахыг дэмждэг бүх уншигч, зохиолчдыг өөрчлөх шаардлагатай болно.

Хаскелл хэл нь зөвхөн зохиогчдын функциональ програмчлалд маш их хайртай байсан тул сонгосонгүй. Хаскелл нь текст боловсруулах өргөн боломжоороо алдартай. Үүний нэг жишээ бол номын сан юм парсек нь функциональ програмчлалын ойлголтууд - моноидууд, монадууд, хэрэглээний болон альтернатив функцүүд - дурын задлан шинжлэгч бичихэд идэвхтэй ашигладаг номын сан юм. Parsec-ийн бүрэн хүчийг эндээс харж болно жишээ HaskellWiki-ээс, энд энгийн императив програмчлалын хэлний бүрэн задлагчийг задлан шинжилдэг. Мэдээжийн хэрэг, Parsec нь Pandoc-д идэвхтэй ашиглагддаг.

Товчхондоо, монадыг дараалсан задлан шинжлэхэд нэг зүйл эхэлж, дараа нь өөр зүйл ирэхэд ашигладаг. Жишээлбэл, энэ жишээнд:

whileParser :: Parser Stmt
whileParser = whiteSpace >> statement

Эхлээд та зайг тоолж, дараа нь Parser Stmt төрөлтэй мэдэгдлийг тоолох хэрэгтэй.

Шинжилгээ амжилтгүй болбол буцаахад өөр функцүүдийг ашигладаг. Жишээлбэл,

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

Энэ нь та хашилтанд байгаа мэдэгдлийг унших эсвэл хэд хэдэн мэдэгдлийг дараалан уншихыг оролдох хэрэгтэй гэсэн үг юм.

Хэрэглээний функцүүдийг үндсэндээ монадын товчлол болгон ашигладаг. Жишээлбэл, tok функцийг зарим жетон уншихыг зөвшөөрнө үү (энэ нь LaTeXReader-ийн бодит функц юм). Энэ хослолыг харцгаая

const <$> tok <*> tok

Энэ нь хоёр жетоныг дараалан уншиж, эхнийхийг нь буцаана.

Эдгээр бүх ангиудын хувьд Хаскелл сайхан симбол операторуудтай бөгөөд энэ нь Reader программчлалыг ASCII урлаг шиг харагдуулдаг. Энэ гайхалтай кодыг зүгээр л биширээрэй.

Бидний даалгавар LaTeXReader-тэй холбоотой байсан. Василий даалгавар бол LaTeX дээр багц бичихэд хэрэгтэй mbox болон hbox командуудыг дэмжих явдал байв. Элизабет нь LaTeX баримт бичигт эпиграф үүсгэх боломжийг олгодог эпиграф командыг дэмжих үүрэгтэй байв.

Хэтрейс

UNIX-тэй төстэй үйлдлийн системүүд нь ихэвчлэн ptrace системийн дуудлагыг хэрэгжүүлдэг. Энэ нь програмын орчныг дибаг хийх, дуурайхад тустай бөгөөд програмын хийсэн системийн дуудлагыг хянах боломжийг танд олгоно. Жишээлбэл, маш хэрэгтэй strace хэрэгсэл нь ptrace-г дотооддоо ашигладаг.

Hatrace бол Haskell-д ptrace хийх интерфейсээр хангадаг номын сан юм. Үнэн хэрэгтээ ptrace өөрөө маш боловсронгуй бөгөөд үүнийг шууд, ялангуяа функциональ хэлнүүдээс ашиглахад нэлээд хэцүү байдаг.

Hatrace нь эхлүүлэхдээ strace шиг ажилладаг бөгөөд ижил төстэй аргументуудыг хүлээн авдаг. Энэ нь strace-аас ялгаатай нь зөвхөн ptrace гэхээсээ илүү хялбар интерфэйстэй номын сан юм.

Hatrace-ийн тусламжтайгаар бид GHC Haskell хөрвүүлэгчийн нэг таагүй алдааг аль хэдийн илрүүлсэн - буруу агшинд устгагдсан тул энэ нь буруу объектын файл үүсгэдэг бөгөөд дахин эхлүүлэх үед тэдгээрийг дахин хөрвүүлдэггүй. Системийн дуудлагуудаар скрипт хийх нь алдааг нэг гүйлтээр найдвартай хуулбарлах боломжтой болгосон бол санамсаргүй аллага нь хоёр цагийн дотор алдааг дахин гаргаж өгдөг.

Бид номын санд системийн дуудлагын интерфейсийг нэмсэн - Елизавета brk, Василий mmap нэмсэн. Бидний ажлын үр дүнд үндэслэн номын санг ашиглахдаа эдгээр системийн дуудлагын аргументуудыг илүү энгийн бөгөөд үнэн зөв ашиглах боломжтой болсон.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх