<?xml version="1.0" encoding="utf-8"?>
<!-- If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/ -->
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:lj="http://www.livejournal.com">
  <id>urn:lj:livejournal.com:atom1:dying_sphynx</id>
  <title>Ангэ Эсэф</title>
  <subtitle>Ivan Veselov</subtitle>
  <author>
    <name>Ivan Veselov</name>
  </author>
  <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/"/>
  <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom"/>
  <updated>2009-04-15T16:38:05Z</updated>
  <lj:journal userid="902413" username="dying_sphynx" type="personal"/>
  <link rel="service.feed" type="application/x.atom+xml" href="http://dying-sphynx.livejournal.com/data/atom" title="Ангэ Эсэф"/>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:72132</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/72132.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=72132"/>
    <title>Norway. Bergen, mon amour</title>
    <published>2009-04-14T19:56:48Z</published>
    <updated>2009-04-15T16:38:05Z</updated>
    <category term="norge"/>
    <category term="bergen"/>
    <category term="travel"/>
    <content type="html">Из Ставангера в Берген я ехал автостопом, решил опробовать этот чудесный способ передвижения и в Норвегии. Водители, как и все остальные норвежцы, отлично говорили по-английски, рассказывали забавные истории и в целом были отличными ребятами. Особенно запомнился пирсинг/тату-мастер на пижонском красном Мерседесе, который завёз меня километров на 30 дальше, чем ему нужно было ехать чтобы подбросить меня до парома. А ещё -- парень-Пушкин, так я про себя его назвал, потому что у него был дед-эфиоп, и он рассказывал истории про то, как ездил в Эфиопию и что там есть классный вулкан.&lt;br /&gt;&lt;br /&gt;Дорога вдоль западного побережья пересекала немалое количество проливов, фьордов и островов с помощью мостов, туннелей (самый длинный был километров 15 длиной) и паромов (их было два и за них пришлось платить, хотя к этому относились не слишком внимательно и при некоторой доле наглости можно было бы проехать и бесплатно). Единственная трудность западно-норвежского автостопа состояла в том, что часто нельзя было останавливаться на обочинах, т.к. дорога была слегка серпантинного типа. Потому однажды пришлось пройти пешком километра четыре, чтобы дойти до места, где машины могли бы остановиться. Пока я ехал -- радовался, что наконец могу созерцать норвежскую природу, радовался свободе и тому, что наконец еду автостопом после, наверное, полугодового перерыва.&lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/SeT42f3zlrI/AAAAAAAAApA/RXRatfhwGnM/s800/Bergen_24.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/ScY8w6o0jeI/AAAAAAAAAgY/u3YoM4c73oo/s800/Bergen_08.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Временами встречались прикольные, больше похожие на исландские пейзажи (по крайней мере по цветам):&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY8vdg7_II/AAAAAAAAAgQ/fL4OxhQfz0w/s800/Bergen_07.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Мост неподалёку от того места, где меня высадил тату-мастер:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/SeT44LZmPuI/AAAAAAAAApI/_Lzin8-0Ej0/s800/Bergen_25.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Наконец под звуки Pantera "Walk" я приехал в пригород Бергена со странноватым названием Paradis, откуда уже решил просто на городском автобусе доехать до Бергена.&lt;br /&gt;&lt;br /&gt;Берген -- очень атмосферный город. Говорят, что это "дождливая столица Европы", здесь очень много дождливых дней и недавно даже был поставлен рекорд, когда их было штук 90 подряд :) Наверное города, где много дождя мне особенно нравятся, потому что по приезду в Берген я испытывал нечто похожее на то, что было с Питером, вроде "Ууу, как же тут классно!". Но кстати дождя во время моего пребывания в Бергене почти и не было :)&lt;br /&gt;&lt;br /&gt;Вокруг города -- семь холмов, с них открываются красивые виды на весь город и там можно бродить по лесу, наслаждаясь свежим воздухом. На самом деле холмов вроде как девять и потому ведутся споры: какие же именно холмы входят в числе тех вот исторических семи :)&lt;br /&gt;&lt;br /&gt;Холм, теряющийся в тумане:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/SeT45CrkdDI/AAAAAAAAApQ/YDFl6-kKaZY/s800/Bergen_26.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Очень часто на фотках Бергена появляется Бригген -- ганзейский торговый квартал. Берген был важным городом для Ганзейской лиги, одним из её центров. Немецкие купцы судя по всему жили там припеваючи, сконцентрировав в своих руках всю торговлю, в том числе торговлю рыбой с северными моряками. Сейчас Бригген -- это ряд деревянных домов и даже несколько деревянных улиц с полом :) Дерево отлично горит и Бригген сжигали и восстанавливали раз пятнадцать, в одноимённом музее Бриггена можно было посмотреть как плавно менялась линия берега и как менялось место, где стоял этот квартал.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY80T9DJKI/AAAAAAAAAgo/__eROwmG4Tc/s800/Bergen_10.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Фотографии из Бергена мне очень уж нравятся, то ли действительно город такой фотогеничный, то ли я немного научился фотографировать после 5-6 дней практики. К тому же я провёл там четыре с лишним дня, потому успел многое увидеть.&lt;br /&gt;&lt;br /&gt;А вот и целая деревянная улица в Бриггене:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/SdfSpCsSgXI/AAAAAAAAAl4/W_GpvUwazsY/s800/Bergen_20.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;и отдельностоящий домик в конце:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/SdfSrMoAylI/AAAAAAAAAmA/7SP3-zSq_v4/s800/Bergen_21.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Из интересных жителей Бергена: известный композитор Эдвард Григ (наверное многие хоть когда-то слышали "В пещере горного короля"), а также целая плеяда известных блэк-метал музыкантов из групп Gorgoroth, Burzum (Варг Викернес), Immortal и других. Кстати, есть ещё группа "1349", я раньше не знал, что значит это число, но оказывается это год прихода чумы в Норвегию. Эпидемия началась, когда английский корабль с практически мёртвым экипажем причалил в бергенском порту. Чума уничтожила около половины населения Норвегии.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/SdfSc3G1rnI/AAAAAAAAAlI/gbRwvrmN95Q/s800/Bergen_14.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;В первые дни в Бергене я останавливался у замечательной девушки Бенедикты, она наполовину креолка из Луизианы, наполовину норвежка, как она сама пишет: ethnicity: creole queen meets viking :) Учится в Бергене, куда приехала из США, готовится к марафону Midnight sun, который будет летом на севере Норвегии, в Тромсё, веселится и путешествует. В очередной раз убедился, что hospitality и couch surfing -- отличные сайты, т.к. все без исключения люди, у которых я останавливался были действительно приятными и часто интересными.&lt;br /&gt;&lt;br /&gt;Конечно же в Бергене много тихих, уютных и узких улочек:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/SdfSl_fuMrI/AAAAAAAAAlo/LpoPuPZTRnU/s800/Bergen_18.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/SeT46v8xoUI/AAAAAAAAApY/26mu_NJufoU/s800/Bergen_27.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY86_Fz1TI/AAAAAAAAAhA/smHsRWM91KE/s800/Bergen_13.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;На один из холмов окружающих Берген -- Флёйен ходит фуникулёр:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY8jBhA2NI/AAAAAAAAAfg/CS9vgtZrdMs/s800/Bergen_01.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Но я поднимался туда пешком -- так намного приятнее и интереснее. Поднимаясь всё выше -- видишь всё новые и новые виды, погода была отличная:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY8pLwG9OI/AAAAAAAAAf4/xd1CuaufOog/s800/Bergen_04.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Сам подъём выглядит примерно так:&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScY84a84EcI/AAAAAAAAAg4/LprS5iXOI-8/s800/Bergen_12.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;поднимаюсь всё выше:&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/SdfSfJQl3qI/AAAAAAAAAlQ/PfGNvgBPpRc/s800/Bergen_15.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;и, наконец, один из видов, открывающихся с вершины:&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/SeT6ElVzaWI/AAAAAAAAApw/mzHg7sNFS10/s800/Bergen_30.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;довольно "геометрическое" озеро в центре:&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY8lfMZjcI/AAAAAAAAAfo/uQQLGdRbWEk/s800/Bergen_02.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;а здесь необычный микс природы и хайтека в виде транспортной развязки на фоне сосен:&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY8nOLWtkI/AAAAAAAAAfw/-P9CMziyoFI/s800/Bergen_03.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;по дороге встречались всякие артефакты:&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY8rxI99GI/AAAAAAAAAgA/-KNzuca3vao/s800/Bergen_05.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;а на холмах лежит снег и живут тролли:&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/SdfShm1BrEI/AAAAAAAAAlY/uMaDC4SnyiM/s800/Bergen_16.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;и волчицы:&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/SdfSkfTeHzI/AAAAAAAAAlg/01wYG2R-MlI/s800/Bergen_17.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;несколько элементов церквей:&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY8yu8-c3I/AAAAAAAAAgg/r70-xhcjYZs/s800/Bergen_09.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/SeT4-WoTQnI/AAAAAAAAApo/SPV5UChuPzE/s800/Bergen_29.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/SdfSn61cH4I/AAAAAAAAAlw/pYLiJBarYNA/s800/Bergen_19.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Жаль, что церковь, которая понравилась мне больше всего в Бергене, была немного вдали от центра и я видел её только ночью, потому не получилось сфотографировать.&lt;br /&gt;&lt;br /&gt;Антикварная лавка, где я хотел купить старую карту Норвегии, но пожадничал. Зато незаметно пофотографировал :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/SdfStCLExeI/AAAAAAAAAmI/ByI1XCycF4s/s800/Bergen_22.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Народ изобретательно шутит:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/SeEHjiAO99I/AAAAAAAAAnw/MnkMCfkP208/s800/Bergen_23.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY8tczFeTI/AAAAAAAAAgI/cdaHJKm_4Gc/s800/Bergen_06.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Рядом с Бриггеном:&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/SeT48da6U-I/AAAAAAAAApg/SbTs2uZRFxo/s800/Bergen_28.jpg" /&gt;&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:71774</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/71774.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=71774"/>
    <title>Norway. Stavanger.</title>
    <published>2009-03-22T20:54:07Z</published>
    <updated>2009-03-22T22:47:46Z</updated>
    <category term="norge"/>
    <category term="stavanger"/>
    <category term="travel"/>
    <content type="html">Сейчас Ставангер считается самым богатым городом Норвегии, главным образом из-за нефти. Когда в 1969-м году в Северном море обнаружили нефть (что положило началу богатству и процветанию Норвегии) &amp;#8212; Ставангер был избран центром нефтебизнеса. Кстати, интересно, что нефтяные разработки в Норвегии национализированы и ими занимается главным образом государственная компания StatOil.&lt;br /&gt;&lt;br /&gt;У города интересная история взлётов/падений и отраслей с ними связанных &amp;#8212; вначале город был известен судостроительством, затем, уже в ХХ-м веке, на смену пришло консервное дело &amp;#8212; в Ставангере делали консервы с сельдью в оливковом масле (даже есть музей консерв :)), которые, как я понимаю, экспортировались во многие страны. Ну а сейчас &amp;#8212; эра нефти.&lt;br /&gt;&lt;br /&gt;После такого вступления наверное представляется индустриальный город со зданиями из стекла и бетона, но здесь совсем другие символы достатка :)&lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;Утренний Ставангер:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY7UQqNIMI/AAAAAAAAAdY/xVo-DjijVkc/s800/Stavanger_08.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;В ХII-м веке здесь построили весьма впечатляющий собор, Stavanger Domkirke, сейчас он &amp;#8212; самый старый в Норвегии. Целиком его нормально сфотографировать мне не удалось, потому выложу не свою фотографию (да не испугает вас контраст моей ранней весны и лета с фотографии :))&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/ScaxouBtHfI/AAAAAAAAAj0/4pIhL0esHeE/s800/Stavanger_31.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;А здесь несколько планов покрупнее, уже мои:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScZKSjYDDDI/AAAAAAAAAhg/FizVr4PfXRI/s800/Stavanger_27.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Вообще, тщательно там всё так сделано и красиво, кажется даже странным, что это только XII-й век:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScY7YfpYanI/AAAAAAAAAdw/xChzP15AcyQ/s800/Stavanger_11.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;И место хорошее &amp;#8212; рядом озеро, много зелени, умиротворённо, люди птиц кормят, мне понравилось гулять рядом.&lt;br /&gt;&lt;br /&gt;Внутри собор выглядит так:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScY7Vsgv6kI/AAAAAAAAAdg/v-6ukTSHU2Q/s800/Stavanger_09.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY7XGYGOOI/AAAAAAAAAdo/gTHWLuw2guw/s800/Stavanger_10.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;В городе уютный старый центр, деревянные белые дома XVIII-го &amp;#8212; XIX-го века, они принадлежат обычным людям (скорей всего не бедным), которые в них живут и поддерживают в отличном состоянии, автоматически сохраняя исторические здания:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY7dc2_9LI/AAAAAAAAAeU/fl0_OmoJ04s/s800/Stavanger_15.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScZKTznPMeI/AAAAAAAAAho/kjNVVhadnA0/s800/Stavanger_28.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Из-за этих домиков я и приехал в Ставангер :) Это одно из мест, где возникает чувство: "вот здесь я бы пожил" :)&lt;br /&gt;&lt;br /&gt;Ставангер был европейской культурной столицей в 2008м году. Вся эта затея с культурными столицами принадлежит Евросоюзу и состоит в выборе прогрессивного города с целью привлечения внимания к его культурной жизни. При этом дополнительное финансирование позволяет городу обновить всяческие культурные ценности или построить новые. Всякие околокультурные штуки часто встречаются в Ставангере :) Например замечательные фото на стене дома:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Scaij3jOAlI/AAAAAAAAAjo/Sr4eU33T1cE/s800/Stavanger_29.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Или такая антикультурная вывеска магазина одежды :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/ScY7rtE5m6I/AAAAAAAAAfU/WJ3oZmJxZng/s800/Stavanger_23.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;А здесь, видимо, дань консервному прошлому и сельди в оливковом масле &amp;#8212; симпатичный магазин, будто юг Европы:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Scaig0KD4lI/AAAAAAAAAjg/-pxGye7Fvfk/s800/Stavanger_30.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;В Норвегии любят троллей, правда как правило они весёлые. Я собрал довольно много разных их фотографий, эти &amp;#8212; ставангерские:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScY7ahs7KpI/AAAAAAAAAeE/EXuuHP6F5hE/s800/Stavanger_13.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Ещё несколько домов:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY7fLi-yPI/AAAAAAAAAec/NX5SDBJVJno/s800/Stavanger_16.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/ScZKP9KY7II/AAAAAAAAAhQ/PobTOXjpjeE/s800/Stavanger_25.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScY7b5dSR0I/AAAAAAAAAeM/SYrX-ZVP1Tg/s800/Stavanger_14.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Нагулявшись вдоволь по старому Ставангеру я отправился к бухте, где находится музей нефти, стилизованный под нефтяную платформу:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScZKRPJxFJI/AAAAAAAAAhY/Z5AK3npmZx8/s800/Stavanger_26.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Внутри было полно любопытных экспонатов, много внимания уделялось детям: стояли игровые автоматы, в которых можно было поиграть во всякие викторины или компьютерные игры на тему энергии, нефтедобычи и т.д. Ещё мне очень понравилась модель "Реквиема" &amp;#8212; творения какого-то скульптора, которого волнует проблема глобального потепления и прочие экологические беды. Как известно, из нефти делают бензин, а когда он сгорает &amp;#8212; выделяется в том числе CO2, что не слишком хорошо. Так вот, "Реквием" представляет собой модель поверхности Земли, с чёрными континентами, плавающими в чёрной-чёрной воде (а-ля нефть) и каждый раз в двенадцать часов ночи вся эта Земля сгорает в пламени и погружается под воду. Выглядит довольно эффектно, даже на модели, там было написано, что реально такой памятник расположен где-то в бухте рядом со Ставангером, я его не видел.&lt;br /&gt;&lt;br /&gt;Модель чего-то внушительного:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY7h_0JznI/AAAAAAAAAes/39XNogDuxuo/s800/Stavanger_18.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;А это мост, который был виден из музея:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScY7fuNPBFI/AAAAAAAAAek/qZp1Zk4R5mM/s800/Stavanger_17.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;После музея я отправился обратно в центр и увидел таких замечательных девушек на тандеме (кстати никогда не видел тандемов в Киеве):&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY7jz-JAXI/AAAAAAAAAe0/30McJUq3-Eo/s800/Stavanger_19.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Потом я гулял по всяким паркам, радовало отсутствие снега, более или менее яркие краски и приятная погода.&lt;br /&gt;&lt;br /&gt;Это здание называется загадочным словом "Ледаал", на карте оно было без объяснений, будто бы всем должно быть ясно, что есть "ледаал". Он был закрыт, но потом мне рассказали, что это музей &amp;#8212; бывшее королевское поместье.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/ScY7l_7SKaI/AAAAAAAAAe8/R_ZRDE1C0-w/s800/Stavanger_20.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Кладбище Содружества. Гулять там было одно удовольствие, меланхоличные, но сочные краски, здания в тумане, странные деревья, красота!&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/ScY7nmto6XI/AAAAAAAAAfE/s4ZX1jR4Xt0/s800/Stavanger_21.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/ScY7qHOI5KI/AAAAAAAAAfM/b8eLQA6BGIo/s800/Stavanger_22.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Количество парикмахерских на квадратный километр по-моему зашкаливало везде в Норвегии, особенно в Бергене. Здесь их тоже было немало, вот указатель:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/ScY7ZD2vZQI/AAAAAAAAAd4/BM8QSJH66Vc/s800/Stavanger_12.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;И напоследок фотография похожая на скриншот экрана линуксоида с бегущими строками в терминале, но на самом деле информационный центр здоровья с названиями всяких напастей:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/ScZKONRfCiI/AAAAAAAAAhI/KoXVN7M-bzk/s800/Stavanger_24.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:71661</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/71661.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=71661"/>
    <title>Norway. Oslo. Part 2.</title>
    <published>2009-03-15T19:27:05Z</published>
    <updated>2009-03-15T21:37:50Z</updated>
    <category term="norge"/>
    <category term="oslo"/>
    <category term="travel"/>
    <content type="html">После парка Вигеланда я отправился в Фольк-музей, что находится на полуострове Bygdøy, который, как потом оказалось, является довольно мажорским районом и в нём оочень красивые домики, прямо как с картинок журнала об элитной недвижимости.&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Sb0uunLoZ5I/AAAAAAAAAbA/k7YF8N2upfI/s800/Oslo_24.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;По дороге к музею, на подходе к Bygdøy:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sbz_UINuffI/AAAAAAAAAYs/mU9Xc-4Sn-c/s800/Oslo_12.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Folkmuseet состоял из городской и сельской составляющих, в начале я пошёл смотреть всякие старые домики из сельской части из разных времён и регионов Норвегии (немного похоже на наше киевское Пирогово).&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Sb1HmaShCSI/AAAAAAAAAbk/sZDLCQH-x5g/s800/Oslo_27.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Школа:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Sbz_V4jY0gI/AAAAAAAAAY0/CJ0_wJ8BP7Q/s800/Oslo_13.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Какая-то комната с портретами людей, похожих на русских цариц, и прикольной печкой:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Sbz_W6IpTGI/AAAAAAAAAY8/yIkJemXWAjc/s800/Oslo_14.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Bethlehem &amp;#8212; это Вифлеем, город в Палестине, родина Христа. Не знаю почему такая вывеска на одном из домов, видимо какого-то религиозного назначения. Пример приятных шрифтов и ещё так называется некая метал-группа из Германии:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Sbz_YqVOW6I/AAAAAAAAAZE/46oGNpi2zkc/s800/Oslo_15.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Здесь я увидел первую &lt;a href="http://ru.wikipedia.org/wiki/Каркасная_церковь"&gt;stavkirke&lt;/a&gt;, а также много всяких "хаток" и прочего краеведческой "стаффа". Жаль, что я пришёл поздновато, поэтому часть экспозиции была закрыта, но зато мне сделали скидку на билет. Cначала я думал, что stavkirke переводится как "деревянная церковь", но потом оказалось, что даже по-английски это слово будет "stave church", и stave &amp;#8212; это те внутренние деревянные колонны, на которых держится церковь. По-русски эти церкви называются "мачтовыми" или "каркасными" или даже просто "ставкирками". Являют собой довольно уникальный пример скандинавского зодчества, когда-то были почти полностью уничтожены (сгорали, подгнивали, уничтожались населением), но при нарастании волны национализма в Норвегии, перед обретением страной независимости от Швеции, их стали охранять и реставрировать.&lt;br /&gt;&lt;br /&gt;А вот и сама церковь:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sbz_dT8N4PI/AAAAAAAAAZc/uUrmh557_is/s800/Oslo_18.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Общий вид такой, раньше она стояла в городе Гол, а теперь её перенесли в этот музей (фотография не моя):&lt;br /&gt;&lt;br /&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/98/Gol_stavkirke%2C_vinter.JPG/450px-Gol_stavkirke%2C_vinter.JPG" /&gt;&lt;br /&gt;&lt;br /&gt;Выглядят они красиво и весьма даже по-язычески, жаль даже и удивительно, что Варг и прочие товарищи из black metal комьюнити Норвегии их жгли :)&lt;br /&gt;&lt;br /&gt;Двери были украшены скандинавским орнаментом:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/Sbz_cbzIStI/AAAAAAAAAZU/JsvtpS3ghc0/s800/Oslo_17.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Вокруг церкви можно идти по такому коридорчику:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Sbz_aZ5zFGI/AAAAAAAAAZM/Jjp3SH1OgMM/s800/Oslo_16.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;В одном из домов жил какой-то художник-самоучка, который любил украшать свою мебель картинками, потом его нашли, картинки оценили по достоинству и даже выставляют в музее:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sbz_fSORlBI/AAAAAAAAAZk/EPSBSTC2HG8/s800/Oslo_19.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;В городской части музея много зданий увитых плющом (или растением на него похожим):&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sbz_gqGEFTI/AAAAAAAAAZs/kHNahBg0jK4/s800/Oslo_20.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Это пример старого магазина:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sbz_hzyfIOI/AAAAAAAAAZ0/GUzJ62rrtxY/s800/Oslo_21.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;А это &amp;#8212; мастерская и инструменты:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Sbz_kKF0qsI/AAAAAAAAAZ8/IylMIGLHIpg/s800/Oslo_22.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Наконец я отправился к самому краю полуострова Bygdøy, полюбовался видом с пристани:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Sb0utbBVjMI/AAAAAAAAAa4/Z7lVGIBbYNM/s800/Oslo_23.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Весной и летом здесь ходит водный транспорт к центру Осло, зимой же лёд и мне приходилось ездить на автобусе номер 30.&lt;br /&gt;&lt;br /&gt;Здесь недалеко находятся музей корабля Фрам. Fram (по-норвежски "вперёд") &amp;#8212; корабль, на котором плавали в своих великих экспедициях сначала Фритьоф Нансен, а потом Руаль Амундсен &amp;#8212; к Южному полюсу. Фритьоф Нансен &amp;#8212; замечательный человек, учёный, путешественник, а затем и отличный дипломат, чтение его биографии как-то доставило мне массу удовольствия.&lt;br /&gt;&lt;br /&gt;Рядом находится музей "Кон-Тики и Ра", посвящённый известному норвежскому путешественнику Туру Хейердалу. Он поддерживал идею, что индейцы Южной Америки могли поддерживать контакты с полинезийскими народами Океании и что 8000 км Тихого океана этому не помеха. Для подтверждения этой гипотезы он отправился в путешествие на плоту "Кон-Тики", построенному по образу плотов инков и через 101 день успешно прибыл к одному из островов Туамоту. Очень впечатляет, учитывая что этот плот &amp;#8212; по сути такая себе большая деревянная доска с парусом :)&lt;br /&gt;&lt;br /&gt;Ещё есть музей древних кораблей викингов, правда я в него не попал, потому видел только на фотографиях.&lt;br /&gt;&lt;br /&gt;Затем у меня почти разрядились батареи, потому фотографии на тот день закончились :)&lt;br /&gt;&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:71281</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/71281.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=71281"/>
    <title>Norway. Oslo. Part 1.</title>
    <published>2009-03-15T16:35:36Z</published>
    <updated>2009-03-15T21:37:14Z</updated>
    <category term="norge"/>
    <category term="oslo"/>
    <category term="travel"/>
    <content type="html">У меня часто спрашивали: "Почему именно Норвегия и зимой?", потому я сразу отвечу. Причин несколько: я люблю север, люблю black metal, и Норвегия &amp;#8212; слегка экзотическая страна, если выбирать из стран Европы. Мне хотелось посмотреть северное сияние, фьорды, красивую природу, наконец попробовать себя в получении шенгенской визы и также немаловажно, что WizzAir открыли дешёвый рейс Киев &amp;#8212; Осло (билет в оба конца с багажом обошёлся мне всего 454 гривны). Так что вот &amp;#8212; долгие и тщательные приготовления, сбор документов для визы, поиск хостелов и хороших ребят из hospitalityclub.org и couchsurfing.com (в итоге хостелы мне не понадобились вовсе), ранняя покупка билетов (я рискнул и заказал многие билеты даже до получения визы, и в итоге выиграл немало денег) и наконец виза получена и я улетаю в Осло!&lt;br /&gt;&lt;br /&gt;Маршрут был выбран такой:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Киев - Осло - Ставангер - Берген - куда-то на фьорды - Осло - Тромсё - Осло - Киев&lt;/b&gt;.&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;Передвижение планировалось осуществлять на самолётах, поездах, автобусах и автостопом. Почти все билеты купил заранее: у норвежской железной дороги есть такая штука как Minipris, то есть в начале продажи можно купить любой билет за 199 норвежских крон (1 доллар = примерно 7 NOK), потом билеты за 199 заканчиваются и их продают уже за 299, а потом уже реальная стоимость &amp;#8212; часто она бывает 700, а то и 1000 крон, таким образом миниприс очень выгоден, но заказывать билеты часто надо за месяц, а то и раньше.&lt;br /&gt;&lt;br /&gt;Это был мой первый полет на самолёте (до этого я летал разве что на маленьком самолёте, чтобы потом прыгнуть с парашютом), в целом всё прошло хорошо: новый самолёт, нормальный сервис (если сравнивать с другими лоукостами, которыми я передвигался в Норвегии дальше, то он даже выигрывает). Правда при посадке меня малость укачало, я не ожидал, что снижение и посадка проходят так долго.&lt;br /&gt;&lt;br /&gt;Норвегия встретила не слишком дружелюбно &amp;#8212; пришлось постоять в очереди на паспортном контроле и многих удивляли ворота безопасности при выходе, но я в этих делах не слишком опытен, потому особенно не заморачивался и не расстраивался. Впрочем на автобус до Осло я таки опоздал (а от аэропорта Сандефьорд Торп до Осло порядка 180 км). В итоге опоздал и на метро и шёл по ночному городу пешком с большим рюкзаком, что, однако, было неплохим приключением. Спасибо Андрею Сорокину, который доходчиво объяснил СМС-ками как добраться до его дома в студгородке на Согне, где я ночевал в первые дни. Первые впечатления: люди говорят по-английски, целые стада велосипедов в снегу и весёлый негр, едущий навстречу на велосипеде по ночному городу и распевающий песню на родном языке :) Ещё весьма понравились местные общежития и их жители. И наконец: часа два ночи и я могу отдохнуть и поспать.&lt;br /&gt;&lt;br /&gt;Утро, Осло. В городе полно интересных музеев, однако, как и всё в Норвегии, стоят они весьма порядочно, потому тщательный выбор может помочь сэкономить. Имеется такая штука как Oslo Pass, он стоит 220 крон за одни сутки и позволяет бесплатный проезд на любом транспорте в пределах города и посещение кучи музеев. Однако напосещать музеев аж на 220 крон за одни сутки немного утомительно, потому я его не покупал.&lt;br /&gt;&lt;br /&gt;Иногда встречаются электромашины, вроде бы они даже выпускаются в Норвегии, люди заботятся об экологии, хотя в Норвегии она и так на высоте.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/Sb1Pa_n5uhI/AAAAAAAAAb8/yup3GOEaX5k/s800/Oslo_30.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Поскольку на Осло у меня была выделена куча времени и планировалось несколько визитов города (т.к. в Осло сходятся многие маршруты, как авиа- так и железнодорожные), то в первые дни я совершенно не напрягался и не особенно старался посещать всякие достопримечательности, а просто бродил по городу, рассматривал витрины магазинов, парки, пытался найти тихие спокойные улицы. Жители Норвегии мне понравились своими правильными чертами лица, особенно красивы мужчины, девушки в целом тоже симпатичны, много натуральных блондинок.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sb1HkTGYxLI/AAAAAAAAAbc/z-v6K23o0BM/s800/Oslo_26.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Через некоторое время бродить надоело, потому я отправился в крепость Akershus, которая впрочем оказалось закрытой (довольно много интересных мест, увы, закрыты зимой, в том числе музеи Теодора Киттельсена, которые весьма хотелось посетить). Тут я встретил парочку русских туристов, после того как Wizz Air открыли свой рейс &amp;#8212; много народу ездят смотреть Осло на выходные или что-то в этом духе, так например делали ребята, с которыми я познакомился в самолёте.&lt;br /&gt;&lt;br /&gt;На улице развевался пятицветный "гейский" флаг, подошёл из интереса посмотреть, написано паб "Лондон" :) Кстати, Норвегия лояльно относится к меньшинствам, кажется даже разрешены однополые браки. А вот проституцию с января запретили.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sb1PcpsnOSI/AAAAAAAAAcE/kkud08GrVwU/s800/Oslo_31.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;А вот модерновое здание оперы, не так давно построенной в Осло. Выглядит любопытно, можно спокойно забираться на крышу и смотреть виды.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sb1Hnc2QrxI/AAAAAAAAAbs/FLB0TEm_ZUo/s800/Oslo_28.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Запомнившиеся из описания Лебедевым Осло два красных пешехода на каждом светофоре. Особенно прикольно, когда в некоторых местах сразу шесть светофоров и на них горит двенадцать красных пешеходов!&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sbz-P8e3u8I/AAAAAAAAAXE/j7FdEEKAP1U/s800/Oslo_01.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;На следующий день меня пригласили на тусовку каучсёрферов (участников сайта couchsurfing.com) в местечке с финским названием Хаукето неподалёку от Осло, где я познакомился с множеством народу из разных стран мира (примерно пятнадцать стран, а человек было от тридцати до сорока в разное время) в том числе Японии, Бразилии, Малайзии и т.д. Народ приносил свою национальную еду, было много пива, снега и музыки, отличная получилась вечеринка. Чем дальше, тем больше веселья, и вот я уже прыгаю по танцполу вместе с парнем из Малайзии и румынской девушкой Андреа под Nirvana "Smells Like Teen Spirit" :) Party в разгаре:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Sb1IbBzKfHI/AAAAAAAAAb0/U0kgqBC9hic/s800/Oslo_29.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Ещё я познакомился с прикольной молдавской семьёй, которая недавно переехала в Норвегию из Новой Зеландии, вот путешественники, блин! После полуночи народ плавно стал расходиться, а мы конечно же остались на афтепати, крепость напитков и интимность обстановки возросла, фотки стали немного crazy, а утром я обнаружил, что на моём фотоаппарате остались только несколько фотографий со мной, а все остальные, сделанные в Осло &amp;#8212; загадочно исчезли :) Видимо, кто-то уничтожал компромат, а может и просто случайность :) В начале было жаль, но теперь понимаю, что те фото все равно были явно не самыми лучшими. Ещё запомнился норвежский парень с футболкой "Прокидайся, Україно, москаль вже годину не спить!" :) Оказалось, что он недавно был во Львове, где её и приобрёл. Надо будет непременно посетить такую встречу и в Киеве.&lt;br /&gt;&lt;br /&gt;Заснеженный вид из окна дома Тригге в Хаукето:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Sbz_Hf8-gzI/AAAAAAAAAXs/jLHNlye6L2Q/s800/Oslo_03.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;В итоге на следующий день я проснулся с лёгким похмельем и провёл большую часть дня болтая с Тригге &amp;#8212; хозяином вечеринки и Андреем (моим хостом), а вечером отправился гулять по Осло с новоприобретённой знакомой из Бразилии, с английским у нас обоих было не очень хорошо, потому наши разговоры были довольно незамысловатыми :)&lt;br /&gt;&lt;br /&gt;На третий день моего пребывания в Осло я начал немного беспокоиться о том, что время идёт, а достопримечательности толком не осмотрены и ломанулся в &lt;a href="http://ru.wikipedia.org/wiki/Парк_скульптур_Вигеланда"&gt;Вигеланд-парк&lt;/a&gt;, там интересные скульптуры в большом количестве. В силу своей специфичности парк воспринимается жителями Осло двояко: его либо любят либо нет :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Sbz_KlliaEI/AAAAAAAAAX8/_ONlxhwpKk4/s800/Oslo_05.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Всего скульптур больше двухсот, по идее главной темой являются "состояния человека", не знаю, что под этим имеется в виду, но часто встречаются всякие странные композиции, например вот этот мужчина, раскидывающий младенцев :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/Sbz_OJcdl_I/AAAAAAAAAYM/dtrTcFepZ5c/s800/Oslo_07.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Ещё там в центре есть так называемый Мегалит, высокий столб, состоящий из сплетения тел и символизирующий их единение и стремление вверх, к духовному и небесному :) Вырезали его три резчика в течение четырнадцати лет:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Sb0uvxgMScI/AAAAAAAAAbI/JcTiVGl0aQ4/s800/Oslo_25.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Особенно мне понравились решётки на воротах парка и тот эффект, который получается, когда через них смотришь:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Sbz_QaK-NzI/AAAAAAAAAYU/JA2qdUGObdQ/s800/Oslo_08.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;На решётках не только обнажённые мужчины, но и женщины :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Sbz_SlWCjhI/AAAAAAAAAYk/RwGmotHizhU/s800/Oslo_11.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;А также непонятные комбинации:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_qPWkw_yZQyI/Sbz_RqwJZ-I/AAAAAAAAAYc/NY4qbvDqy68/s800/Oslo_10.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Эта вот скульптура, видимо, символизирует детское иго :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_qPWkw_yZQyI/Sbz_F9WDIzI/AAAAAAAAAXk/S2_pYb6VP9k/s800/Oslo_02.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;И ещё несколько девушек:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_qPWkw_yZQyI/Sbz_MHfMfRI/AAAAAAAAAYE/yakLclKah5Y/s800/Oslo_06.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh6.ggpht.com/_qPWkw_yZQyI/Sbz_JTQ8zQI/AAAAAAAAAX0/BUf6EEz8PNE/s800/Oslo_04.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Огромное спасибо &lt;span class='ljuser  ljuser-name_martreya' lj:user='martreya' style='white-space: nowrap;'&gt;&lt;a href='http://martreya.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://martreya.livejournal.com/'&gt;&lt;b&gt;martreya&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; за обработку фотографий!&lt;br /&gt;&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:70919</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/70919.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=70919"/>
    <title>Как я готовил презентацию. Часть 1. LaTeX.</title>
    <published>2008-12-04T06:51:16Z</published>
    <updated>2008-12-04T08:14:45Z</updated>
    <category term="latex"/>
    <category term="typesetting"/>
    <content type="html">Когда наступила надобность сверстать слайды для следующей презентации &amp;#8212; я наконец решил воспользоваться &lt;a href="http://www.latex-project.org"&gt;LaТеХ-ом&lt;/a&gt; (это уже далеко не первый мой подход, но пока самый продуктивный). В процессе работы у меня возникали различные мелкие задачи: нарисовать диаграмму, нарисовать синтаксическое дерево, нарисовать несколько деревьев "в разных позах", раскрасить исходный код, ну и наконец всё это представить в виде более или менее симпатичных слайдов.&lt;br /&gt;&lt;br /&gt;Поскольку часто полученные знания были достойны того, чтобы ими делиться, а весь этот подход по сравнению с традиционным &lt;a href="http://en.wikipedia.org/wiki/WYSIWIG"&gt;WYSIWYG&lt;/a&gt; (в лице Open или Microsoft Office) весьма любопытный и просветляющий &amp;#8212; я решил написать на эту тему несколько постов. Они не будут претендовать на роль учебных, т.к. я постараюсь быть кратким и выражать самую суть, чтобы позволить прочувствовать эту атмосферу, заинтересовать и дать толчок к дальнейшему изучению. Кроме того, я сам только изучаю LaTeX, потому не могу служить авторитетом в данной области.&lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt; Итак, начнём с LaTeX. Про него написано множество хороших статей и книг, как технического, так и идеологического характера (например почему WYSIWIG &amp;#8212; это плохо, а разделение содержания и представления во время создания документа &amp;#8212; хорошо). LaTeX &amp;#8212; это некая большая надстройка над системой компьютерного набора ТеХ, разработанной не кем иным, как &lt;a href="http://en.wikipedia.org/wiki/Donald_Knuth"&gt;Дональдом Кнутом&lt;/a&gt;, знакомым многим по объёмному труду по анализу алгоритмов и другим хорошим работам и высказываниям (мне например нравится "Premature optimization is the root of all evil"). Интересно, что версия ТеХ-а сходится к &amp;pi; (например сейчас у меня &lt;i&gt;latex --version&lt;/i&gt; выдаёт 3.1415926).&lt;br /&gt;&lt;br /&gt;Основная идея LaTeX-а проста: разделение содержания и представления. TeX-файл представляет собой обычный текстовый файл, в котором к собственно контенту добавляется некие указания, относящиеся, в основном, к логическому структурированию текста &amp;#8212; разбиение на главы, разделы, определение сносок, набор формул, таблиц и прочего. Таким образом, в процессе создания документа автор мало отвлекается на визуальное оформление &amp;#8212; это за него потом сделает система, да ещё и с помощью весьма умных алгоритмов вёрстки (Кнут же их создавал! И &lt;a href="http://en.wikipedia.org/wiki/Knuth_reward_check"&gt; обещает $327.68&lt;/a&gt; за найденный баг в системе, но их вроде с 1995-го не находят). В принципе, можно сравнить этот подход с "контент в HTML + стили в CSS".&lt;br /&gt;&lt;br /&gt;Кроме того, система позволяет расширять себя с помощью макросов, что привело к появлению огромного числа наборов этих самых макросов, собранных в пакеты, способных удовлетворить многие нужды пользователей. Собственно LaTeX &amp;#8212; и есть большая сборка различных пакетов, значительно упрощающая создание документов, но не превосходящая по возможностям сам ТеХ (то есть, теоретически, всё то, что можно сделать в LaTeX-e можно сделать и в чистом TeX-e).&lt;br /&gt;&lt;br /&gt;Касательно технических подробностей и "как же всё это попробовать": LaTeX является свободно распространяется вместе с исходниками по лицензии &lt;a href="http://www.latex-project.org/lppl.txt"&gt;LPPL (LaTeX Project Public License)&lt;/a&gt;, доступен для Linux, MacOS, Windows и прочих. Я пробовал только под Linux: нужно поставить пакет texlive (у меня в ArchLinux минимальная дистрибуция LaTeX содержится в пакетах texlive-core и texlive-bin, размер пакетов примерно 70 мегабайт).&lt;br /&gt;  &lt;br /&gt;Окей, посмотрим теперь как выглядит в TeX-e одна очень простая статья:&lt;br /&gt;&lt;br /&gt;  &lt;div style="color: #bebebe; background-color: #262626;"&gt;&lt;br /&gt;    &lt;pre&gt;
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\documentclass&lt;/span&gt;[11pt]{&lt;span style="color: #7fffd4;"&gt;article&lt;/span&gt;} &lt;span style="color: #add8e6;"&gt;%% &lt;/span&gt;&lt;span style="color: #add8e6;"&gt;type of document -- we want article
&lt;/span&gt;&lt;span style="color: #afeeee; font-weight: bold;"&gt;\usepackage&lt;/span&gt;[utf8]{&lt;span style="color: #7fffd4;"&gt;inputenc&lt;/span&gt;} &lt;span style="color: #add8e6;"&gt;%% &lt;/span&gt;&lt;span style="color: #add8e6;"&gt;we use utf8, because it rules
&lt;/span&gt;
&lt;span style="color: #add8e6;"&gt;% &lt;/span&gt;&lt;span style="color: #add8e6;"&gt;defines the title
&lt;/span&gt;&lt;span style="color: #afeeee; font-weight: bold;"&gt;\author&lt;/span&gt;{Ivan N. Veselov}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\title&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;Minimalism in \LaTeX art&lt;/span&gt;}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\date&lt;/span&gt;{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\today&lt;/span&gt;}

&lt;span style="color: #afeeee; font-weight: bold;"&gt;\begin&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;document&lt;/span&gt;}

&lt;span style="color: #add8e6;"&gt;% &lt;/span&gt;&lt;span style="color: #add8e6;"&gt;generates the title
&lt;/span&gt;&lt;span style="color: #afeeee; font-weight: bold;"&gt;\maketitle&lt;/span&gt;

&lt;span style="color: #add8e6;"&gt;% &lt;/span&gt;&lt;span style="color: #add8e6;"&gt;insert the table of contents
&lt;/span&gt;&lt;span style="color: #afeeee; font-weight: bold;"&gt;\tableofcontents&lt;/span&gt;

&lt;span style="color: #afeeee; font-weight: bold;"&gt;\section&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;Some Interesting Words&lt;/span&gt;}
Well, and here begins my lovely article. I hope you enjoy it, but I'm a bit
hesitating because it is so short &lt;span style="color: #afeeee; font-weight: bold;"&gt;\ldots&lt;/span&gt;{}

&lt;span style="color: #afeeee; font-weight: bold;"&gt;\begin&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;itemize&lt;/span&gt;} &lt;span style="color: #add8e6;"&gt;%% &lt;/span&gt;&lt;span style="color: #add8e6;"&gt;some list
&lt;/span&gt;  &lt;span style="color: #afeeee; font-weight: bold;"&gt;\item&lt;/span&gt; Item A
  &lt;span style="color: #afeeee; font-weight: bold;"&gt;\item&lt;/span&gt; Item B
  &lt;span style="color: #afeeee; font-weight: bold;"&gt;\item&lt;/span&gt; Item C
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\end&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;itemize&lt;/span&gt;}

&lt;span style="color: #afeeee; font-weight: bold;"&gt;\section&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;Good Bye World&lt;/span&gt;}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\ldots&lt;/span&gt;{} and here it ends.

&lt;span style="color: #afeeee; font-weight: bold;"&gt;\end&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;document&lt;/span&gt;}
&lt;/pre&gt;&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Как видно, команды LaTeX-a начинаются со знака "backslash" \. Некоторые из них принимают параметры, которые заключаются в фигурные скобки (обязательный параметр) или в квадратные (опциональные параметры). Сам документ состоит из &lt;i&gt;преамбулы&lt;/i&gt; и &lt;i&gt;тела&lt;/i&gt; документа. В преамбуле указывается класс документа (статья, книга, презентация, письмо и т.д.), используемые пакеты макросов, собственные макросы, информация об авторе и т.д. В теле документа, которое начинается после команды &lt;i&gt;\begin{document}&lt;/i&gt;, находится собственно содержимое документа с командами разметки.&lt;br /&gt;  &lt;br /&gt;В результате, после команды &lt;pre&gt;pdflatex example1.tex&lt;/pre&gt; мы получаем отличную &lt;a href="http://horna.org.ua/misc/example1.pdf"&gt;статью&lt;/a&gt; в формате PDF :) А здесь приведу пример, конвертированный в PNG:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://horna.org.ua/misc/example1.png" /&gt;&lt;br /&gt;&lt;br /&gt;Кстати, если собираетесь писать в документе по-русски &amp;#8212; необходимо использовать пакет babel: &lt;pre&gt;\usepackage[russian]{babel}&lt;/pre&gt; и доставить кириллические шрифты (если вы устанавливали какую-нибудь минимальную сборку &amp;#8212; их может не быть, и LaTeX не замедлит об этом напомнить).&lt;br /&gt;&lt;br /&gt;Отдельная приятность LaTeX-а &amp;#8212; очень мощная поддержка вёрстки математических формул, которую я с радостью использовал в дипломе. Я начал использовать LaTeX именно в качестве генератора красиво выглядящих и удобно набираемых формул, которые я потом превращал в картинки и вставлял в диплом. Кто пробовал набирать более или менее сложные формулы в Офисе &amp;#8212; весьма оценят эту возможность LaTeX-a. Конечно же для того, чтобы научиться их писать &amp;#8212; нужно вначале почитать учебник (ссылки на них находятся в конце статьи), однако всё довольно понятно и быстро запоминается. Кстати, формулы в Википедии задаются именно в формате ТеХ-а.&lt;br /&gt;&lt;br /&gt;Вот несколько формул на закуску.&lt;br /&gt;&lt;br /&gt;Исходник в .tex:&lt;br /&gt;&lt;br /&gt;  &lt;div style="color: #bebebe; background-color: #262626;"&gt;&lt;br /&gt;    &lt;pre&gt;
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\documentclass&lt;/span&gt;{&lt;span style="color: #7fffd4;"&gt;article&lt;/span&gt;}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\usepackage&lt;/span&gt;{&lt;span style="color: #7fffd4;"&gt;amsmath&lt;/span&gt;}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\begin&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;document&lt;/span&gt;}
All of us know that &lt;span style="color: #87cefa;"&gt;$sin^&lt;/span&gt;&lt;span style="color: #87cefa; font-size: 80%;"&gt;2&lt;/span&gt;&lt;span style="color: #87cefa;"&gt; x + cos^&lt;/span&gt;&lt;span style="color: #87cefa; font-size: 80%;"&gt;2&lt;/span&gt;&lt;span style="color: #87cefa;"&gt; x = 1$&lt;/span&gt;    &lt;span style="color: #add8e6;"&gt;% simple inlined formula
&lt;/span&gt;
But what about calculating this?
&lt;span style="color: #87cefa;"&gt;$$&lt;/span&gt;
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\frac&lt;/span&gt;{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\pi&lt;/span&gt;}{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\sum\limits&lt;/span&gt;_&lt;span style="font-size: 80%;"&gt;{m=0}&lt;/span&gt;^&lt;span style="font-size: 80%;"&gt;{&lt;/span&gt;&lt;span style="color: #afeeee; font-size: 80%; font-weight: bold;"&gt;\infty&lt;/span&gt;&lt;span style="font-size: 80%;"&gt;}&lt;/span&gt;{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\frac&lt;/span&gt;{2}{(4n + 1)(4n + 3)}}}
&lt;span style="color: #87cefa;"&gt;$$&lt;/span&gt;

Continued fraction (with further formulae numbering):
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\begin&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;equation&lt;/span&gt;}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\cfrac&lt;/span&gt;{1}{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\sqrt&lt;/span&gt;{2}+
 &lt;span style="color: #afeeee; font-weight: bold;"&gt;\cfrac&lt;/span&gt;{1}{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\sqrt&lt;/span&gt;{2}+
  &lt;span style="color: #afeeee; font-weight: bold;"&gt;\cfrac&lt;/span&gt;{1}{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\sqrt&lt;/span&gt;{2}+&lt;span style="color: #afeeee; font-weight: bold;"&gt;\dotsb&lt;/span&gt;
}}}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\end&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;equation&lt;/span&gt;}

And something more advanced:
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\begin&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;equation&lt;/span&gt;}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\Re&lt;/span&gt;{z} =&lt;span style="color: #afeeee; font-weight: bold;"&gt;\frac&lt;/span&gt;{n&lt;span style="color: #afeeee; font-weight: bold;"&gt;\pi&lt;/span&gt; &lt;span style="color: #afeeee; font-weight: bold;"&gt;\dfrac&lt;/span&gt;{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\theta&lt;/span&gt; +&lt;span style="color: #afeeee; font-weight: bold;"&gt;\psi&lt;/span&gt;}{2}}{
        &lt;span style="color: #afeeee; font-weight: bold;"&gt;\left&lt;/span&gt;(&lt;span style="color: #afeeee; font-weight: bold;"&gt;\dfrac&lt;/span&gt;{&lt;span style="color: #afeeee; font-weight: bold;"&gt;\theta&lt;/span&gt; +&lt;span style="color: #afeeee; font-weight: bold;"&gt;\psi&lt;/span&gt;}{2}&lt;span style="color: #afeeee; font-weight: bold;"&gt;\right&lt;/span&gt;)^&lt;span style="font-size: 80%;"&gt;2&lt;/span&gt; + &lt;span style="color: #afeeee; font-weight: bold;"&gt;\left&lt;/span&gt;( &lt;span style="color: #afeeee; font-weight: bold;"&gt;\dfrac&lt;/span&gt;{1}{2}
        &lt;span style="color: #afeeee; font-weight: bold;"&gt;\log&lt;/span&gt; &lt;span style="color: #afeeee; font-weight: bold;"&gt;\left\lvert\dfrac&lt;/span&gt;{B}{A}&lt;span style="color: #afeeee; font-weight: bold;"&gt;\right\rvert\right&lt;/span&gt;)^&lt;span style="font-size: 80%;"&gt;2&lt;/span&gt;}.
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\end&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;equation&lt;/span&gt;}
&lt;span style="color: #afeeee; font-weight: bold;"&gt;\end&lt;/span&gt;{&lt;span style="color: #7fffd4; font-weight: bold;"&gt;document&lt;/span&gt;}
&lt;/pre&gt;&lt;br /&gt;  &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Результат:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://horna.org.ua/misc/formulae-little.png" /&gt;&lt;br /&gt;&lt;br /&gt;Итак, подытожим. Что мы получаем, изучив LaTeX?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;возможность верстать сложные документы в любимом текстовом редакторе (например vim или emacs). Хотя если хочется каких-то специализированных графических редакторов &amp;#8212; их тоже полно, например &lt;a href="http://kile.sourceforge.net/"&gt;Kile&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;отличные, профессиональные шаблоны для вёрстки just for free&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;инструмент для удобной генерации математических формул любой сложности&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;знание формата, который является стандартом де-факто для публикации статей многих математических и computer science конференций, журналов и т.п.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;инструмент для быстрого создания презентаций&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;возможность последующей конвертации в PDF, PostScript, DocBook, HTML и другие форматы&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Какие же могут возникнуть проблемы?&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;потеря возможности легко "копипэйстить" из чужих вордовских документов в свои, что довольно актуально для студентов :)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;как всегда в чём-то хорошем &amp;#8212; требуется некоторое время на изучение&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;В следующих постах я собираюсь перейти ближе к делу и рассказать о том, как я делал презентацию с помощью пакета beamer, генерировал картинки разных графов и деревьев для последующей вставки в ТеХ-овский документ, а также о том, как можно рисовать деревья средствами самого LaTeX-а. Stay tuned! &lt;br /&gt;&lt;br /&gt;Полезные ссылки:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://ru.wikipedia.org/wiki/LaTeX"&gt;Как всегда, Википедия [RU]&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.tex.uniyar.ac.ru/doc/lshortru.pdf"&gt;Один из основных базовых учебников ("Не очень краткое введение в LaTeX") [RU, PDF]&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.mccme.ru/free-books/llang/newllang.pdf"&gt;Часто рекомендуемая книга Львовского С.М. ("Набор и вёрстка в системе LaTeX") [RU, PDF]&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="ftp://ftp.ams.org/pub/tex/doc/amsmath/short-math-guide.pdf"&gt;Short math guide for LaTeX (довольно краткая сводка знаний о LaTeX, полезных для набора формул) [EN, PDF]&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:70419</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/70419.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=70419"/>
    <title>happy birthday!</title>
    <published>2008-09-09T09:25:31Z</published>
    <updated>2008-09-09T09:25:31Z</updated>
    <content type="html">Сегодня у &lt;span class='ljuser  ljuser-name_martreya' lj:user='martreya' style='white-space: nowrap;'&gt;&lt;a href='http://martreya.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://martreya.livejournal.com/'&gt;&lt;b&gt;martreya&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; День Рожденья! Ура, ура, ура! :)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:70300</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/70300.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=70300"/>
    <title>xmonad</title>
    <published>2008-08-29T08:07:29Z</published>
    <updated>2008-08-29T08:08:41Z</updated>
    <content type="html">&lt;a href="http://ro-che.info"&gt;Роман Чепляка&lt;/a&gt; выложил в HTML &lt;a href="http://ro-che.info/docs/xmonad"&gt;нашу статью о xmonad&lt;/a&gt;, весьма хорошем оконном менеджере, написанном на haskell. &lt;br /&gt;Ранее она публиковалась в журнале &lt;a href="http://osa.samag.ru"&gt;Open Source&lt;/a&gt;, выпуски 27, 28, 29. &lt;br /&gt;Можно смело сказать, что статья является самой подробной из всего написанного про xmonad на русском :)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:69995</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/69995.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=69995"/>
    <title>On CS articles</title>
    <published>2008-08-28T20:17:09Z</published>
    <updated>2008-08-28T21:02:13Z</updated>
    <content type="html">Хотите написать умную статью, но не знаете о чём?&lt;br /&gt;&lt;br /&gt;Вам поможет &lt;a href="http://pdos.csail.mit.edu/scigen/"&gt;это&lt;/a&gt;! О правильном использовании написано в разделе Examples :)&lt;br /&gt;&lt;br /&gt;P.S. Спасибо за наводку замечательному блогу &lt;a href="http://www.defmacro.org"&gt;http://www.defmacro.org&lt;/a&gt;, не перестаю получать удовольствие от тонкого юмора в статьях автора :)&lt;br /&gt;&lt;br /&gt;P.P.S. А в материалах конференции WMSCI 2005 такие статьи даже печатают! Подробнее обо всей этой истории &lt;a href="http://itre.cis.upenn.edu/~myl/languagelog/archives/002067.html"&gt;здесь&lt;/a&gt;.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:69781</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/69781.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=69781"/>
    <title>Турция</title>
    <published>2008-07-22T08:31:36Z</published>
    <updated>2009-04-15T09:07:38Z</updated>
    <category term="turkey"/>
    <category term="travel"/>
    <content type="html">Примерно неделю назад мы с Мариной (&lt;span class='ljuser  ljuser-name_martreya' lj:user='martreya' style='white-space: nowrap;'&gt;&lt;a href='http://martreya.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://martreya.livejournal.com/'&gt;&lt;b&gt;martreya&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;) вернулись из двухнедельного автостопа по Турции. Поездка получилось отличной, полной ярких впечатлений и интересной. Турки - замечательные люди, спокойные, улыбчивые и дружелюбные.  История страны невообразимо насыщена, кого здесь только не было: и хетты, и греки, и римляне, и турки-сельджуки, и турки-османы! Стамбул (Константинополь) - бывшая столица трёх империй: Восточно-Римской, Византийской и Османской. В общем, предварительно начитавшись статей и путеводителей мы двинулись в путь :)&lt;br /&gt;&lt;br /&gt;Маршрут был такой:&lt;br /&gt;&lt;br /&gt;Киев - Одесса - (1.5 дня на теплоходе) - Стамбул - Изник - Ассос - Эгейское море - Измир - Гюмюльдюр - Сельчук - Эфес - Конья - Гёреме (Каппадокия) - Невшехир - Стамбул - (1.5 дня на теплоходе) - Севастополь - Киев.&lt;br /&gt;&lt;br /&gt;Карта:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://i61.photobucket.com/albums/h67/martreya/2008_07_Turkey/map.jpg"&gt;&lt;br /&gt;&lt;br /&gt;В процессе путешествия удалось немного изучить турецкий язык :) Слов 70, которые часто нам были нужны, типа числительных, местоимений и т.д. Ещё я читал, что у него весьма логичная грамматика, и благодарен Ататюрку за введение латиницы вместо арабской вязи, ибо надписи на дорожных знаках так читать несравненно легче.&lt;br /&gt;&lt;br /&gt;Несмотря на то, что во время путешествия я записывал некоторые впечатления в блокнот, я всё никак не соберусь упорядочить их и привести в какой-то художественный вид. В отличие от меня, Марина - молодец, выкладывает фотографии и пишет отличные отчёты, ссылки на которые я сейчас и приведу. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/330322.html"&gt;Вступление&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/330545.html"&gt;Одесса&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/331213.html"&gt;Стамбул (часть первая)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/331373.html"&gt;Изник&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/331553.html"&gt;Ассос(Бехрамкале)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/331796.html"&gt;Гюмюлдюр&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/332286.html"&gt;Эфес&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/332286.html"&gt;Сельчук&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;UPD:&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/332667.html"&gt;Конья&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/332924.html"&gt;Гёреме, Каппадокия&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/333339.html"&gt;Каппадокия (часть вторая)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/333589.html"&gt;Гёреме, музей&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/334730.html"&gt;Стамбул (часть вторая)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martreya.livejournal.com/334993.html"&gt;Море&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:69501</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/69501.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=69501"/>
    <title>О букве Ё</title>
    <published>2008-03-12T10:06:03Z</published>
    <updated>2008-03-12T11:59:11Z</updated>
    <category term="yo"/>
    <category term="orphography"/>
    <category term="lingua"/>
    <content type="html">В последнее время я начал проверять орфографию с помощью программы aspell и обнаружил, что в виндовой её поставке нет русского словаря с буквой "ё". Соответственно, при проверке aspell ругается на слова типа "поёт", "смеётся" и т.д., что мне совершенно не нравится.&lt;br /&gt;&lt;br /&gt;  Оказалось, что такая проблема со словарями есть далеко не только у aspell-а, и довольно часто отдельно выпускаются словари с буквой "ё" и без неё. Более того, опросив пару человек в аське, я удивился тому, что многие из них не употребляют в наборе букву "ё", так как "она неудобно расположена на клавиатуре", "и так понятно где она, а где е" и т.д.&lt;br /&gt;&lt;br /&gt;  Немного поисследововав этот вопрос, можно узнать следующие факты:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; Ё была предложена в 1783, впервые использована в печати в 1795, однако формально вошла в алфавит только в советские годы &lt;/li&gt;&lt;br /&gt;&lt;li&gt; относительно названия надстрочного элемента (вот тех двух точек) нет единого мнения. Употребление слов "умляут", "трема" считается некорректным, поскольку относится к диакритике символа, а диакритика связана с произношением звука (и т.к. ё фонетически не связана с е (ё=йо, е=йэ), то две точки сверху - не диакритический символ) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; медленное введение в обиход и распространение буквы ё объясняется её неудобной для быстрого письма формой и техническим несовершенством печатных средств докомпьютерной эпохи. Заметьте, обе эти причины отсутствуют в компьютерном наборе. Хотя, конечно, им на смену может прийти несколько необычное расположение этой буквы на клавиатуре &lt;/li&gt;&lt;br /&gt;&lt;li&gt; в результате необязательности употребления буквы "ё", сейчас мы можем наблюдать множество исковерканных личных имён (Ришелье, Монтескье, Рентген, Рерих и т.д. - все они были с буквой Ё ;)) &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;  И что мне кажется более важным: появляются разногласия при написании слов типа "маневр", "желчь", "блеклый", "издевка" и т.д. Таким образом, когда мы видим букву "е" - мы должны задумываться о том как правильно прочесть это слово: с "е" или с "ё". Если бы "ё" было обязательным в этих случаях, разногласий бы не возникло.&lt;br /&gt;&lt;br /&gt;  Действующие правила орфографии не требуют написания буквы "ё", однако рекомендуют её написание в неоднозначных словах. Однако, задумываетесь ли вы например при написании очередного поста в ЖЖ, что слово "все" может быть прочитано как "всё"? Уверен, что нет. Увидев такое слово в неоднозначном предложении, приходится возвращаться к нему и переосмысливать прочитанное, что не менее важно, чем то, что взгляд "спотыкается о букву Ё", что например является одним из главных аргументов "против" в статье Лебедева про Ё из его книги "Ководство".&lt;br /&gt;&lt;br /&gt;  Для того, чтобы исследовать какой процент фрэндов моего ЖЖ использует букву "ё" в своих постах, я написал небольшой скрипт - ёметер :) Он извлекает список друзей, затем последние 25 постов каждого пользователя и проводит простой анализ. Для каждого пользователя затем выдаётся "yo-ratio" (отношение постов с "ё" ко всем постам), так же отношение фрэндов хотя бы раз употребивших "ё" ко всем фрэндам. У меня этот результат таков:&lt;br /&gt; &lt;pre&gt;
 total users = 106, significant users = 100,
 yo users = 64, ratio = 0.64
 &lt;/pre&gt; Таким образом &lt;b&gt;36&lt;/b&gt; процентов моих фрэндов ни разу не употребило "ё" за последние 25 постов! К вам, собственно, и обращён этот мой пост :)&lt;br /&gt;&lt;br /&gt; Ссылки:&lt;br /&gt;&lt;br /&gt; - исходный код &lt;a href="http://horna.org.ua/misc/yometer.txt"&gt;yometer.py&lt;/a&gt; (для использования необходим python и доступ в интернет)&lt;br /&gt; - &lt;a href="http://ru.wikipedia.org/wiki/%D0%81"&gt;статья про Ё в русской википедии&lt;/a&gt;&lt;br /&gt; - много ссылок в конце этой статьи&lt;br /&gt; - &lt;a href="http://www.artlebedev.ru/kovodstvo/paragraphs/119/"&gt;параграф из книги "Ководство" А. Лебедева&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPD:&lt;/b&gt; Для поднятия насущности вопроса публикую под катом список фрэндов, не употребляющих "ё" :) (отредактирован после работы скрипта - вычеркнуты англоязычные и украиноязычные юзеры)&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;&lt;span class='ljuser  ljuser-name_alexott' lj:user='alexott' style='white-space: nowrap;'&gt;&lt;a href='http://alexott.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://alexott.livejournal.com/'&gt;&lt;b&gt;alexott&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_vrepets' lj:user='vrepets' style='white-space: nowrap;'&gt;&lt;a href='http://vrepets.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://vrepets.livejournal.com/'&gt;&lt;b&gt;vrepets&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_andriyv' lj:user='andriyv' style='white-space: nowrap;'&gt;&lt;a href='http://andriyv.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://andriyv.livejournal.com/'&gt;&lt;b&gt;andriyv&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_gogabr' lj:user='gogabr' style='white-space: nowrap; text-decoration: line-through;'&gt;&lt;a href='http://gogabr.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://gogabr.livejournal.com/'&gt;&lt;b&gt;gogabr&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_uhzpm' lj:user='uhzpm' style='white-space: nowrap;'&gt;&lt;a href='http://uhzpm.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://uhzpm.livejournal.com/'&gt;&lt;b&gt;uhzpm&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_dr_klm' lj:user='dr_klm' style='white-space: nowrap;'&gt;&lt;a href='http://dr-klm.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://dr-klm.livejournal.com/'&gt;&lt;b&gt;dr_klm&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_dtim' lj:user='dtim' style='white-space: nowrap;'&gt;&lt;a href='http://dtim.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://dtim.livejournal.com/'&gt;&lt;b&gt;dtim&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_japanspy' lj:user='japanspy' style='white-space: nowrap;'&gt;&lt;a href='http://japanspy.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://japanspy.livejournal.com/'&gt;&lt;b&gt;japanspy&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_e_v_ches' lj:user='e_v_ches' style='white-space: nowrap;'&gt;&lt;a href='http://e-v-ches.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://e-v-ches.livejournal.com/'&gt;&lt;b&gt;e_v_ches&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_fotoankh' lj:user='fotoankh' style='white-space: nowrap;'&gt;&lt;a href='http://fotoankh.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://fotoankh.livejournal.com/'&gt;&lt;b&gt;fotoankh&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_frumich' lj:user='frumich' style='white-space: nowrap;'&gt;&lt;a href='http://frumich.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://frumich.livejournal.com/'&gt;&lt;b&gt;frumich&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_zoodyzero' lj:user='zoodyzero' style='white-space: nowrap;'&gt;&lt;a href='http://zoodyzero.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://zoodyzero.livejournal.com/'&gt;&lt;b&gt;zoodyzero&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_krlz' lj:user='krlz' style='white-space: nowrap;'&gt;&lt;a href='http://krlz.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://krlz.livejournal.com/'&gt;&lt;b&gt;krlz&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name__denplusplus_' lj:user='_denplusplus_' style='white-space: nowrap;'&gt;&lt;a href='http://users.livejournal.com/_denplusplus_/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://users.livejournal.com/_denplusplus_/'&gt;&lt;b&gt;_denplusplus_&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name__elfik_' lj:user='_elfik_' style='white-space: nowrap; text-decoration: line-through;'&gt;&lt;a href='http://users.livejournal.com/_elfik_/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://users.livejournal.com/_elfik_/'&gt;&lt;b&gt;_elfik_&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_thesz' lj:user='thesz' style='white-space: nowrap;'&gt;&lt;a href='http://thesz.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://thesz.livejournal.com/'&gt;&lt;b&gt;thesz&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_martreya' lj:user='martreya' style='white-space: nowrap;'&gt;&lt;a href='http://martreya.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://martreya.livejournal.com/'&gt;&lt;b&gt;martreya&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_lyubkin' lj:user='lyubkin' style='white-space: nowrap;'&gt;&lt;a href='http://lyubkin.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://lyubkin.livejournal.com/'&gt;&lt;b&gt;lyubkin&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_yury_lifshits' lj:user='yury_lifshits' style='white-space: nowrap;'&gt;&lt;a href='http://yury-lifshits.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://yury-lifshits.livejournal.com/'&gt;&lt;b&gt;yury_lifshits&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_musta_auringon' lj:user='musta_auringon' style='white-space: nowrap;'&gt;&lt;a href='http://musta-auringon.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://musta-auringon.livejournal.com/'&gt;&lt;b&gt;musta_auringon&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_natalie_ray' lj:user='natalie_ray' style='white-space: nowrap;'&gt;&lt;a href='http://natalie-ray.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://natalie-ray.livejournal.com/'&gt;&lt;b&gt;natalie_ray&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_palm_mute' lj:user='palm_mute' style='white-space: nowrap;'&gt;&lt;a href='http://palm-mute.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://palm-mute.livejournal.com/'&gt;&lt;b&gt;palm_mute&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_muha_elka' lj:user='muha_elka' style='white-space: nowrap;'&gt;&lt;a href='http://muha-elka.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://muha-elka.livejournal.com/'&gt;&lt;b&gt;muha_elka&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_ironpeter' lj:user='ironpeter' style='white-space: nowrap;'&gt;&lt;a href='http://ironpeter.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://ironpeter.livejournal.com/'&gt;&lt;b&gt;ironpeter&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_n_a_d_i_r' lj:user='n_a_d_i_r' style='white-space: nowrap;'&gt;&lt;a href='http://n-a-d-i-r.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://n-a-d-i-r.livejournal.com/'&gt;&lt;b&gt;n_a_d_i_r&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_pericotera' lj:user='pericotera' style='white-space: nowrap;'&gt;&lt;a href='http://pericotera.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://pericotera.livejournal.com/'&gt;&lt;b&gt;pericotera&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_kaktycnet' lj:user='kaktycnet' style='white-space: nowrap;'&gt;&lt;a href='http://kaktycnet.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://kaktycnet.livejournal.com/'&gt;&lt;b&gt;kaktycnet&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:69246</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/69246.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=69246"/>
    <title>Вторая встреча SpbHUG</title>
    <published>2007-11-18T00:00:40Z</published>
    <updated>2007-11-21T13:58:49Z</updated>
    <category term="event"/>
    <category term="spbhug"/>
    <category term="haskell"/>
    <lj:music>The Velvet Underground</lj:music>
    <content type="html">Сегодняшняя встреча &lt;a href="http://spbhug.folding-maps.org/wiki/"&gt;SpB Haskell user group&lt;/a&gt; прошла просто замечательно - услышал много нового и интересного, да и сам что-то хорошее рассказал :)&lt;br /&gt;&lt;br /&gt;В программе было три доклада:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; "Комбинаторы сериализации" (&lt;a href="http://spbhug.folding-maps.org/wiki/PicklerCombinators"&gt;слайды&lt;/a&gt;) - мой доклад. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; "Свободные теоремы" (или "Теоремы нахаляву" - вольный перевод Theorems for free)   (&lt;a href="http://spbhug.folding-maps.org/wiki/TheoremsForFree"&gt;слайды&lt;/a&gt;) - доклад &lt;span class='ljuser  ljuser-name_deni_ok' lj:user='deni_ok' style='white-space: nowrap;'&gt;&lt;a href='http://deni-ok.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://deni-ok.livejournal.com/'&gt;&lt;b&gt;deni_ok&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; "Функциональные структуры данных (часть вторая)" (&lt;a href="http://spbhug.folding-maps.org/wiki/FunctionalDataStructures2"&gt;слайды&lt;/a&gt;) - доклад &lt;span class='ljuser  ljuser-name_antilamer' lj:user='antilamer' style='white-space: nowrap;'&gt;&lt;a href='http://antilamer.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://antilamer.livejournal.com/'&gt;&lt;b&gt;antilamer&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; (чуть позже возможно появятся фотографии и аудиозапись)&lt;br /&gt;&lt;br /&gt;Я получил свой первый опыт чтения докладов широкой (да ещё и весьма интеллектуальной) публике, получив при этом массу fun-a. Смею надеяться - первый блин не вышел комом :) &lt;br /&gt;&lt;br /&gt;Остальные доклады тоже весьма порадовали - и интересные результаты, получающиеся в результате вывода этих самых "халявных" теорем, и полезные и интересные техники, описанные Женей, вместе с его замечательными иллюстрациями :) и последующая мини-лекция о realtime-вычислениях и проблемах, с этим связанных, рассказанная Иваном Тарасовым (&lt;span class='ljuser  ljuser-name__navi_' lj:user='_navi_' style='white-space: nowrap;'&gt;&lt;a href='http://users.livejournal.com/_navi_/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://users.livejournal.com/_navi_/'&gt;&lt;b&gt;_navi_&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;), так сказать, в кулуарах.&lt;br /&gt;&lt;br /&gt;Что же, с нетерпением жду следующих встреч! :)</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:68947</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/68947.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=68947"/>
    <title>SPJ "The implementation of functional programming languages"</title>
    <published>2007-11-09T22:08:48Z</published>
    <updated>2007-11-09T22:18:19Z</updated>
    <category term="plt"/>
    <category term="functional programming"/>
    <category term="book"/>
    <lj:music>muse</lj:music>
    <content type="html">Сегодня, просматривая свою коллекцию книжек и paper-ов по функциональному программированию, решил посмотреть, что там пишет Simon L. Peyton Jones в своей книге &lt;i&gt;"The implementation of functional programming languages"&lt;/i&gt;. И был приятно удивлён - как же классно он пишет! Хотел всего лишь прочесть вступление и зачитался! :)  Меньше чем за 30 первых страниц книги получаем чёткое, сжатое, понятное и хорошо иллюстрированное описание таких тем:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; синтаксис лямбда-исчисления (в дальнейшем ЛИ) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; карринг &lt;/li&gt;&lt;br /&gt;&lt;li&gt; операционная семантика ЛИ  &lt;/li&gt;&lt;br /&gt;&lt;li&gt; бета-редукция, альфа- и эта-преобразования и что они значат &lt;/li&gt;&lt;br /&gt;&lt;li&gt; порядок редукции, его оптимальность &lt;/li&gt;&lt;br /&gt;&lt;li&gt; нормальный порядок редукции &lt;/li&gt;&lt;br /&gt;&lt;li&gt; теоремы Чёрча-Россера &lt;/li&gt;&lt;br /&gt;&lt;li&gt; пример выражения, у которого нет нормальной формы &lt;/li&gt;&lt;br /&gt;&lt;li&gt; как выражать рекурсивные функции в ЛИ &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Y-комбинатор &lt;/li&gt;&lt;br /&gt;&lt;li&gt; денотационная семантика ЛИ, отличие денотационной семантики от операционной &lt;/li&gt;&lt;br /&gt;&lt;li&gt; bottom _|_ &lt;/li&gt;&lt;br /&gt;&lt;li&gt; строгость и ленивость функций &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Конечно, почти все эти темы и ЛИ в общем являются классикой, так сказать ядром функционального программирования, и я про них неоднократно читал раньше в разных источниках. Но столь хорошее описание встречаю, наверное, впервые.&lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt; В качестве анонса попробую написать свой вольный пересказ/перевод вступления к книге.&lt;br /&gt;&lt;br /&gt;Судя из названия, книга рассказывает об имплементации функциональных языков с использованием редукции графов. В первой части книги производится трансляция языков высокого уровня в промежуточное представление - лямбда-исчисление, во второй части приводится имплементация такого промежуточного языка с помощью техники  редукция графов, а также её вариаций. В третьей части описывается &lt;i&gt;G-машина&lt;/i&gt;, хитрая имплементация редукции графов, приводящая к значительному росту производительности. &lt;br /&gt;&lt;br /&gt;А теперь подробнее. &lt;br /&gt;&lt;br /&gt;&lt;b&gt; Первая часть. &lt;/b&gt; &lt;br /&gt;Поскольку многие функциональные языки похожи по своей сути - возникает идея использовать для их имплементации некое промежуточное представление, промежуточный язык, имплементация которого не будет зависеть от различий в изначальных языках высокого уровня. В качестве такого языка было выбрано лямбда-исчисление в силу своей простоты и выразительности. Таким образом, имплементация функциональных языков будет состоять из двух фаз:&lt;br /&gt;&lt;br /&gt;1. Преобразование программы из функционального языка высокого уровня в промежуточный язык, базирующийся на ЛИ.&lt;br /&gt;2. Имплементация промежуточного языка.&lt;br /&gt;&lt;br /&gt;После описанного в начале поста обзора классического лямбда-исчисления вводится некое надмножество ЛИ (enriched lambda calculus), которое облегчает трансляцию в него языков высокого уровня. &lt;br /&gt;Оставшиеся главы первой части книги раскрывают такие аспекты преобразования в промежуточный код:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; трансляция простых программ на Miranda (который является примером языка высокого уровня в книге и в некотором роде одним из прообразов Haskell) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; сопоставление по образцу (pattern matching), его формальная семантика &lt;/li&gt;&lt;br /&gt;&lt;li&gt; эффективная трансляция pattern matching выражений (эта глава, как и некоторые последующие, написана Филипом Вадлером) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; преобразование обогащённого лямбда-исчисления в обычное &lt;/li&gt;&lt;br /&gt;&lt;li&gt; list comprehensions &lt;/li&gt;&lt;br /&gt;&lt;li&gt; проверка типов, полиморфизм &lt;/li&gt;&lt;br /&gt;&lt;li&gt; реализация type-checker-а &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;&lt;br /&gt;&lt;b&gt; Вторая часть. &lt;/b&gt; &lt;br /&gt;Вторая и третья части книги посвящены имплементации лямбда-исчисления с помощью техники &lt;i&gt;редукция графов (graph reduction)&lt;/i&gt;. &lt;br /&gt;Кратко суть этой техники можно описать на примере выполнения простой программы&lt;br /&gt;&lt;pre&gt; f x = (x + 3) * (x - 1) &lt;/pre&gt;&lt;br /&gt;Предположим, нам нужно посчитать f 2:&lt;br /&gt;&lt;pre&gt; f 2 = (2 + 3) * (2 - 1) &lt;/pre&gt;&lt;br /&gt;Это выражение можно представить в виде дерева:&lt;br /&gt;&lt;pre&gt;
     *
    / \
   +   -
  / \ / \
 2  3 2  1
&lt;/pre&gt;&lt;br /&gt;применяя последовательно сложение и вычитание (в любом порядке), мы получим такое (редуцированное) дерево:&lt;br /&gt;&lt;pre&gt;
     *
    / \
   5   1
&lt;/pre&gt;&lt;br /&gt;в итоге, умножив, мы получим результат 5, который более не редуцируется.&lt;br /&gt;&lt;br /&gt;Проведя вышеописанный процесс, можно сделать следующие наблюдения:&lt;br /&gt;&lt;br /&gt;1. Выполнение функциональной программы состоит в вычислении выражений.&lt;br /&gt;2. Естественным представлением функциональной программы является дерево (или более обще - граф)&lt;br /&gt;3. Вычисление происходит посредством выполнения последовательных простых шагов называемых редукциями. Каждая редукция представляет собой простое локальное изменение в графе - редукцию графа. &lt;br /&gt;4. Редукции могут проводиться в различном порядке, а также параллельно, поскольку часто они не влияют не взаимодействуют друг с другом.&lt;br /&gt;5. Вычисление считается завершённым, если не осталось выражений, которые могут быть редуцированы. &lt;br /&gt;&lt;br /&gt;Техника редукции графов представляет модель выполнения функциональной программы, разительно отличающуюся от модели выполнения в императивных языках.&lt;br /&gt;Эта техника последовательно рассматривается во второй части книги, которая рассказывает о таких темах:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; представление программы в виде графа &lt;/li&gt;&lt;br /&gt;&lt;li&gt; порядок редукций &lt;/li&gt;&lt;br /&gt;&lt;li&gt; собственно проведение редукций &lt;/li&gt;&lt;br /&gt;&lt;li&gt; суперкомбинаторы &lt;/li&gt;&lt;br /&gt;&lt;li&gt; полная ленивость &lt;/li&gt;&lt;br /&gt;&lt;li&gt; SK - комбинаторы (техника альтернативная суперкомбинаторам) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; сборка мусора &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;&lt;br /&gt;&lt;b&gt; Третья часть. &lt;/b&gt; &lt;br /&gt;Третья часть книги повествует о некоей &lt;i&gt;G-машине&lt;/i&gt;, предназначенной для прямого выполнения на ней редукции графов. То есть процесс редукции графов может быть компилирован в некоторое представление, которое может быть достаточно быстро напрямую выполнено в G-машине на обычном компьютере, выполняющем линейную последовательность команд. Кроме этого, в третьей части содержатся некоторые проясняющие и дополнительные темы. Итак, третья часть:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; концепция и описание G-машины &lt;/li&gt;&lt;br /&gt;&lt;li&gt; различные оптимизации её работы &lt;/li&gt;&lt;br /&gt;&lt;li&gt; анализ строгости &lt;/li&gt;&lt;br /&gt;&lt;li&gt; оценка сложности функциональных программ &lt;/li&gt;&lt;br /&gt;&lt;li&gt; параллельные реализации редукции графов &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;&lt;br /&gt;В общем, продолжу читать, думаю, что при такой отличной манере изложения и столь интересных темах книга принесёт определённую пользу и удовольствие.&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:68608</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/68608.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=68608"/>
    <title>Неисповедимы пути википедии</title>
    <published>2007-10-20T22:40:47Z</published>
    <updated>2007-10-20T22:40:47Z</updated>
    <category term="fun"/>
    <content type="html">Весёлая, однако, штука - википедия! Читал статью про метасинтаксические переменные, а буквально через два-три перехода по ссылкам внутри статей - уже попал на статью про куннилингус! :) При этом узнал, что и до него, и после нежелательно чистить зубы и есть чипсы и сухарики :)&lt;br /&gt;&lt;br /&gt;А в дополнение выпуск xkcd на эту же тему:&lt;br /&gt;&lt;a href="http://xkcd.com/214/"&gt;[xkcd.com - The problem with Wikipedia]&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:68413</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/68413.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=68413"/>
    <title>QuickCheck</title>
    <published>2007-10-06T15:05:13Z</published>
    <updated>2007-10-06T17:09:43Z</updated>
    <category term="quickcheck"/>
    <category term="haskell"/>
    <category term="testing"/>
    <content type="html">Вчера, с подачи &lt;span class='ljuser  ljuser-name_antilamer' lj:user='antilamer' style='white-space: nowrap;'&gt;&lt;a href='http://antilamer.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://antilamer.livejournal.com/'&gt;&lt;b&gt;antilamer&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; (спасибо за вдохновляющий поток эмоций! :)), поразбирался с &lt;a href="http://www.cs.chalmers.se/~rjmh/QuickCheck/"&gt; QuickCheck&lt;/a&gt; - средством для тестирования функционального кода, которое основывается на проверках неких свойств, которые задаются относительно определённых функций и проверяются на случайно сгенерированных данных. &lt;br /&gt;&lt;br /&gt;Классический пример: есть функция &lt;i&gt;reverse&lt;/i&gt; для обращения списков. Тогда можно придумать такие достаточно ярко её характеризующие свойства:&lt;br /&gt;&lt;pre&gt;
propReverseUnit x       = reverse [x] == [x]                             
-- (то есть, обращая список из одного элемента - получаем тот же список)

propReverseAppend xs ys = reverse (xs++ys) == reverse ys ++ reverse xs
-- (обращая конкатенацию списков, получаем конкатенацию обращений частей 
-- в обратном порядке)

propReverseReverse xs   = reverse (reverse xs) == xs
-- (обращая обращение списка - получаем тот же список)
&lt;/pre&gt;&lt;br /&gt;Теперь из-под &lt;i&gt;ghci&lt;/i&gt; запускаем &lt;i&gt;QuickCheck&lt;/i&gt;:&lt;br /&gt;&lt;pre&gt;
Main&amp;gt; quickCkeck propReverseReverse
OK, 100 tests passed
&lt;/pre&gt;&lt;br /&gt;и - вот он, момент истины! - QuickCheck сгенерил 100 случайных списков, на которых проверил данное свойство и поскольку оно всегда выполнилось - выдал &lt;i&gt;OK&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;При этом свойства могут быть и посложнее нежели описанные выше - в них могут присутствовать необходимые для выполнения свойства условия, генерируемые данные могут быть определённым образом классифицированы, кроме этого можно создавать свои генераторы значений, в том числе для рекурсивных типов (легко!) и даже генераторы случайных функций!&lt;br /&gt;&lt;br /&gt;Для того, чтобы дополнительно управлять случайными значениями, которые генерятся и направлять эти значения в нужное русло - существуют понятие "генератор", которые можно (и иногда нужно) описывать для своих и стандартных типов данных, а также некоторый небольшой фрэймворк, который позволяет эти генераторы комбинировать с помощью стандартных, довольно удобных и отлично продуманных комбинаторов - получая при этом новые необходимые генераторы.&lt;br /&gt;&lt;br /&gt;На предстоящей встрече &lt;a href="http://spbhug.folding-maps.org/wiki/"&gt; Spb Haskell User Group &lt;/a&gt;, как раз ожидается доклад по QuickCheck от Дмитрия Тимофеева (&lt;span class='ljuser  ljuser-name_dtim' lj:user='dtim' style='white-space: nowrap;'&gt;&lt;a href='http://dtim.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://dtim.livejournal.com/'&gt;&lt;b&gt;dtim&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;), который, думаю, будет весьма интересно послушать, при этом уточнив пока неясные для меня моменты.&lt;br /&gt;&lt;br /&gt;В общем, весьма любопытная штука и немного необычный (по крайней мере для меня) подход к тестированию, который отлично работает в условиях отсутствия побочных эффектов и превращает процесс тестирования в весьма увлекательный процесс размышления над свойствами своей программы. Изначально QuickCheck был написан для Haskell и активно там используется, но поиск в гугле выдал и &lt;a href="http://www.cs.chalmers.se/~rjmh/ErlangQC/"&gt; порт для Erlang &lt;/a&gt;.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:68070</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/68070.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=68070"/>
    <title>Котята в Киеве :)</title>
    <published>2007-07-24T11:18:52Z</published>
    <updated>2007-07-24T11:18:52Z</updated>
    <category term="cats"/>
    <content type="html">У меня вот родились котята с месяц назад (мама - наша Маська, папа - некий сторонний перс), теперь ищем им хозяев.&lt;br /&gt;На эту тему сделал здесь пост:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://community.livejournal.com/ru_cats/7034131.html"&gt;Пост про котят с фото&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Там есть и фотки, и небольшое описание, и контакты. &lt;br /&gt;А ещё сделаю превью одного котёнка здесь: &lt;br&gt; &lt;br /&gt;&lt;a href="http://picasaweb.google.ru/veselov/Cats/photo#5090711883197482402"&gt;&lt;img src="http://lh6.google.ru/veselov/RqXXfGvYhaI/AAAAAAAAAGw/lrvGu1MUrPE/s144/preview%20-%20marta.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Был бы очень благодарен за помощь в раздаче, ибо в воскресенье утром (29.07) возвращаюсь в Петербург, и было бы весьма неплохо их к тому времени раздать. Котята весьма позитивные, игривые и пока неизбалованные, так что рекомендую :)&lt;br /&gt;Спасибо!</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:67756</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/67756.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=67756"/>
    <title>Киев - СПб</title>
    <published>2007-07-08T09:38:46Z</published>
    <updated>2007-07-08T09:38:46Z</updated>
    <category term="info"/>
    <content type="html">Вчера благополучно переехали в Санкт-Петербург, буду теперь некоторое время здесь жить :)&lt;br /&gt;Старый номер телефона можете смело удалять, теперь контакты такие: +7 921 3782469.&lt;br /&gt;&lt;br /&gt;У нас тут есть чукотские сказки, шахматы, автомобильная сирена по утрам и новый нескрипящий диван!&lt;br /&gt;Все желающие повидать меня в СПб are welcome! :)&lt;br /&gt;&lt;br /&gt;Кроме того, примерно 15 июля ещё вернусь на несколько дней в Киев.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:67501</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/67501.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=67501"/>
    <title>Пример изоморфизма</title>
    <published>2007-06-20T13:38:29Z</published>
    <updated>2007-06-21T09:05:02Z</updated>
    <category term="math"/>
    <content type="html">Наткнулся на прикольный пример изоморфизма. Есть игра для двух игроков: каждый по очереди называет число от 1 до 9. Повторяться нельзя. Выигрывает тот игрок, который первым назовёт числа, сумма которых равна 15.&lt;br /&gt;Спрашивается: какой &lt;i&gt;известной&lt;/i&gt; игре эта игра изоморфна?&lt;br /&gt;Комментарии пока скрываются :).&lt;br /&gt;&lt;br /&gt;P.S. &lt;i&gt;Изоморфизм&lt;/i&gt; - это по сути взаимно-однозначное соответствие между двумя множествами, которое сохраняет структуру этих множеств - то есть какой-то набор правил (аксиом), соответствующий множеству, будет выполняться в обеих множествах. &lt;br /&gt;Например есть колода карт с зелёными рубашками и колода карт с синими рубашками. Между ними можно провести взаимно-однозначное соответствие, при этом каждой из них можно всё так же играть (то есть соблюдается определённый набор правил, которому соответствует каждая колода). Таким образом, это соответствие сохраняет структуру и потому может называться изоморфизмом.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE (ответ)&lt;/b&gt;&lt;br /&gt;Более половины комментариев были верными - ответом является игра в крестики-нолики на магическом квадрате 3х3 (сумма чисел в котором по вертикалям, горизонталям и главным диагоналям которого равна 15).&lt;br /&gt;Выглядит он вот так:&lt;br /&gt;&lt;div align="center"&gt;&lt;pre&gt;2 7 6
9 5 1
4 3 8&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;При этом я немного некорректно поставил условие: действительно, как справедливо отметили некоторые из отвечавших, следует ограничить условия победы тем, что суммировать можно три и только три числа из названных игроком (что соответствует победе тремя крестиками или ноликами, поставленными в ряд). &lt;br /&gt;&lt;br /&gt;Спасибо всем за ответы, было интересно!</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:67156</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/67156.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=67156"/>
    <title>Белорусский арабский алфавит</title>
    <published>2007-05-28T22:00:55Z</published>
    <updated>2007-05-29T09:20:09Z</updated>
    <category term="lingua"/>
    <content type="html">Захотел я почитать в Википедии статью про DSL (&lt;i&gt;domain specific languages&lt;/i&gt;) и не пожалел :) Набрал не в той раскладке "&lt;i&gt;dsl&lt;/i&gt;", и по запросу "&lt;i&gt;выд&lt;/i&gt;" английская Википедия достаточно неожиданно выдала мне с релевантностью 9,9% интересную статью про белорусский арабский алфавит. Поначалу я подумал, что это очередной википедийный вандализм (а-ля &lt;a href="http://ru.wikipedia.org/w/index.php?title=%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D0%BE%D0%B5_%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%9C%D0%93%D0%A3&amp;amp;oldid=4224409"&gt;недавняя байка про МГУ&lt;/a&gt;), но нет. &lt;br /&gt;&lt;br /&gt;Как оказалось, белорусский язык записывался в XVI-м веке арабскими буквами местными татарами, которые почти в абсолютном большинстве забыли родной язык, но не хотели терять свою религию и нашли такое решение: пересказать Коран на белорусском и записать его с помощью арабской письменности. Возникли проблемы с некоторыми звуками, которых изначально не было в арабском ("ж", "ч", "п", "дз", "ц", а также "у краткое"), но они были решены введением новых символов. Таким образом, возникли "&lt;i&gt;китабы&lt;/i&gt;" (&lt;i&gt;kitabs&lt;/i&gt;) - целые книги, записанные подобным образом - преимущественно религиозные и фольклорные.&lt;br /&gt;&lt;br /&gt;Сейчас китабы хранятся в библиотеках АН Беларуси, АН Литвы, Вильнюсского, Петербургского и Казанского университетов, а также в частных коллекциях. &lt;br /&gt;Такой вот интересный пример транслита.&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;Ссылки по теме:&lt;br /&gt;&lt;a href="http://ru.wikipedia.org/wiki/%D0%91%D0%B5%D0%BB%D0%BE%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D1%80%D0%B0%D0%B1%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D0%BB%D1%84%D0%B0%D0%B2%D0%B8%D1%82"&gt;Статья на русской Википедии&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.pravapis.org/art_kitab1_en.asp"&gt;Более подробная статья о кетабах (англ.)&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:66854</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/66854.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=66854"/>
    <title>Haskell: комбинаторные парсеры Parsec.</title>
    <published>2007-05-24T12:20:35Z</published>
    <updated>2007-05-24T12:53:15Z</updated>
    <category term="haskell"/>
    <category term="parsing"/>
    <category term="geek"/>
    <content type="html">Что же, &lt;a href="http://dying-sphynx.livejournal.com/66108.html"&gt;в прошлый раз&lt;/a&gt; мы вспомнили формы записи операторов и рассмотрели написание простого вычислителя постфиксных выражений на Haskell. Следующим шагом является создание транслятора выражений из инфиксной формы - в префиксную. Однако, перед этим нам необходимо улучшить разбор выражения на токены, поэтому в данной статье мы рассмотрим монадические комбинаторные парсеры на примере модуля &lt;a href="http://www.cs.ruu.nl/~daan/parsec.html"&gt;Parsec&lt;/a&gt;, а также использование их на практике.&lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;strong&gt;Haskell postfix: часть вторая. Комбинаторные парсеры Parsec.&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Как мы уже убедились, постфиксная форма предоставляет массу преимуществ, которыми было бы неплохо пользоваться. Хотя в реальной жизни чаще используется инфиксная форма, существуют несложные алгоритмы для преобразования. Наиболее известным их представителем является &lt;a href="http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C#.D0.90.D0.BB.D0.B3.D0.BE.D1.80.D0.B8.D1.82.D0.BC"&gt;алгоритм "сортировочная станция"&lt;/a&gt;, предложенный Дейкстрой.  Алгоритм получил своё название из-за сходства его операций с действиями, происходящими на железнодорожных сортировочных станциях. Подробно приводить его здесь я не стану, ибо он хорошо описан в указанной выше статье. Работает алгоритм на основе стека, в процессе работы используется входная и выходная строки, в стеке находятся символы, ещё не выведенные в выходную строку. Из входной строки считывается очередной символ и в зависимости от его типа (оператор, операнд, функция, скобка, запятая и т.д.) производятся определённые действия по манипулированию со стеком и выходной строкой. &lt;br /&gt;&lt;br /&gt;Вернёмся к программированию. &lt;br /&gt;Поскольку "сортировочная станция" работает не только с операндами и операторами, но и c функциями со списками аргументов, нам необходимо расширить наше описание токена:&lt;br /&gt;&lt;pre&gt;&lt;u&gt;&lt;font color="Green"&gt;data&lt;/font&gt;&lt;/u&gt; Token &lt;font color="Red"&gt;=&lt;/font&gt; Atom String &lt;font color="Red"&gt;|&lt;/font&gt; Op String &lt;font color="Red"&gt;|&lt;/font&gt; LParen &lt;font color="Red"&gt;|&lt;/font&gt; RParen &lt;font color="Red"&gt;|&lt;/font&gt; Comma &lt;font color="Red"&gt;|&lt;/font&gt; Func String &lt;u&gt;&lt;font color="Green"&gt;deriving&lt;/font&gt;&lt;/u&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;Eq&lt;font color="Blue"&gt;,&lt;/font&gt; Ord&lt;font color="Blue"&gt;,&lt;/font&gt; Show&lt;font color="Blue"&gt;)&lt;/font&gt;
&lt;/pre&gt;&lt;br /&gt;Данный типа реализует и скобки, и запятые, и специальный токен функции Func String. &lt;br /&gt;&lt;br /&gt;Очевидно, что для проведения парсинга такого рода функции типа &lt;em&gt;parseToken&lt;/em&gt; из предыдущей части будет недостаточно, поскольку требуется некий предпросмотр (lookahead) для того, чтобы определить будет ли строка функцией или же простым идентификатором, а также хотелось бы не разделять токены пробелами во входной строке, как это было сделано в предыдущей версии программы.&lt;br /&gt;&lt;br /&gt;Что же, для задач подобного рода существует хороший готовый инструмент - монадические парсеры Parsec. Подход, используемый Parsec, вполне естественен для создания рекурсивных парсеров в рамках функционального программирования и базируется на следующих принципах: &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1)&lt;/strong&gt; Каждый парсер представляется в виде некоторой функции.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2) &lt;/strong&gt;Эта функция принимает на вход некоторую строку, которую надо обработать. Подумаем, что является результатом разбора. Вообще говоря, это может быть почти всё, что угодно - к примеру результатом парсинга строки "23" вполне может быть число 23, результатом разбора строки "2 + 3" может быть некое дерево с корнем (+) и листьями 2 и 3. Поэтому назовём тип результата просто &lt;em&gt;a&lt;/em&gt;. Получим следующий тип:&lt;br /&gt;&lt;pre&gt;type Parser a = String -&amp;gt; a&lt;/pre&gt;&lt;br /&gt;где &lt;em&gt;a&lt;/em&gt; - параметр типа &lt;em&gt;Parser&lt;/em&gt;, показывающий, что именно мы хотим от него получить. Например, парсер целых чисел будет иметь тип &lt;em&gt;Parser Int&lt;/em&gt;, а парсер деревьев - &lt;em&gt;Parser Tree&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Однако, парсер может обработать не всю строку, а только её часть и вернуть остаток. К примеру, если мы подадим на вход парсеру целых чисел строку "2s", то он обработает только "2" и должен бы вернуть "s". Поэтому было бы неплохо расширить возвращаемый тип до пары &lt;em&gt;(a, String)&lt;/em&gt;, получив следующее:&lt;br /&gt;&lt;pre&gt;type Parser a = String -&amp;gt; (a, String)&lt;/pre&gt;&lt;br /&gt;Также парсер может вообще не вернуть результат, то есть не распарсить даже части входной строки, а также может распарсить какую-то строку несколькими способами. Это подводит нас к мысли, что способов разбора может быть от нуля до бесконечности. В следствие этого понимания, мы расширяем тип возвращаемого парсером значения до списка пар, то есть:&lt;br /&gt;&lt;pre&gt;type Parser a = String -&amp;gt; [(a, String)] &lt;/pre&gt;&lt;br /&gt;Причём возврат пустого списка будет свидетельствовать о неуспешном разборе, а возврат списка с более чем одним элементом - о неоднозначном разборе. Наиболее удачный вариант - возврат в точности одного элемента в списке. &lt;br /&gt;&lt;br /&gt;Таким образом мы определились с типом парсеров-функций.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3)&lt;/strong&gt; Определяются функции высшего порядка (&lt;em&gt;комбинаторы&lt;/em&gt;), которые определённым образом сочетают парсеры, позволяя производить такие операции определения грамматик, как последовательное распознавание двух символов грамматики (&lt;em&gt;sequencing&lt;/em&gt;), параллельное - то есть выбор из двух альтернатив (&lt;em&gt;choice&lt;/em&gt;) или же более сложные конструкции расширенной нотации Бэкуса-Наура вроде повторов (&lt;em&gt;repeating&lt;/em&gt;).&lt;br /&gt;&lt;br /&gt;Рассмотрим данные конструкции более подробно на примере правила грамматики для идентификатора некоторого языка программирования. Предположим, что первым символом идентификатора может быть любая буква, а последующими символами буква или цифра. Тогда правило будет выглядеть так:&lt;br /&gt;&lt;pre&gt;identifier = letter (letter | digit)*&lt;/pre&gt;&lt;br /&gt;где последовательная запись означает последовательное распознавание (то есть сначала необходмо распознать letter, а затем (letter | digit)*, &lt;br /&gt;&lt;strong&gt;|&lt;/strong&gt; - означает выбор между альтернативами, &lt;br /&gt;&lt;strong&gt;*&lt;/strong&gt; - означает возможность повтора любое количество раз.&lt;br /&gt;&lt;br /&gt;Для всех описанных конструкций существуют аналоги в Parsec. Последовательное выполнение парсеров записывается с помощью операции связывания &lt;strong&gt;&amp;gt;&amp;gt;&lt;/strong&gt;, выбор с помощью комбинатора &lt;strong&gt;&amp;lt;|&amp;gt;&lt;/strong&gt;, а повтор - с помощью комбинатора &lt;em&gt;many&lt;/em&gt;. Таким образом парсер индентификаторов в Parsec будет выглядеть так:&lt;br /&gt;&lt;pre&gt;identifier = letter &amp;gt;&amp;gt; many (letter &amp;lt;|&amp;gt; digit)&lt;/pre&gt;&lt;br /&gt;Затем на основе элементарных комбинаторов строятся более сложные комбинаторы и так далее. Рассматривать подробно этот процесс я не стану, ему посвящены целые отдельные статьи, ссылки на которые будут даны в конце статьи. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4)&lt;/strong&gt; Как оказалось, комбинаторы и парсеры формируют некую абстрактую структуру, называемую &lt;em&gt;"монадой"&lt;/em&gt;, пришедшую в Haskell из теории категорий. Монаду можно представить как некий контейнерный тип, в котором элементы контейнера могут быть связаны друг с другом некоторой стратегией вычислений. В данном случае, каждой составляющей контейнера является конкретный парсер, а под их связыванием подразумевается последовательное выполнение двух парсеров с промежуточной передачей результата разбора первым - второму. "Упаковка" парсеров в монаду помогает сокрыть такие вещи, как явную передачу промежуточного состояния парсинга, а также позволяет записывать парсеры в более компактной и удобочитаемой форме.&lt;br /&gt;&lt;br /&gt;Таким образом, можно отметить, что использование комбинаторных монадических парсеров является типичным функциональным подходом к разбору, позволяет избежать специфических языков, изучение которых необходимо для написания грамматик (как при работе с yacc, ANTLR), кромего того, в случае Parsec - парсеры являются first-class citizens языка, что позволяет значительно ускорить процесс их создания.&lt;br /&gt;&lt;br /&gt;Попробуем продемонстрировать сказанное на нашем примере. Задача стоит следующим образом: создать парсер, которые превращает строки вида "4 * (f(1, 2) + 3)" в список токенов, то есть осуществляет лексический анализ строки. Проверять синтаксическую корректность выражений мы пока не станем, этим займётся будущий транслятор в постфиксную форму.&lt;br /&gt;&lt;br /&gt;Начнём с самых простых токенов - &lt;em&gt;LParen&lt;/em&gt;, &lt;em&gt;RParen&lt;/em&gt;, которым соответствуют символы открывающейся и закрывающейся скобок.&lt;br /&gt;Поскольку мы хотим чтобы парсер возвращал токен, то его типом будет &lt;em&gt;Parser Token&lt;/em&gt;.&lt;br /&gt;&lt;pre&gt;lparen &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
lparen &lt;font color="Red"&gt;=&lt;/font&gt;  char &lt;font color="Magenta"&gt;'('&lt;/font&gt; &lt;font color="Blue"&gt;&amp;gt;&amp;gt;&lt;/font&gt; return LParen&lt;/pre&gt;&lt;br /&gt;Мы воспользовались стандартным парсером &lt;em&gt;char&lt;/em&gt;, уже определённым в Parsec. Несложно догадаться, что он распознаёт один заданный символ, в данном случае '('. В случае успешного распознания нам нужно вернуть токен LParen. Это можно сделать с помощью специальной монадической функции return, которую необходимо связать с парсером char. Делается это с помощью оператора связывания &lt;strong&gt;&amp;gt;&amp;gt;&lt;/strong&gt;. В данном случае связывание означает последовательное выполнение, то есть в начале выполняется распознавание скобки, а затем возвращается токен &lt;em&gt;LParen&lt;/em&gt;. Если скобка не будет распознана - возникнет ошибка, о которой Parsec незамедлительно сообщит. &lt;br /&gt;&lt;br /&gt;Попробуем протестировать наш парсер левой скобки. Сделать это можно в интерпретаторе GHCi. Запишем наше определение типа токен (data Token) и новосозданный парсер. Ключевое слово &lt;em&gt;deriving&lt;/em&gt; в определении типа означает, что данный тип автоматически имплементирует некоторые классы. Если тип имлементирует класс Show - он может быть отображён, то есть существует некоторая функция, которая преобразует этот тип в строку, в данном случае (при употреблении ключевого слова &lt;em&gt;deriving&lt;/em&gt;) эта функция генерируется автоматически. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;u&gt;&lt;font color="Green"&gt;module&lt;/font&gt;&lt;/u&gt; Main &lt;u&gt;&lt;font color="Green"&gt;where&lt;/font&gt;&lt;/u&gt;

&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; Text&lt;font color="Blue"&gt;.&lt;/font&gt;ParserCombinators&lt;font color="Blue"&gt;.&lt;/font&gt;Parsec

&lt;u&gt;&lt;font color="Green"&gt;data&lt;/font&gt;&lt;/u&gt; Token &lt;font color="Red"&gt;=&lt;/font&gt; Atom String &lt;font color="Red"&gt;|&lt;/font&gt; Op String &lt;font color="Red"&gt;|&lt;/font&gt; LParen &lt;font color="Red"&gt;|&lt;/font&gt; RParen &lt;font color="Red"&gt;|&lt;/font&gt; Comma &lt;font color="Red"&gt;|&lt;/font&gt; Func String &lt;u&gt;&lt;font color="Green"&gt;deriving&lt;/font&gt;&lt;/u&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;Eq&lt;font color="Blue"&gt;,&lt;/font&gt; Ord&lt;font color="Blue"&gt;,&lt;/font&gt; Show&lt;font color="Blue"&gt;)&lt;/font&gt;

lparen &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
lparen &lt;font color="Red"&gt;=&lt;/font&gt;  char &lt;font color="Magenta"&gt;'('&lt;/font&gt; &lt;font color="Blue"&gt;&amp;gt;&amp;gt;&lt;/font&gt; return LParen&lt;/pre&gt;&lt;br /&gt;Теперь можно сохранить и загрузить в GHCi. Тестировать парсеры можно с помощью стандартной функции &lt;em&gt;parseTest&lt;/em&gt;, которая принимает в качестве первого параметра парсер, а в качество второго - входную строку:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;*Main&amp;gt; parseTest lparen "("
LParen&lt;/pre&gt;&lt;br /&gt;Как видим, тест успешно пройден, парсер распознал токен LParen и вывел его. Попробуем теперь следующее:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;*Main&amp;gt; parseTest lparen "a"
parse error at (line 1, column 1):
unexpected "a"
expecting "("&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Здесь Parsec выдал вполне информативную ошибку. На формат выдачи ошибок, вернее описание того, ожидалось можно немного влиять с помощью комбинатора &lt;strong&gt;&amp;lt;?&amp;gt;&lt;/strong&gt;&lt;br /&gt;Достаточно написать &lt;br /&gt;&lt;pre&gt;char '(' &lt;?&gt; "left parenthesis" &amp;gt;&amp;gt; return LParen&lt;/pre&gt;&lt;br /&gt;как описание ошибки станет таким:&lt;br /&gt;&lt;pre&gt;*Main&amp;gt; parseTest lparen "a"
parse error at (line 1, column 1):
unexpected "a"
expecting "left parentheses"&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Продолжим описывать необходимые функции. Парсеры для закрывающейся скобки и запятой выглядят аналогично:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;rparen &lt;font color="Red"&gt;=&lt;/font&gt;  char &lt;font color="Magenta"&gt;')'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;gt;&amp;gt;&lt;/font&gt; return RParen
comma  &lt;font color="Red"&gt;=&lt;/font&gt;  char &lt;font color="Magenta"&gt;','&lt;/font&gt; &lt;font color="Blue"&gt;&amp;gt;&amp;gt;&lt;/font&gt; return Comma&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Парсер для токена &lt;em&gt;Atom&lt;/em&gt; (то есть переменной или числа), выглядит следующим образом:&lt;br /&gt;&lt;pre&gt;atom &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
atom &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  a &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; many1 alphaNum &lt;font color="Blue"&gt;&amp;lt;?&amp;gt;&lt;/font&gt; &lt;font color="Green"&gt;"atom"&lt;/font&gt;
  return &lt;font color="Blue"&gt;(&lt;/font&gt;Atom a&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;Здесь мы используем &lt;em&gt;do-нотацию&lt;/em&gt;, которая помогает записывать монадические выражения в более читабельной форме и, возможно, придаёт им более императивный вид, поскольку все операции в данном случае выполняются строго последовательно. &lt;br /&gt;Запись &lt;br /&gt;&lt;pre&gt;do 
  a 
  b &lt;/pre&gt;&lt;br /&gt;аналогична записи:&lt;br /&gt;&lt;pre&gt;a &amp;gt;&amp;gt; b&lt;/pre&gt;&lt;br /&gt;Стрелка &lt;strong&gt;&amp;lt;-&lt;/strong&gt; означает, что результат выполнения парсера помещается в некоторую переменную &lt;em&gt;a&lt;/em&gt;, которая затем может использоваться далее внутри do-выражения. В частности, здесь мы используем полученную в результате строку &lt;em&gt;a&lt;/em&gt; для того, чтобы сконструировать токен Atom. Комбинатор &lt;em&gt;many1&lt;/em&gt; - производит из парсера &lt;em&gt;alphaNum&lt;/em&gt; (который различает одну букву или цифру) новый парсер, который различает одну и больше букв или цифр. &lt;br /&gt;&lt;em&gt;&amp;lt;?&amp;gt; "atom"&lt;/em&gt; - как и в прошлом примере влияет на вывод ошибок парсинга, делая его более информативным. &lt;br /&gt;&lt;em&gt;return (Atom a)&lt;/em&gt; - возвращает токен &lt;em&gt;Atom&lt;/em&gt; c лексемой &lt;em&gt;a&lt;/em&gt;, полученной в результате работы &lt;em&gt;many1 alphaNum&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;operator&lt;/em&gt; представляет собой альтернативу между несколькими символами и возвращает токен &lt;em&gt;Op&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;operator &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
operator &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  c &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; char &lt;font color="Magenta"&gt;'-'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'+'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'*'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'/'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'^'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'.'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;?&amp;gt;&lt;/font&gt; &lt;font color="Green"&gt;"operator"&lt;/font&gt;
  return &lt;font color="Blue"&gt;$&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;c&lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt;[]&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Попробуем теперь определить парсера для токена &lt;em&gt;Func&lt;/em&gt;. Его можно отличить от других токенов с помощью последующей скобки, то есть при входной строке вида "f(1) + 2",  &lt;em&gt;f&lt;/em&gt; - будет токеном &lt;em&gt;Func "f"&lt;/em&gt;, а если входная строка имеет вид "f - 1", то &lt;em&gt;f&lt;/em&gt; - это &lt;em&gt;Atom "f"&lt;/em&gt;. Таким образом в процессе парсинга нам необходимо &lt;em&gt;"заглянуть вперёд" (lookahead)&lt;/em&gt; , чтобы определить каким будет следующий токен. Данное действие можно реализовать с помощью комбинатора &lt;em&gt;lookahead&lt;/em&gt;, который не поглощает символы из входной строки, а лишь проверяет успешность работы своего парсера-аргумента.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;func &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
func &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  Atom a &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; atom
  skipMany space
  lookAhead lparen
  return &lt;font color="Blue"&gt;(&lt;/font&gt;Func a&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;В начале распознаётся Atom, затем с помощью &lt;em&gt;skipMany&lt;/em&gt; комбинатора пропускается свободное место (парсер &lt;em&gt;space&lt;/em&gt; распознаёт пробелы, табуляции и т.д.), затем проверяется успешно ли отработает парсер &lt;em&gt;lparen&lt;/em&gt; и, наконец, возвращается токен &lt;em&gt;Func&lt;/em&gt; со строкой &lt;em&gt;а&lt;/em&gt;, которую уже распознал парсер &lt;em&gt;atom&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Теперь объединим все парсеры токенов вместе - в едином парсере токенов &lt;em&gt;tok&lt;/em&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;tok &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
tok &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  t &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; try &lt;font color="Blue"&gt;(&lt;/font&gt;func&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; atom &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; operator &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; lparen &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; rparen &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; comma
  skipMany space
  return t&lt;/pre&gt;&lt;br /&gt;Здесь нам придётся использовать комбинатор &lt;em&gt;try&lt;/em&gt;, который "пробует" распарсить функцию с помощью парсера &lt;em&gt;func&lt;/em&gt;, и если у него "не получится" - нужно продолжить разбирать альтернативы. Если этого не сделать, то в случае входной строки "f + 1" парсер func начнёт парсить функцию f, однако не обнаружит скобки и выдаст ошибку, что неверно, поскольку &lt;em&gt;f&lt;/em&gt; - в данном случае &lt;em&gt;Atom&lt;/em&gt;. Таким образом, в случае сбоя парсера &lt;em&gt;func&lt;/em&gt; - необходимо продолжить парсинг с другими альтернативами, например &lt;em&gt;atom&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Наконец сформируем парсер для всего выражения:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;expression &lt;font color="Red"&gt;::&lt;/font&gt; Parser &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt;
expression &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  skipMany space
  ts &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; many1 tok
  eof
  return ts&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Здесь из нового - только парсер &lt;em&gt;eof&lt;/em&gt;, который распознаёт конец файла.&lt;br /&gt;&lt;br /&gt;Теперь нужно правильно вызывать парсер и обработать возможные ошибки:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;parse' &lt;font color="Red"&gt;::&lt;/font&gt; String &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt;
parse' s &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;case&lt;/font&gt;&lt;/u&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;parse expression &lt;font color="Green"&gt;"expr"&lt;/font&gt; s&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;of&lt;/font&gt;&lt;/u&gt;
  Left err &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; error &lt;font color="Blue"&gt;(&lt;/font&gt;show err&lt;font color="Blue"&gt;)&lt;/font&gt;
  Right x &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; x&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Делается это с помощью функции &lt;em&gt;parse&lt;/em&gt;, первый параметер которой - парсер, второй - название строки (можно оставить любым), и третий - сама строка.&lt;br /&gt;Результат её типа &lt;em&gt;Either ParserError a&lt;/em&gt; - то есть либо ошибка парсинга (&lt;em&gt;ParserError&lt;/em&gt;), либо тип возвращаемого парсером значения (то есть - некий любой тип &lt;em&gt;a&lt;/em&gt;).&lt;br /&gt;Вообще, тип &lt;em&gt;Either&lt;/em&gt; представляет значения с двумя возможностями - значение типа &lt;em&gt;Either a b&lt;/em&gt; может быть либо &lt;em&gt;Left a&lt;/em&gt;, либо &lt;em&gt;Right b&lt;/em&gt; (то есть &lt;em&gt;data Either a b = Left a | Right b&lt;/em&gt;). Иногда тип &lt;em&gt;Either&lt;/em&gt; используется для представления значения которое является либо ошибкой, либо правильным значением. Обычно, конструктор &lt;em&gt;Left&lt;/em&gt; используется для представления ошибочного значения и конструктор &lt;em&gt;Right&lt;/em&gt; для правильного (можно легко запомнить поскольку "right" означает ещё и "правильный"). &lt;br /&gt;&lt;br /&gt;Затем с помощью &lt;em&gt;case of&lt;/em&gt; мы определяем правильное или ошибочное значение получено: в случае ошибки - выводим её с помощью функции &lt;em&gt;error&lt;/em&gt;, которая выводит сообщение и останавливает вычисления, а в случаего успешного парсинга - выводим его результат. &lt;br /&gt;&lt;br /&gt;Можно сказать, что код получился вполне читабельным и несложным. Следует отметить, что в статье продемонстрированы лишь базовые возможности Parsec. &lt;br /&gt;Если говорить о его возможностях более серьёзно, то можно отметить следующее:&lt;br /&gt;- Parsec может обеспечивать разбор грамматики с бесконечным предпросмотром (&lt;em&gt;lookahead&lt;/em&gt;) с помощью комбинатора try, который обеспечивает так называемый &lt;em&gt;синтаксичечкий предпросмотр&lt;/em&gt;, но лучше всего работает с LL(1)-грамматиками;&lt;br /&gt;- как заявляет автор Parsec, он обеспечивает достаточно неплохую скорость разбора, в особенности в сравнении с другими комбинаторными парсерами;&lt;br /&gt;- выбор стандартных библиотечных парсеров весьма богат;&lt;br /&gt;- простота разработки и читабельность кода парсеров - на высоте;&lt;br /&gt;- парсер может работать на любых данных, необязательно строках. Таким образом синтаксический разбор можно производить на списках токенов, а не списках символов;&lt;br /&gt;- возможность быстрой реализации лексических анализаторов, использующих готовые схемы языков (например схема для языка Haskell или Java);&lt;br /&gt;- достаточно хорошая документация.&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;Полезные ссылки:&lt;br /&gt;&lt;a href="http://www.cs.ruu.nl/~daan/parsec.html"&gt; Parsec &lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cs.yale.edu/homes/carsten/classes/f02/handouts/MonadicParserCombinators.pdf"&gt; G.Hutton, E.Meijer "Monadic parser combinators" [PDF]&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cs.nott.ac.uk/~gmh/pearl.pdf"&gt; G.Hutton, E.Meijer "Monadic parsing in Haskell" [PDF]&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;В качестве приложения стоит привести полный код парсера.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;u&gt;&lt;font color="Green"&gt;module&lt;/font&gt;&lt;/u&gt; Main &lt;u&gt;&lt;font color="Green"&gt;where&lt;/font&gt;&lt;/u&gt;

&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; Text&lt;font color="Blue"&gt;.&lt;/font&gt;ParserCombinators&lt;font color="Blue"&gt;.&lt;/font&gt;Parsec

&lt;u&gt;&lt;font color="Green"&gt;data&lt;/font&gt;&lt;/u&gt; Token &lt;font color="Red"&gt;=&lt;/font&gt; Atom String &lt;font color="Red"&gt;|&lt;/font&gt; Op String &lt;font color="Red"&gt;|&lt;/font&gt; LParen &lt;font color="Red"&gt;|&lt;/font&gt; RParen &lt;font color="Red"&gt;|&lt;/font&gt; Comma &lt;font color="Red"&gt;|&lt;/font&gt; Func String &lt;u&gt;&lt;font color="Green"&gt;deriving&lt;/font&gt;&lt;/u&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;Eq&lt;font color="Blue"&gt;,&lt;/font&gt; Ord&lt;font color="Blue"&gt;,&lt;/font&gt; Show&lt;font color="Blue"&gt;)&lt;/font&gt;

parse' &lt;font color="Red"&gt;::&lt;/font&gt; String &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt;
parse' s &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;case&lt;/font&gt;&lt;/u&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;parse expression &lt;font color="Green"&gt;"expr"&lt;/font&gt; s&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;of&lt;/font&gt;&lt;/u&gt;
  Left err &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; error &lt;font color="Blue"&gt;(&lt;/font&gt;show err&lt;font color="Blue"&gt;)&lt;/font&gt;
  Right x &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; x

&lt;font color="Blue"&gt;-- operator token&lt;/font&gt;
operator &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
operator &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  c &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; char &lt;font color="Magenta"&gt;'-'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'+'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'*'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'/'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'^'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; char &lt;font color="Magenta"&gt;'.'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;?&amp;gt;&lt;/font&gt; &lt;font color="Green"&gt;"operator"&lt;/font&gt;
  return &lt;font color="Blue"&gt;$&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;c&lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt;[]&lt;font color="Blue"&gt;)&lt;/font&gt;

&lt;font color="Blue"&gt;-- atom token&lt;/font&gt;
atom &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
atom &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  a &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; many1 alphaNum &lt;font color="Blue"&gt;&amp;lt;?&amp;gt;&lt;/font&gt; &lt;font color="Green"&gt;"atom"&lt;/font&gt;
  return &lt;font color="Blue"&gt;(&lt;/font&gt;Atom a&lt;font color="Blue"&gt;)&lt;/font&gt;

&lt;font color="Blue"&gt;-- 1-char tokens&lt;/font&gt;
lparen &lt;font color="Red"&gt;=&lt;/font&gt;  char &lt;font color="Magenta"&gt;'('&lt;/font&gt; &lt;font color="Blue"&gt;&amp;gt;&amp;gt;&lt;/font&gt; return LParen
rparen &lt;font color="Red"&gt;=&lt;/font&gt;  char &lt;font color="Magenta"&gt;')'&lt;/font&gt; &lt;font color="Blue"&gt;&amp;gt;&amp;gt;&lt;/font&gt; return RParen
comma  &lt;font color="Red"&gt;=&lt;/font&gt;  char &lt;font color="Magenta"&gt;','&lt;/font&gt; &lt;font color="Blue"&gt;&amp;gt;&amp;gt;&lt;/font&gt; return Comma

&lt;font color="Blue"&gt;-- func token&lt;/font&gt;
func &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
func &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  Atom a &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; atom
  skipMany space
  lookAhead lparen
  return &lt;font color="Blue"&gt;(&lt;/font&gt;Func a&lt;font color="Blue"&gt;)&lt;/font&gt;

&lt;font color="Blue"&gt;-- one token&lt;/font&gt;
tok &lt;font color="Red"&gt;::&lt;/font&gt; Parser Token
tok &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  t &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; try &lt;font color="Blue"&gt;(&lt;/font&gt;func&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; atom &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; operator &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; lparen &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; rparen &lt;font color="Blue"&gt;&amp;lt;|&amp;gt;&lt;/font&gt; comma
  skipMany space
  return t

&lt;font color="Blue"&gt;-- all expression&lt;/font&gt;
expression &lt;font color="Red"&gt;::&lt;/font&gt; Parser &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt;
expression &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;do&lt;/font&gt;&lt;/u&gt;
  skipMany space
  ts &lt;font color="Red"&gt;&amp;lt;-&lt;/font&gt; many1 tok
  eof
  return ts
&lt;/pre&gt;&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:66416</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/66416.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=66416"/>
    <title>Exaile и opensource</title>
    <published>2007-05-09T14:53:03Z</published>
    <updated>2007-05-10T18:11:49Z</updated>
    <category term="python"/>
    <category term="gtk"/>
    <category term="exaile"/>
    <category term="opensource"/>
    <category term="geek"/>
    <category term="linux"/>
    <content type="html">В очередной раз убеждаюсь, что хорошая штука opensource :) &lt;br /&gt;&lt;br /&gt;Я пользуюсь Linux Ubuntu и недавно сменил основной аудио-проигрыватель с &lt;a href="http://amarok.kde.org"&gt;Amarok&lt;/a&gt; на &lt;a href="http://exaile.org"&gt;Exaile&lt;/a&gt;, поскольку Amarok, будучи KDE-приложением, несколько тормозил при запуске в моём Gnome. Exaile - является некоторым подобием Amarok под Gnome, вполне приятный плэйер, в котором есть интеграция с &lt;a href="http://last.fm"&gt;last.fm&lt;/a&gt;, неплохой менеджер артворков, нотификации, работа с мультимедийными клавишами out of the box, приятный внешний вид и т.д. После перехода я обнаружил, что некоторых мелочей мне не хватает и решил сделать их сам. &lt;br /&gt;Что же, получаем исходный код для разработчиков: &lt;pre class="wiki"&gt;svn co svn://exaile.org/usr/local/svn/exaile/trunk trunk&lt;/pre&gt; и вперёд! :) Заодно познакомлюсь с Python и GTK. &lt;br /&gt;&lt;br /&gt;Захожу на канал &lt;i&gt;#exaile&lt;/i&gt; в IRC, знакомлюсь с одним из двух разработчиков Exaile - sjohannes, пытаюсь задавать какие-то вопросы. В принципе ребята на вопросы отвечают, но помогать в разборе кода особенно не хотят. Что ж, посмотрю сам.&lt;br /&gt;&lt;br /&gt;Поначалу я реализовал простенькую фичу. Заключалась она в добавлении возможности "Load", которая параллельно очищала плэйлист и добавляла в него выбранный трек или альбом: добавил menu item "Load" в контекстное меню, навесил на него обработчик. В итоге всё вылилось в такой вот &lt;a href="http://exaile.org/trac/ticket/459"&gt;ticket&lt;/a&gt; с патчем.&lt;br /&gt;Особого успеха у sjohannes этот патч не имел -  сказал, что не думает что это особенно нужная функциональность, но, тем не менее, на следующий день пришло письмо от некоего благодарного пользователя, так что хоть кому-то он да понадобился :)&lt;br /&gt;&lt;br /&gt;Вторая же возможность, которую я добавил, была навеяна похожей функциональностью Eclipse IDE и сразу понравилась разработчикам. Я говорю о возможности &lt;i&gt;"Show in collection"&lt;/i&gt;, которая может быть полезна при желании быстро перейти от трека в плэйлисте к соответствующему треку в коллекции (это важно при прослушивании случайных треков, при этом иногда хочется послушать полностью ту группу, которая только что играла и, как следствие, нужно искать её в коллекции, что возможность делает автоматически). В Eclipse этой возможности соответствует переход от текущего редактируемого файла к его ноде в дереве проекта. В итоге, я сделал ещё один &lt;a href="http://exaile.org/trac/ticket/467"&gt;патч&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Эта идея и её реализация уже гораздо больше впечатлила sjohannes, и он сказал, что непременно включит её в следующий релиз (см. UPDATE). Что ж, буду рад :)&lt;br /&gt;&lt;br /&gt;Хочется отметить, что Python, как и обещалось многими, оказался действительно интуитивно понятным языком, с хорошим синтаксисом. Практически все вещи, что я делал почти наобум - работали именно так, как полагалось. Мне кажется, что это весьма важное качество языка - works as expected. Насчёт GTK и биндингов под Python - pyGTK, тоже ничего плохого сказать не могу, хорошая документация, поработал с деревом и его моделью без особенных проблем. Хотя здесь, конечно, моё мнение весьма поверхностно и сравнивать мне не с чем, ибо я никогда не занимался разработкой GUI под Linux. &lt;br /&gt;&lt;br /&gt;Резюмируя, можно сказать, что теперь я на собственном опыте прочувствовал один из плюсов открытых исходных текстов - при определённой квалификации и желании можно достаточно просто реализовать нужные и вполне полезные вещи и, возможно, донести их другим, что не может не радовать.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE:&lt;/b&gt; Функциональность "Show in collection" добавили в Exaile в ревизии 2358 (&lt;i&gt;"svn log -r 2358"&lt;/i&gt;).</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:66108</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/66108.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=66108"/>
    <title>Haskell Postfix: часть первая. Операторы. Вычислитель постфиксных выражений на Haskell.</title>
    <published>2007-05-03T12:27:11Z</published>
    <updated>2008-11-22T21:38:43Z</updated>
    <category term="it"/>
    <category term="haskell"/>
    <category term="geek"/>
    <content type="html">Недавно я встретил упоминание ещё об одном сайте, предлагающем разные математические и программистские задачи. Это &lt;em&gt;Sphere Online Judge&lt;/em&gt; (&lt;a href="http://spoj.pl"&gt;http://spoj.pl&lt;/a&gt;). От популярного нынче &lt;em&gt;"Проекта Эйлера" &lt;/em&gt;(&lt;a href="http://projecteuler.net"&gt;http://projecteuler.net&lt;/a&gt;) отличается тем, что вводятся не ответы на задачи, а на сервер загружается сам код, который там компилируется и запускается на тестовых примерах. Решение одной из задач этого контеста привело к довольно интересным для меня результатам, о которых я решил написать небольшой цикл статей.&lt;br /&gt;&lt;br /&gt;Некоторое время думал для кого писать эти статьи и какова их цель. Наверное, их будет интересно прочитать людям, желающим познакомиться с функциональным языком программирования Haskell без особого углубления в теорию, а также тем, кто просто интересуется математикой, языками программирования, всякого рода парсингом и прочими околоакадемическими вещами. Уровень изложения материала - весьма доступный, надеюсь многое будет понятно людям, не особенно знакомым с функциональными языками программирования.&lt;br /&gt;&lt;br /&gt;Содержание статей будет примерно таким:&lt;br /&gt;1. Формы записи операторов (инфиксная, префиксная, постфиксная). Реализация на языке Haskell простого вычислителя арифметических выражений, записанных в постфиксной форме.&lt;br /&gt;2. Преобразование инфиксной формы в постфиксную. Алгоритм "сортировочная станция" Дейкстры. Транслятор на Haskell. Использование комбинаторных парсеров Parsec для разбора выражения.&lt;br /&gt;3. Реализация более полного эвалуатора, вычисляющего как арифметические выражения, так и функции. &lt;br /&gt;4. Переход от вычисления значения выражения к вычислению типа выражения. Последствия в виде использования в реальной жизни для вывода типов выражения в ActionScript 3. &lt;br /&gt;&lt;br /&gt;Тех, кому интересно - прошу к прочтению первой части :)&lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;&lt;div align="center"&gt;Haskell Postfix: часть первая. Операторы. Вычислитель постфиксных выражений на Haskell.&lt;/div&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Формы записи операторов представляют собой способ для записи математических выражений в виде линейной последовательности токенов (самих операторов и их операндов). Можно выделить такие основные формы записи:&lt;br /&gt;&lt;ul&gt; &lt;br /&gt;&lt;li&gt;&lt;em&gt;префиксная&lt;/em&gt;, оператор записывается перед своими операндами, например "+ 1 2".&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;em&gt;постфиксная&lt;/em&gt;, оператор записывается после своих операндов, например "1 2 +".   Такую форму ещё называют обратной польской записью или "полиз" (сокращение от "польская инверсная запись"). Польской она называется потому, что впервые была предложена польским математиком Лукасевичем.&lt;/li&gt; &lt;br /&gt;&lt;li&gt;&lt;em&gt;инфиксная&lt;/em&gt;, оператор записывается между своими аргументами, например привычное "1 + 2". Здесь стоит отметить, что инфиксная запись может применятьcя не только с бинарными операторами, пример тому - запись тернарного оператора (?:) из С.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Рассмотрим постфиксную нотацию. Она удобна тем, что на момент появления операции все операнды уже определены, поэтому остаётся лишь применить операцию. Вычисления проводятся с помощью стека, то есть операнды достаются из стека и затем результат операции помещается в стек вместо них. Например, предположим, что надо вычислить выражение &lt;strong&gt;4 1 - 2 * &lt;/strong&gt;, то есть &lt;strong&gt;(4 - 1) * 2&lt;/strong&gt; в обычной инфиксной записи. Действия и состяние стека в процессе выполнения алгоритма показаны в таблице:&lt;br /&gt;&lt;br /&gt;&lt;table align="center" border="1"&gt; 
&lt;tr align="center"&gt;
	&lt;th&gt; Входной &lt;br&gt; символ &lt;/th&gt;
	&lt;th&gt; Действие &lt;/th&gt;
	&lt;th&gt; Стек &lt;/th&gt;
&lt;/tr&gt;&lt;tr&gt;
	&lt;td&gt; 4 &lt;/td&gt;
	&lt;td&gt; Кладём в стек &lt;/td&gt;
	&lt;td&gt; 4 &lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
	&lt;td&gt; 1 &lt;/td&gt;
	&lt;td&gt; Кладём в стек &lt;/td&gt;
	&lt;td&gt; 4 1 &lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
	&lt;td&gt; - &lt;/td&gt;
	&lt;td&gt; Извлекаем из стека два операнда, &lt;br&gt; применяем операцию "-", &lt;br&gt; кладём результат обратно &lt;/td&gt;
	&lt;td&gt; 3 &lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
	&lt;td&gt; 2 &lt;/td&gt;
	&lt;td&gt; Кладём в стек&lt;/td&gt;
	&lt;td&gt; 3 2 &lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
	&lt;td&gt; * &lt;/td&gt;
	&lt;td&gt; Извлекаем из стека два операнда, &lt;br&gt; применяем операцию "*", &lt;br&gt; кладём результат обратно &lt;/td&gt;
	&lt;td&gt; 6 &lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
	&lt;td&gt;  &lt;/td&gt;
	&lt;td&gt; Входные символы закончились, &lt;br&gt; берём из стека ответ и выдаём его &lt;/td&gt;
	&lt;td&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Ещё одним плюсом такой записи является ненужность скобок и приоритетов операций.&lt;br /&gt;&lt;br /&gt;Запишем реализацию этого простого алгоритма с помощью Haskell. Для простоты предположим, что все токены отделены разделены пробелами, то есть входная строка представляется в виде "6 1 3 - 4 * +".&lt;br /&gt;Подумаем, что нам нужно сделать для написания программы:&lt;br /&gt;1. Определить тип токена, который мы будем использовать для представления операндов и операторов.&lt;br /&gt;2. Преобразовать входную строку в список токенов.&lt;br /&gt;3. Вычислить выражение, определённое данными токенами.&lt;br /&gt;4. Обеспечить операции ввода-вывода.&lt;br /&gt;&lt;br /&gt;Для начала назовём нашу программу и импортируем полезные модули. &lt;em&gt;IO&lt;/em&gt; - для ввода/вывода, &lt;em&gt;Data.Map&lt;/em&gt; - ассоциативный массив, &lt;em&gt;Maybe&lt;/em&gt; - для представления результатов вычислений, которые могут не вернуть ожидаемый результат - например поиск по ключу в Map.&lt;br /&gt;&lt;pre&gt;
&lt;u&gt;&lt;font color="Green"&gt;module&lt;/font&gt;&lt;/u&gt; Main &lt;u&gt;&lt;font color="Green"&gt;where&lt;/font&gt;&lt;/u&gt;
&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; IO
&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; Maybe
&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; &lt;u&gt;&lt;font color="Green"&gt;qualified&lt;/font&gt;&lt;/u&gt; Data&lt;font color="Blue"&gt;.&lt;/font&gt;Map &lt;u&gt;&lt;font color="Green"&gt;as&lt;/font&gt;&lt;/u&gt; M&lt;/pre&gt;&lt;br /&gt;Теперь определим тип токена - &lt;strong&gt;Token&lt;/strong&gt;, который обладает двумя конструкторами типа - &lt;strong&gt;Atom Int&lt;/strong&gt; (принимает на вход целое число) для представления чисел и &lt;strong&gt;Op (Int -&amp;gt; Int -&amp;gt; Int)&lt;/strong&gt; (принимает на вход бинарный оператор, то есть функцию с двумя параметрами, работающую с целыми числами). Таким образом токены можно будет создавать таким образом: &lt;em&gt;Atom 7&lt;/em&gt;, &lt;em&gt;Atom 0&lt;/em&gt;,&lt;em&gt; Op (+)&lt;/em&gt;, &lt;em&gt;Op (-)&lt;/em&gt; и т.д.&lt;br /&gt;&lt;pre&gt;
&lt;u&gt;&lt;font color="Green"&gt;data&lt;/font&gt;&lt;/u&gt; Token &lt;font color="Red"&gt;=&lt;/font&gt; Atom Int &lt;font color="Red"&gt;|&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;Int &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;Определим теперь соответствие между текстовым представлением поддерживаемых операторов и токенами. Сделаем это в виде карты (&lt;em&gt;Map&lt;/em&gt;), где ключом будет строка, а значением - соответствующий токен:&lt;br /&gt;&lt;pre&gt;operatorsTable &lt;font color="Red"&gt;::&lt;/font&gt; M&lt;font color="Blue"&gt;.&lt;/font&gt;Map String Token
operatorsTable &lt;font color="Red"&gt;=&lt;/font&gt; M&lt;font color="Blue"&gt;.&lt;/font&gt;fromList &lt;font color="Red"&gt;[&lt;/font&gt;
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"+"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;+&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt;
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"-"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;-&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt;
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"*"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;*&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt;
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"/"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op div&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt;
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"^"&lt;/font&gt;&lt;font clor="Blue"&gt;,&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;^&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Red"&gt;]&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;Первая строчка описывает тип функции, почти всегда его можно опустить, поскольку компилятор во многих случаях сам может вывести нужные типы, однако программу легче читать имея под рукой типы функций.&lt;br /&gt;&lt;br /&gt;Теперь попробуем получить список токенов из входной строки. Поскольку мы предложили, что токены будут разделены с помощью whitespace, то мы можем воспользоваться стандартной функцией &lt;em&gt;words&lt;/em&gt;, которая разбивает строку на список строк используя в качестве разделителя whitespace. Затем применим к каждой полученной строке функцию &lt;em&gt;parseToken&lt;/em&gt;, которая парсит отдельно взятый токен. Сделать это можно с помощью функции &lt;em&gt;map&lt;/em&gt;, которая принимает на вход два аргумента: некую функцию и список, и затем применяет указанную функцию к каждому элементу списка. Например получить квадраты первых трёх натуральных чисел можно так:&lt;br /&gt;&lt;pre&gt;  map (^2) [1, 2, 3] = [1, 4, 9] &lt;/pre&gt;&lt;br /&gt;Точка же означает &lt;a href="http://en.wikipedia.org/wiki/Function_composition_%28computer_science%29"&gt; композицию функций &lt;/a&gt;, т.е. &lt;i&gt; (f . g) x = f (g x) &lt;/i&gt;&lt;br /&gt;Почитать о &lt;em&gt;map&lt;/em&gt; и других базовых функциях для работы со списками немного более подробно можно &lt;a href="http://en.wikibooks.org/wiki/Haskell/YAHT/Language_basics#Simple_List_Functions"&gt;здесь&lt;/a&gt;.&lt;br /&gt;Таким образом, мы применяем &lt;em&gt;map parseToken&lt;/em&gt; к результату полученному от &lt;em&gt;words&lt;/em&gt;.&lt;pre&gt;
parse &lt;font color="Red"&gt;::&lt;/font&gt; String &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt;
parse &lt;font color="Red"&gt;=&lt;/font&gt; map parseToken &lt;font color="Blue"&gt;.&lt;/font&gt; words&lt;/pre&gt;&lt;br /&gt;Сама функция &lt;em&gt;parseToken&lt;/em&gt; работает так: мы смотрим (&lt;em&gt;lookup&lt;/em&gt;) в нашу таблицу операторов в поисках оператора по строке. Если мы находим его ('&lt;em&gt;Just op&lt;/em&gt;'-ветка case-выражения), то возвращаем, если же нет (&lt;em&gt;Nothing&lt;/em&gt;), то считаем что это число и создаём новый токен &lt;em&gt;Atom&lt;/em&gt; и заносим туда число, которое преобразуем из строки функцией &lt;em&gt;read&lt;/em&gt;.&lt;br /&gt;&lt;pre&gt;
parseToken &lt;font color="Red"&gt;::&lt;/font&gt; String &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Token
parseToken t &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;case&lt;/font&gt;&lt;/u&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;M&lt;font color="Blue"&gt;.&lt;/font&gt;lookup t operatorsTable&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;of&lt;/font&gt;&lt;/u&gt;
  Just op &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; op
  Nothing &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Atom &lt;font color="Blue"&gt;(&lt;/font&gt;read t&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Теперь нам необходимо реализовать главную часть алгоритма - вычисление выражений на основе стека. Реализуем это в виде функции &lt;em&gt;evaluate&lt;/em&gt;, которая принимает на вход список токенов, который может быть получен от функции &lt;em&gt;parse&lt;/em&gt; и выдаёт результат - целое число.&lt;br /&gt;&lt;br /&gt;Для вычисления будем использовать промежуточную функцию &lt;em&gt;evaluate'&lt;/em&gt;. Кавычка, которая часто читается как "штрих", является обычным символом языка, часто используется для того, чтобы показать что одна функция является вспомогательной функцией другой, или что две функции выполняют похожие действия.&lt;br /&gt;У функции &lt;em&gt;evaluate'&lt;/em&gt; появляется дополнительный параметр - стек, представленный в виде списка целых чисел. Таким образом тип этой функции &lt;strong&gt;[Token] -&amp;gt; [Int] -&amp;gt; Int&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt; [Token]&lt;/strong&gt; - список токенов, которые ещё нужно "посчитать"&lt;br /&gt;&lt;strong&gt; [Int]&lt;/strong&gt; - стек, в который кладутся числа&lt;br /&gt;и возвращает она результат вычислений - &lt;strong&gt;Int&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;В начале стек пуст, потому изначально мы вызываем &lt;em&gt;evaluate'&lt;/em&gt; с пустым списком в качестве второго параметра.&lt;br /&gt;&lt;pre&gt;
evaluate &lt;font color="Red"&gt;::&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int
evaluate tokens &lt;font color="Red"&gt;=&lt;/font&gt; evaluate' tokens []
&lt;/pre&gt;&lt;br /&gt;Теперь нужно производить различные действия в зависимости от того какой токен поступает на вход. Можно, конечно, реализовать это обычным if-ом, но в Haskell есть гораздо более мощный и изящный инструмент - сопоставление с образцом (&lt;a href="http://en.wikipedia.org/wiki/Pattern_matching"&gt;pattern matching&lt;/a&gt;). Работает он так: мы пишем несколько определений функции (pattern-ов) для различных наборов параметров и, сопоставив, компилятор сам сможет определить какой из вариантов подходит (matching).&lt;br /&gt;&lt;br /&gt;Например safe функцию деления можно определить так:&lt;br /&gt;&lt;pre&gt;
 myDivision x 0 = error "division by zero!"
 myDivision x y = x / y
&lt;/pre&gt;&lt;br /&gt;При вызове &lt;em&gt;myDivision 4 2&lt;/em&gt;, компилятор выберет второе определение (поскольку сопоставление &lt;em&gt;x = 4, 0 = 2&lt;/em&gt; не подходит), а сопоставление (&lt;em&gt;x = 4 , y = 2&lt;/em&gt;) - вполне. Кроме того,  при сопоставлении производится и означивание параметров, то есть &lt;em&gt;x&lt;/em&gt; станет равным 4, а &lt;em&gt;y = 2&lt;/em&gt;. В качестве образцов для параметров можно применять и более сложные конструкции, например рассмотрим классическое рекурсивное нахождение длины списка:&lt;br /&gt;&lt;pre&gt;
 myLength [] = 0
 myLength (x:xs) = 1 + myLength xs
&lt;/pre&gt;&lt;br /&gt;здесь мы пытаемся сопоставить параметр сначала с пустым списком, если это так - то его длина равна 0, а затем с непустым, при этом в &lt;em&gt;x&lt;/em&gt; - помещается голова списка, а в &lt;em&gt;xs&lt;/em&gt; - его хвост, и длина будет равна длине хвоста + 1. Операция &lt;em&gt;(:)&lt;/em&gt; в &lt;em&gt;(x:xs)&lt;/em&gt; означает "сцепление" головы с хвостом. Конечно, вторую строку можно записать и так: &lt;br /&gt;&lt;pre&gt;
 myLength list = 1 + myLength (tail list)
&lt;/pre&gt;&lt;br /&gt;где &lt;em&gt;tail list&lt;/em&gt; - определяет хвост списка, но такой вариант гораздо менее изящен :)&lt;br /&gt;&lt;br /&gt;Что же, вооружившись знаниями о pattern matching, можно весьма эффективно записать функцию &lt;em&gt;evaluate'&lt;/em&gt;. Нас интересует несколько случаев:&lt;br /&gt;1) входной список токенов завершился&lt;br /&gt;2) во входном списке - оператор &lt;em&gt;Op&lt;/em&gt;&lt;br /&gt;3) во входном списке - число &lt;em&gt;Atom&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;В первом случаем нам необходимо вернуть вершину стека как результат:&lt;br /&gt;&lt;pre&gt;
evaluate' &lt;font color="Red"&gt;::&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Int&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int
evaluate' [] &lt;font color="Red"&gt;[&lt;/font&gt;x&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; x&lt;/pre&gt;&lt;br /&gt;Во втором - необходимо взять два операнда из стека, произвести операцию &lt;em&gt;op&lt;/em&gt; над ними и результат снова поместить в стек. Извлечение из стека можно сделать с помощью &lt;em&gt;pattern matching&lt;/em&gt;, второй параметр имеет вид &lt;em&gt;(x1 : x2 : s)&lt;/em&gt;, таким образом в &lt;em&gt;x1&lt;/em&gt; и &lt;em&gt;x2&lt;/em&gt; - попадут нужные нам два верхних аргумента, а в &lt;em&gt;s&lt;/em&gt; - будет находиться остаток стека. Затем мы производим операцию над ними &lt;em&gt;(op x2 x1)&lt;/em&gt;  и добавляем результат к стеку. Затем снова вызываем функцию &lt;em&gt;evaluate'&lt;/em&gt; для остатка входного списка токенов и с модифицированным стеком.&lt;br /&gt;&lt;pre&gt;
evaluate' &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;(&lt;/font&gt;Op op &lt;font color="Blue"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; xs&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;x1 &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; x2 &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; s&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; evaluate' xs &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;(&lt;/font&gt;op x2 x1&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; s&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;В третьем случае - нужно просто переместить число из входного потока в стек:&lt;br /&gt;&lt;pre&gt;
evaluate' &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;(&lt;/font&gt;Atom n&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; xs&lt;font color="Blue"&gt;)&lt;/font&gt; s &lt;font color="Red"&gt;=&lt;/font&gt; evaluate' xs &lt;font color="Blue"&gt;(&lt;/font&gt;n &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; s&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;Во всех остальных случаях - выдаём ошибку, они значат, что выражение было неправильным (заданы не все операнды, остаток в стеке после выполнения всех операций и т.д.). Для того, что механизм pattern matching обязательно попал в этот образец можно воспользоваться "ничего не значащей" переменной "подчёркивание" _, которая матчится в любом случае.&lt;br /&gt;&lt;pre&gt;
evaluate' &lt;u&gt;&lt;font color="Green"&gt;_&lt;/font&gt;&lt;/u&gt; &lt;u&gt;&lt;font color="Green"&gt;_&lt;/font&gt;&lt;/u&gt; &lt;font color="Red"&gt;=&lt;/font&gt; error &lt;font color="Green"&gt;"Error in evaluating: incorrect expression"&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;Теперь ввод-вывод. Сделаем мы его с помощью магической функции &lt;em&gt;interact&lt;/em&gt;, которая работает следующим образом: считываем из &lt;em&gt;stdin&lt;/em&gt; ввод, применяет к нему некоторую функцию и выводит результат в &lt;em&gt;stdout&lt;/em&gt;. Таким образом, например, для того чтобы просто вывести ввод можно сделать так:&lt;br /&gt;&lt;pre&gt; main = interact id &lt;/pre&gt;&lt;br /&gt;где &lt;em&gt;id&lt;/em&gt; - функция которая просто ничего не делает со своим аргументом.&lt;br /&gt;Нам же надо кое-что сделать, а именно: разбить ввод на строки стандартной функцией &lt;em&gt;lines&lt;/em&gt;, каждую из строк распарсить нашей функцией &lt;em&gt;parse&lt;/em&gt;, затем вычислить с помощью &lt;em&gt;evaluate&lt;/em&gt;, отобразить результат с помощью &lt;em&gt;show&lt;/em&gt;. Затем все строки скрепить воедино функцией &lt;em&gt;unlines&lt;/em&gt;, а потом можно и выводить. Весь этот набор реализуется такой вот строчкой:&lt;br /&gt;&lt;pre&gt;
main &lt;font color="Red"&gt;=&lt;/font&gt; interact &lt;font color="Blue"&gt;(&lt;/font&gt;unlines &lt;font color="Blue"&gt;.&lt;/font&gt; map &lt;font color="Blue"&gt;(&lt;/font&gt;show &lt;font color="Blue"&gt;.&lt;/font&gt; evaluate &lt;font color="Blue"&gt;.&lt;/font&gt; parse&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Blue"&gt;.&lt;/font&gt; lines&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;Программа готова. Можно сохранить её как &lt;em&gt;pf-eval.hs&lt;/em&gt; и запустить в интерпретаторе Haskell с помощью&lt;br /&gt;&lt;pre&gt;ghci pf-eval.hs&lt;/pre&gt;&lt;br /&gt;или же скомпилировать командой&lt;br /&gt;&lt;pre&gt;ghc --make pf-eval.hs&lt;/pre&gt;&lt;br /&gt;и затем запускать исполняемый файл, подавая ему на вход строки для эвалуации.&lt;br /&gt;&lt;br /&gt;Пример работы программы:&lt;br /&gt;&lt;pre&gt;
sphynx@behexen:~/haskell$ ghc --make pf-eval.hs
[1 of 1] Compiling Main             ( pf-eval.hs, pf-eval.o )
Linking pf-eval ...

sphynx@behexen:~/haskell$ ./pf-eval
1 2 +
3
2 5 1 - ^ 2 * 3 +
35
1 + +
pf-eval: Error in evaluating: incorrect expression
&lt;/pre&gt;&lt;br /&gt;Таким образом мы сделали необходимый эвалуатор. В следующей части мы реализуем преобразование выражений, записанных в инфиксной форме в постфиксную, а также усовершенствуем наш парсер, использовав стандартную библиотеку Parsec языка Haskell. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Ваши замечания, вопросы и пожелания - приветствуются!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Полезные ссылки:&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Pattern_matching"&gt; Механизм pattern matching &lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Reverse_Polish_notation"&gt; Постфиксная запись операторов &lt;a&gt;&lt;br /&gt;&lt;a href="http://haskell.org"&gt;Сайт языка Haskell &lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikibooks.org/wiki/Haskell/YAHT/"&gt;Неплохой учебник по Haskell&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;В конце, для удобства, я приведу полный код программы. Как можно видеть, она получилась вполне компактной. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;u&gt;&lt;font color="Green"&gt;module&lt;/font&gt;&lt;/u&gt; Main &lt;u&gt;&lt;font color="Green"&gt;where&lt;/font&gt;&lt;/u&gt;

&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; IO
&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; Maybe
&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; &lt;u&gt;&lt;font color="Green"&gt;qualified&lt;/font&gt;&lt;/u&gt; Data&lt;font color="Blue"&gt;.&lt;/font&gt;Map &lt;u&gt;&lt;font color="Green"&gt;as&lt;/font&gt;&lt;/u&gt; M

&lt;u&gt;&lt;font color="Green"&gt;data&lt;/font&gt;&lt;/u&gt; Token &lt;font color="Red"&gt;=&lt;/font&gt; Atom Int &lt;font color="Red"&gt;|&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;Int &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int&lt;font color="Blue"&gt;)&lt;/font&gt;

operatorsTable &lt;font color="Red"&gt;::&lt;/font&gt; M&lt;font color="Blue"&gt;.&lt;/font&gt;Map String Token
operatorsTable &lt;font color="Red"&gt;=&lt;/font&gt; M&lt;font color="Blue"&gt;.&lt;/font&gt;fromList &lt;font color="Red"&gt;[&lt;/font&gt; 
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"+"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;+&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; 
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"-"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;-&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; 
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"*"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;*&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; 
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"/"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op div&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt;
  &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Green"&gt;"^"&lt;/font&gt;&lt;font color="Blue"&gt;,&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;^&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Red"&gt;]&lt;/font&gt;

parse &lt;font color="Red"&gt;::&lt;/font&gt; String &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt;
parse &lt;font color="Red"&gt;=&lt;/font&gt; map parseToken &lt;font color="Blue"&gt;.&lt;/font&gt; words

parseToken &lt;font color="Red"&gt;::&lt;/font&gt; String &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Token
parseToken t &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;case&lt;/font&gt;&lt;/u&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;M&lt;font color="Blue"&gt;.&lt;/font&gt;lookup t operatorsTable&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;of&lt;/font&gt;&lt;/u&gt;
  Just op &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; op
  Nothing &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Atom &lt;font color="Blue"&gt;(&lt;/font&gt;read t&lt;font color="Blue"&gt;)&lt;/font&gt;

evaluate &lt;font color="Red"&gt;::&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int
evaluate tokens &lt;font color="Red"&gt;=&lt;/font&gt; evaluate' tokens []

evaluate' &lt;font color="Red"&gt;::&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Token&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; &lt;font color="Red"&gt;[&lt;/font&gt;Int&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int
evaluate' [] &lt;font color="Red"&gt;[&lt;/font&gt;x&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; x
evaluate' &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;(&lt;/font&gt;Op op &lt;font color="Blue"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; xs&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;x1 &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; x2 &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; s&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; evaluate' xs &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;(&lt;/font&gt;op x2 x1&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; s&lt;font color="Blue"&gt;)&lt;/font&gt;
evaluate' &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;(&lt;/font&gt;Atom n&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; xs&lt;font color="Blue"&gt;)&lt;/font&gt; s &lt;font color="Red"&gt;=&lt;/font&gt; evaluate' xs &lt;font color="Blue"&gt;(&lt;/font&gt;n &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; s&lt;font color="Blue"&gt;)&lt;/font&gt;
evaluate' &lt;u&gt;&lt;font color="Green"&gt;_&lt;/font&gt;&lt;/u&gt; &lt;u&gt;&lt;font color="Green"&gt;_&lt;/font&gt;&lt;/u&gt; &lt;font color="Red"&gt;=&lt;/font&gt; error &lt;font color="Green"&gt;"Error in evaluating: incorrect expression"&lt;/font&gt;

main &lt;font color="Red"&gt;=&lt;/font&gt; interact &lt;font color="Blue"&gt;(&lt;/font&gt;unlines &lt;font color="Blue"&gt;.&lt;/font&gt; map &lt;font color="Blue"&gt;(&lt;/font&gt;show &lt;font color="Blue"&gt;.&lt;/font&gt; evaluate &lt;font color="Blue"&gt;.&lt;/font&gt; parse&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Blue"&gt;.&lt;/font&gt; lines&lt;font color="Blue"&gt;)&lt;/font&gt;
&lt;/pre&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;b&gt;UPDATE:&lt;/b&gt;&lt;br /&gt;Задавшись целью сократить размер программы, с учётом упрощений и замечаний, высказанных в комментариях, можно получить такой результат, ещё более компактный:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;u&gt;&lt;font color="Green"&gt;module&lt;/font&gt;&lt;/u&gt; Main &lt;u&gt;&lt;font color="Green"&gt;where&lt;/font&gt;&lt;/u&gt;

&lt;u&gt;&lt;font color="Green"&gt;import&lt;/font&gt;&lt;/u&gt; IO

&lt;u&gt;&lt;font color="Green"&gt;data&lt;/font&gt;&lt;/u&gt; Token &lt;font color="Red"&gt;=&lt;/font&gt; Atom Int &lt;font color="Red"&gt;|&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;Int &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; Int&lt;font color="Blue"&gt;)&lt;/font&gt;

parse &lt;font color="Red"&gt;=&lt;/font&gt; map parseToken &lt;font color="Blue"&gt;.&lt;/font&gt; words 

parseToken &lt;font color="Green"&gt;"+"&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;+&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;
parseToken &lt;font color="Green"&gt;"-"&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;-&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;
parseToken &lt;font color="Green"&gt;"*"&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; Op &lt;font color="Blue"&gt;(&lt;/font&gt;&lt;font color="Blue"&gt;*&lt;/font&gt;&lt;font color="Blue"&gt;)&lt;/font&gt;
parseToken &lt;font color="Green"&gt;"/"&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; Op div
parseToken t   &lt;font color="Red"&gt;=&lt;/font&gt; Atom &lt;font color="Blue"&gt;(&lt;/font&gt;read t&lt;font color="Blue"&gt;)&lt;/font&gt;

evaluate ts &lt;font color="Red"&gt;=&lt;/font&gt; &lt;u&gt;&lt;font color="Green"&gt;case&lt;/font&gt;&lt;/u&gt; foldl foldF [] ts &lt;u&gt;&lt;font color="Green"&gt;of&lt;/font&gt;&lt;/u&gt;
	&lt;font color="Red"&gt;[&lt;/font&gt;x&lt;font color="Red"&gt;]&lt;/font&gt; &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; x
	&lt;u&gt;&lt;font color="Green"&gt;_&lt;/font&gt;&lt;/u&gt;   &lt;font color="Red"&gt;-&amp;gt;&lt;/font&gt; error &lt;font color="Green"&gt;"incorrect expression!"&lt;/font&gt;

foldF &lt;font color="Blue"&gt;(&lt;/font&gt;x1&lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt;x2&lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt;stack&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;Op op&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; &lt;font color="Blue"&gt;(&lt;/font&gt;op x2 x1&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; stack
foldF stack &lt;font color="Blue"&gt;(&lt;/font&gt;Atom n&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Red"&gt;=&lt;/font&gt; n &lt;b&gt;&lt;font color="Red"&gt;:&lt;/font&gt;&lt;/b&gt; stack

main &lt;font color="Red"&gt;=&lt;/font&gt; interact &lt;font color="Blue"&gt;(&lt;/font&gt;unlines &lt;font color="Blue"&gt;.&lt;/font&gt; map &lt;font color="Blue"&gt;(&lt;/font&gt;show &lt;font color="Blue"&gt;.&lt;/font&gt; evaluate &lt;font color="Blue"&gt;.&lt;/font&gt; parse&lt;font color="Blue"&gt;)&lt;/font&gt; &lt;font color="Blue"&gt;.&lt;/font&gt; lines&lt;font color="Blue"&gt;)&lt;/font&gt;
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/a&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:65652</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/65652.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=65652"/>
    <title>Равны ли 0,(9) и 1? Периодические дроби.</title>
    <published>2007-03-27T20:53:33Z</published>
    <updated>2007-04-01T09:07:18Z</updated>
    <content type="html">&lt;em&gt;Отвечавшим на мою анкету и думавшим над вопросом про 0,(9) посвящается :)&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://infostore.org/file/2951363/2458103/300px-999_Perspective.png"&gt;&lt;br /&gt;&lt;br /&gt;Как-то сидели мы с &lt;span class='ljuser  ljuser-name_martreya' lj:user='martreya' style='white-space: nowrap;'&gt;&lt;a href='http://martreya.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://martreya.livejournal.com/'&gt;&lt;b&gt;martreya&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, &lt;span class='ljuser  ljuser-name_iiryna' lj:user='iiryna' style='white-space: nowrap;'&gt;&lt;a href='http://iiryna.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://iiryna.livejournal.com/'&gt;&lt;b&gt;iiryna&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; и &lt;span class='ljuser  ljuser-name_deadvom' lj:user='deadvom' style='white-space: nowrap;'&gt;&lt;a href='http://deadvom.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://deadvom.livejournal.com/'&gt;&lt;b&gt;deadvom&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; в пиццерии и мне почему-то пришёл в голову вопрос, который я позже задавал в &lt;a href="http://dying-sphynx.livejournal.com/65093.html?mode=reply"&gt;анкете&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Равны ли числа 0,(9) и 1?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Вопрос этот, наверное, несколько странный и многих, особенно нематематиков, может удивить и ответа на него не будет. &lt;br /&gt;Мне здесь хочется немного прояснить свои и не только свои соображения по этому поводу. Начну издалека. &lt;br /&gt;&lt;br /&gt;Как мы знаем, число - это одно из основополагающих понятий математики, мир чисел постоянно пополнялся на протяжении развития человечества. В первом классе мы изучали самые первые числа: 1, 2, 3... Эти числа называются &lt;em&gt;натуральными&lt;/em&gt;, и их множество обозначается буквой &lt;em&gt;N&lt;/em&gt;. В рамках этих чисел можно отлично выполнять операции сложения и умножения. Если же мы захотим применять вычитание, то из подсознания выплывает фраза вроде "Из 2 яблок нельзя вычесть 4" или что-то в этом духе. Таким образом, мы получаем какие-то ограничения, которые расширяются введением отрицательных чисел. Множество всех отрицательных и положительных чисел называется множеством &lt;em&gt;целых&lt;/em&gt; чисел и обозначается буквой &lt;em&gt;Z&lt;/em&gt;. В рамках этих чисел отрицание уже выполняется без всяких проблем (2 - 4 = -2). &lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;Следующей общеизвестной арифметической операцией является деление. Если поделить 1 на 2, то получится число &lt;em&gt;не&lt;/em&gt; из множества целых чисел. Таким образом, снова придётся расширять известные числа, чтобы вместить результаты и этой операции. Числа которые представимы в виде частного, то есть дроби &lt;em&gt;m / n&lt;/em&gt; (m - числитель, n - знаменатель) - называются &lt;em&gt;рациональными&lt;/em&gt; числами (множество &lt;em&gt;Q&lt;/em&gt;). По своей сути, дроби - это как раз и есть рациональные числа, то есть обыкновенная дробь представляет собой частное, а результат деления числителя на знаменатель и есть рациональное число. Опять же, вспомнинаем школу и на ум приходят задачи типа "сложить треть яблока с половиной яблока" и некоторые проблемы, возникающие при сложении дробей. Проблема состояла в том, что их надо было приводить к общему знаменателю (то есть 1/3 + 1/2 = 3/6 + 2/6 = 5/6), поскольку складывать без проблем можно было только дроби с одинаковым знаменателем. Соответственно, для того, чтобы от этих проблем избавиться, и из-за того, что у нас принята десятичная система счисления, были введены &lt;em&gt;десятичные дроби&lt;/em&gt;. То есть такие дроби, у которых знаменатель - какая-то степень 10, то есть 3/10, 12/100, 13/1000  и т.д. Записывают их либо с запятой как у нас - (2,34) , либо с точкой, как принято на Западе (2.34). &lt;br /&gt;&lt;br /&gt;Возникает вопрос: "а как перевести обычные дроби в десятичные?". Вспоминая деление уголком, можно набросать нечто такое:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;img src="http://infostore.org/file/2948680/2455599/38.png" alt="3 / 8" title="3 / 8"&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Если говорить формально - то задача перевода из обычной дроби в десятичную представляет собой задачу нахождения такой наименьшей степени десятки, которая будет делиться на знаменатель заданной обычной дроби. То есть например для перевода дроби 3 / 8: берём знаменатель 8 и перебираем степени 10 до тех пор, пока какая-то степень 10 не станет делиться на 8: 10 не делится, 100 не делится, а вот 1000 делится (1000 / 8 = 125), значит 3 / 8 = 375 / 1000 = 0,375. &lt;br /&gt;Однако, что делать, если такой степени не находится или в случае деления уголком - процесс не заканчивается? Например, попробуем поделить 1 на 3:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;img src="http://infostore.org/file/2948674/2455596/13.png" alt="1 / 3" title="1 / 3" /&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Как мы видим - процесс через некоторое время зацикливается - то есть повторяются те же остатки, и мы точно знаем, что следующие цифры будут повторять предыдущие.&lt;br /&gt;Таким образом имеем, что:&lt;br /&gt;&lt;pre&gt;
1/3 = 0.333333...
&lt;/pre&gt;&lt;br /&gt;Терпение, мы уже близки к ответу на вопрос :) Для того, чтобы отразить тот факт, что тройка в десятичной записи числа 1/3 повторяется и не писать троеточий - было введено специальное обозначение 0,(3). Часть в скобках называется &lt;em&gt;"периодом" дроби&lt;/em&gt;, то есть бесконечно периодически повторяющейся частью дроби, а сама дробь - периодической. Таким образом, запись дроби с периодом является лишь иной формой записи обычного рационального числа, возникающей при переходе к конкретной системе счисления (в нашем случае десятичной) и период появляется, если в разложении на простые множители знаменателя уже сокращённой дроби присутствуют сомножители, на которые не делится основание системы счисления (например 6 = 2 * 3, 10 не делится на 3, потому у дроби 1/6 есть период в десятичной системе счисления). Кроме того, можно показать, что &lt;em&gt;любая&lt;/em&gt; периодическая дробь является рациональным числом (то есть числом вида &lt;strong&gt;m / n&lt;/strong&gt;), всего лишь представленным в альтернативном виде. &lt;br /&gt;&lt;br /&gt;Таким образом можно смело записать что &lt;strong&gt;0,(3) = 1/3&lt;/strong&gt;, поскольку это одно и то же число, записанное различным образом. Соответственно, умножив на 3 каждую из частей уравнения, мы получаем, что 0,(9) = 1. Такое доказательство немного напоминает магию, однако всё дело в том, что по сути не существует чисел, разделив столбиком которые, мы могли бы получить число 0,(9) так, как мы получили 0,(3) разделив 1 и 3.  Так что можно и усомниться в праве на существования у этого числа. Однако было бы нецелостно и математически нестрйоно отказываться от периодической формы записи в том случае, если число в периоде - 9, то есть 0,(9) или 1,(9) и т.д. &lt;br /&gt;Поэтому число 0,(9) в данный момент вполне признано и является лишь альтернативной, неудобной и ненужной формой записи числа 1. &lt;br /&gt;&lt;br /&gt;Как мы видим, определение периодических дробей не имеет никакого отношения к рядам, анализу бесконечно малых величин, пределам и тому подобным вещам, преподаваемым в высшей школе. &lt;br /&gt;Резюмируя, можно сказать, что данная форма записи является всего лишь артефактом, вызванным применением конкретных систем счисления (в нашем случае десятичной системы). Насколько мне известно, некоторые математики (которых цитировал в одной из своих статей весьма известный Д. Кнут) ратуют за упразднение таких двузначных и спорных представлений чисел как 0,(9) и некоторых других.&lt;br /&gt;&lt;br /&gt;Полезные ссылки по данному вопросу:&lt;br /&gt;&lt;a href="http://ilyabirman.ru/meanwhile/2006/07/15/1/"&gt;Блог Ильи Бирмана, в котором он расcматривает похожий вопрос&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Proof_that_0.999..._equals_1"&gt; Статья из Википедии о 0,(9) и 1 (англ., рус.)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D1%87%D0%B8%D1%81%D0%BB%D0%B0"&gt;Определение рационального числа на Википедии&lt;/a&gt;&lt;br /&gt;&lt;a href="http://mathworld.wolfram.com/RepeatingDecimal.html"&gt; О периодических дробях и их свойствах на MathWorld.com (англ.) &lt;/a&gt;&lt;br /&gt;&lt;a href="http://mathworld.wolfram.com/DecimalExpansion.htm"&gt; Описание процесса Decimal Expansion (представление дроби в десятичной форме) на MathWorld.com (англ.)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Надеюсь, что объяснения были вполне понятными и интересными. Все возникшие вопросы, замечания и исправления - буду рад видеть в комментариях!&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:65455</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/65455.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=65455"/>
    <title>Hello, space dog</title>
    <published>2007-03-27T00:57:30Z</published>
    <updated>2007-03-27T01:01:18Z</updated>
    <lj:music>:Of the Wand and The Moon:</lj:music>
    <content type="html">&lt;i&gt;Грядущему дню космонавтики посвящается. &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Узнал такие вот факты о собаках-космонавтах.&lt;br /&gt;В СССР чаще всего в космос отправляли именно собак, так как считалось, что они лучше всего переносят длительную вынужденную неподвижность, именно бродячих собак - из-за того, что они лучше переносят стрессы, и именно самок (сук) - из-за  их темперамента и того, что им не надо поднимать ногу для понятного процесса :) &lt;br /&gt;&lt;br /&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/en/c/c9/Laika.jpg" title="Laika" /&gt;&lt;br /&gt;&lt;br /&gt;Первым живым существом с Земли, попавшим на Земную орбиту была собака Лайка. Её нашли, бродившей по улицам Москвы, затем она прошла конкурсный отбор среди трёх других собак. &lt;a name="cutid1"&gt;&lt;/a&gt;В процессе тренировок их садили во всё уменьшающиеся клетки для того, чтобы приучить к тесноте спутника, крутили на центрифугах и помещали в специальные шумовые машины, имитирующие звуки, возникающие при запуске и работе спутника. Кроме этого, собак специально приучали есть специальный питательный гель, который стал бы им пищей в космосе. Лайка погибла из-за стресса и перегрева, после нескольких часов пребывания на орбите, что некоторое время скрывалось. Лайка является одним из персонажей Монумента "Покорителям Космоса" в Москве, а также персонажем многих песен и книг, в том числе группы The Cardigans и писателя Харуки Мураками.&lt;br /&gt;&lt;br /&gt;Другими, не менее знаменитыми космонавтами были Белка и Стрелка:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/a/a7/Belka_and_Strelka_Russian_Space_Dogs.jpg" title="Belka and Strelka"&gt;&lt;br /&gt;&lt;br /&gt;Они отправились в космос в 1960-м году, в компании кролика, сорока мышей, всяческих растений  и были первыми существами, успешно вернувшимися с орбиты обратно на Землю, проведя в космосе около суток. Через полгода у Стрелки даже родилось шесть щенков, одного из которых забрал себе Хрущёв и подарил его дочери президента США Джону Кеннеди. После смерти, тела Белки и Стрелки были сохранены. Тело Белки находится в каком-то музее в Москве, а Стрелки - является частью передвижной выставки и путешествует по миру. &lt;br /&gt;&lt;br /&gt;А вот космонавты в космосе :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/ru/e/e1/Belka-Strelka.jpg" title="Belka and Strelka v kosmose :)"&gt;&lt;br /&gt;&lt;br /&gt;Американцы же отправляли в космос преимущественно обезьян. Но это уже другая история :)&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:65093</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/65093.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=65093"/>
    <title>Geek-анкета</title>
    <published>2007-03-18T19:51:19Z</published>
    <updated>2007-03-18T19:51:19Z</updated>
    <lj:music>Forseti - "Stern (Kim Larsen)"</lj:music>
    <content type="html">Вдохновившись начинаниями &lt;span class='ljuser  ljuser-name_martreya' lj:user='martreya' style='white-space: nowrap;'&gt;&lt;a href='http://martreya.livejournal.com/profile'&gt;&lt;img src='http://l-stat.livejournal.com/img/userinfo.gif' alt='[info]' width='17' height='17' style='vertical-align: bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='http://martreya.livejournal.com/'&gt;&lt;b&gt;martreya&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; в области анкетостроения, я тоже решил "вспомнить молодость", но при этом перейти на новый качественный уровень, вооружившись знаниями в области IT и околоайтишного юмора.&lt;br /&gt;Итак, вашему вниманию предлагается небольшой окологикерский опросник. Я надеюсь, что ответы на вопросы принесут вам несколько минут радости и подтолкнут к интересным размышлениям :)&lt;br /&gt;Отвечать желательно на большинство вопросов, однако если вопросы вызывают затруднение или непонимание - пропускайте без проблем.&lt;br /&gt;&lt;br /&gt;Кроме этого очень welcome предложения по поводу улучшения структуры и содержания анкеты, например внесения в неё интересных элементов - рекурсий, замыканий и т.д. и т.п. :)&lt;br /&gt;&lt;br /&gt;1. Кто вы? (можно писать несколько своих алиасов :))&lt;br /&gt;2. Вы человек или робот?&lt;br /&gt;3. Ваша любимая операционная система.&lt;br /&gt;4. Куда деваются программы, когда их удаляют? Есть ли небесный сервер?&lt;br /&gt;5. Что даёт вам Интернет?&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;6. Что для вас жизнь оффлайн?&lt;br /&gt;7. Какая ваша любимая цитата с bash.org.ru (если есть)?&lt;br /&gt;8. Как вы относитесь к учащению использования английских слов в русском языке в связи с компьютеризацией?&lt;br /&gt;9. Самый значимый для вас человек в области информационных технологий?&lt;br /&gt;10. Windows?&lt;br /&gt;11. Какая ваша любимая числовая последовательность?&lt;br /&gt;12. Вставьте то, что у вас сейчас в буфере обмена.&lt;br /&gt;13. Что значит для вас слово "программирование"?&lt;br /&gt;14. Верите ли вы в жизнь вне Земли?&lt;br /&gt;15. Кто такой Ктулху?&lt;br /&gt;16. Ваш любимый раздел математики.&lt;br /&gt;17. Ваше отношение к свободному программному обеспечению?&lt;br /&gt;18. Сколько компьютеров у вас дома?&lt;br /&gt;19. Есть ли у вас любимый гаджет?&lt;br /&gt;20. Каким браузером вы пользуетесь?&lt;br /&gt;21. Любите вы решать задачи?&lt;br /&gt;22. Равны ли 0,(9) и 1?&lt;br /&gt;23. Считаете ли вы, что можно будет когда-либо полностью повторить работу мозга?&lt;br /&gt;24. Сколько знаков числа "пи" вы помните наизусть?&lt;br /&gt;25. Что вы знаете о танцах с бубном?&lt;br /&gt;26. Доводилось ли вам заниматься сексом с человеком, с которым вы познакомились по интернету?&lt;br /&gt;27. Какой ваш любимый сайт?&lt;br /&gt;28. Пользуетесь ли вы ICQ (и другими IM-сетями)?&lt;br /&gt;29. Участвовали ли вы в FIDO?&lt;br /&gt;30. Ваша любимая цитата великих "компьютерщиков".&lt;br /&gt;31. Что вы знаете о резиновых утятах?&lt;br /&gt;32. Какие у вас есть замечания и пожелания к данной анкете?&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:dying_sphynx:64986</id>
    <link rel="alternate" type="text/html" href="http://dying-sphynx.livejournal.com/64986.html"/>
    <link rel="self" type="text/xml" href="http://dying-sphynx.livejournal.com/data/atom/?itemid=64986"/>
    <title>Ванная, комбинаторы и волосы на лобке</title>
    <published>2007-03-16T23:06:57Z</published>
    <updated>2007-03-16T23:27:31Z</updated>
    <lj:music>Radioahead "Kid a"</lj:music>
    <content type="html">Лёжа в ванной, думал о том, что ванная, в сущности, не очень удобное место для отдыха - здесь нельзя разместить ноутбук и нельзя даже взять с собой книгу (разве что ту, что совсем не жаль).&lt;br /&gt;Здесь, конечно, доступны некоторые развлечения (обычно свойственные новорожденным), но лучше таки использовать её как надо - для расслабления :) Да, ещё там удалось попить джин-тоника из банки! :)&lt;br /&gt;&lt;br /&gt;А, ещё задался там вопросом - зачем, интересно, волосы на лобке? Наверное можно занести куда-то в раздел "детские вопросы" :) Ответы и предположения - можно в комменты.&lt;br /&gt;&lt;br /&gt;Ещё сегодня открыл для себя исчисление комбинаторов - вещь, которую мы совсем не изучали по дискретной математике, вполне интересно. Получается, что исчисление комбинаторов - это такое себе полупрограммистское исчисление без переменных. И комбинатор, по сути, представляет собой некий объект, который просто &lt;i&gt;комбинирует&lt;/i&gt; свои входы (то есть те объекты, к которым он применён). А входы представляют собой те же объекты или комбинаторы. Они обычно обозначаются латинскими буквами и имеют названия а-ля "канцеллятор", "дупликатор" и т.д. В этом исчислении существует единственная операция - применение комбинатора. В общем, кому интересно - можно почитать здесь: &lt;a href="http://en.wikipedia.org/wiki/Combinator"&gt;http://en.wikipedia.org/wiki/Combinator&lt;/a&gt;  (увы, в русской Википедии по слову комбинатор находится только Остап Бендер :) - что совпадает с большинством откликов на эту тему в реале :)</content>
  </entry>
</feed>
