вторник, 28 декабря 2010 г.

Ещё о кризисе научной фантастики

В последнее время прочитал несколько книг Олега Дивова. Среди прочего прочитал и "Стенограмму одной дискуссии", в которой отечественные писатели обсуждали роль фантастического допущения в фантастике. Ознакомиться с текстом можно, например, здесь: http://lib.ololo.cc/b/181728/read#t30. По поводу прочитанного высказался на фантлабе: http://www.fantlab.ru/work174136#response160950

Вот недавно опять наткнулся на похожее мнение telemont о роли фантастического допущения в фантастике:
Так и читателю НФ нет дела до того, когда откроют гиперпространство. И автору тоже. Это лишь предлог, технический прием для того, чтобы рассказать некую историю - нравоучительную (часто), или парадоксальную, или просто забавную.


Ответил так:
Вот из-за того, что к фантастическому допущению относятся лишь как к предлогу рассказать привычную историю в необычном антураже, научная фантастика и находится в глубочайшем кризисе.

Фантастическое допущение - это не ещё один инструмент. Это уникальный инструмент, применение которого в жанре фантастики узаконено. Пользоваться этим инструментом нужно с осознанием его уникальности.

Только тогда может получиться настоящая качественная фантастика, "твёрдая" научная или "мягкая" гуманитарная. Разница между ними только в базе, от которой отталкивается писатель. В твёрдой НФ исходят из развития технологий и пытаются представить проблемы, которые порождают технологии - конфликт этики, личности, общественного устройства и технологий. В мягкой НФ исходят из желания рассмотреть какую-то уникальную проблему, для вскрытия которой недостаточно средств ни "большой" литературы, ни твёрдой НФ. В этом случае придумывается ситуация, пусть и невероятная, которая позволит эту проблему вскрыть.

Если же фантастические допущения делаются лишь для придания опусу необычного антуража, то получается то, что сейчас и наблюдаем - кризис научной фантастики.

Самое главное - не понятно, с кого началось именно такое восприятие жанра? С читателей или с писателей? Видно, что и те и другие мыслят сходным образом. Но кто начал? Или это начали писатели, которые под видом НФ начали писать мистику и фэнтези, формируя тем самым читательский спрос, или это начали читатели, которые сформировали рынок, на котором стало выгодно писать только эту самую мистику и фэнтези, в которых роль фантастического допущения низведена до средства создания необычного антуража и атмосферы загадочности? Возможно этот вопрос так же бессмысленнен, как и вопрос о яйце и курице, и такое мнение о НФ сформировалось в читательских и писательских головах под влиянием мнений друг друга. Если это так, то настоящая НФ, скорее всего, навсегда останется малотиражной литературой для горстки маргиналов, что меня лично весьма огорчает.

понедельник, 13 декабря 2010 г.

Подборка интересных статей

Наука:
o Средства против цели
o Про науку

Ассандж, WikiLeaks и радикальные феминистки:
o Изнасилование по-шведски
o ХОББИ ГЕНДЕРНОГО ЛОББИ. Мелкая грязь и крупная политика

Общественный транспорт, каким он должен быть:
o Зачем приседает автобус? Общественный транспорт США

Человек стремится стать... чипом?

Тут вот один футурист-любитель, делает такой вот Прогноз: человек стремится стать чипом :) скорей всего он им и станет.

Обосновывает он свой прогноз очень просто. Всё, что сделано человечеством, на его взгляд, сделано для удовольствия. А раз так, то можно ничего не делать, а просто воздействовать на мозг таким образом, чтобы испытывать точно то же самое удовольствие. В пределе функции мозга человека редуцируются до микросхемы, которая сама внутри себя создаёт источник удовольствия и сама испытывает его.

Мне это напоминает малобюджетный, но тем не менее довольно глубокий по смыслу фильм "Виртуальный кошмар". Да и если покопаться, можно найти ещё массу примеров.

Ответил я ему, как мне кажется, довольно удачно. Хочется запомнить мысль.

Главный движущий вектор у человечества - не получение кайфа, а желание остаться живым и продолжить свой род. Получение кайфа - это движущий фактор, вектор которого направлен в направлении могилы. Это человечество постоянно вымирает, т.к. ставит кайф превыше жизни и создания жизнеспособного потомства.

Есть такой программист, его зовут Линус Торвальдс. Он считает, что человечество в первую очередь пытается обеспечить собственную безопасность, потом обустроить свой быт, и только потом получать удовольствие. Любая изобретённая технология проходит через этих три этапа.

Например, первый автомобиль был создан для того, чтобы передвигать тяжёлую пушку. Потом автомобиль стал перевозить людей и грузы. И только потом появился автоспорт (ралли, гонки, гонки Formula), автомобильные развлечения для любителей (дрифт, стрит-рейсинг, тюнинг) и так называемые "спортивные авто", на которых зачастую не то что багажника нет, но и в салоне имеется всего одно место для водителя.

Возьмём компьютеры. Сначала это были огромные шкафы, которые просчитывали таблицы для артиллерийской стрельбы. Потом они стали меньше и стали использоваться для ведения экономических расчётов, для печати документов. Потом они уменьшились до совсем маленьких размеров, стали персональными и начали использоваться для развлечения.

И так - почти вся деятельность человечества.

Обеспеченный обыватель может думать, что главная цель человечества - это развлечения. Он становится особо опасным, когда получает право голоса в демократическом государстве. Выбор каждого из миллионов обывателей в конце концов приводит к падению обороноспособности, ухудшению здравоохранения, образования, продовольственным кризисам. Такой обыватель ставит на первое место не проблему выживания и конкурентоспособности в современном обществе, а проблему получения удовольствия. Такое государство чахнет и завоёвывается конкурентами.

Кстати, война может быть и не явной. Не обязательно вводить свои войска на чужую территорию, достаточно лишь чтобы чужое население подчинялось твоей власти. Захотел получать нефть за зелёные фантики - нужно убедить нефтяное государство, что ему нужны зелёные фантики. Напечатать их - не проблема. Нефть перегоняешь на пластмассу и топливо, аборигенам даёшь зелёные фантики. Чтобы аборигены хотели ещё зелёных фантиков, продаёшь им стеклянные бусы с айфонами. Когда надоест их кормить, просто приходишь и убиваешь, т.к. они уже давно забыли что такое оружие и радуются айфонам.

среда, 1 декабря 2010 г.

Лучшие роботы 2010 года

Японцы назвали лучших роботов 2010 года

Меня заинтересовала фабрика для разделки свиных ножек, хоть и вызвала жуткое неприятие. Люди что, стремятся остаться не запачканными? Осталось только создать свиноферму-автомат, чтобы подсыпала свиньям жратву, убирала говно. Ну и для полной автономии - чтобы свиноматкам боровов по расписанию загоняла, да убоем занималась. Тогда люди смогут стать чистенькими моралистами, не убившие ни одной свиньи. И знать они не захотят, откуда берётся мясо и какие ужасы происходят у них под носом.

Очень понравился робот для инспекции высоковольтных линий электропередач. Особенно после просмотра ролика, где человек выравнивает потенциал вертолёта с полумегавольтным проводом и затем залезает на этот провод. Робот посадить на линию нужно всего один раз, а дальше он сможет передвигаться по всей длине линии электропередачи, преодолевая даже места, за которые провод подвешивается.

Понравился робот для сбора клубники. Он сам обнаруживает созревшие ягоды, срезает их и кладёт в лоток.

Он снимал КЕНО!!!


А лучше бы он и в самом деле снимал клипы.

вторник, 30 ноября 2010 г.

Человек-музыкальный компьютер

Дерек Паравичини - гениальный пианист, не смотря на то, что слепой и аутист. Он обладает разумом четырёхлетнего ребёнка, не может отличить правое от левого, не может сосчитать до десяти.

Однако обладает феноменальным слухом, способен исполнить на пианино любую музыку, услышанную им всего один раз. Более того - способен исполнить раздельно две мелодии, услышанные одновременно. Умеет импровизировать: менять тональность, лад, темп и нечто неподдающееся формализации - настроение мелодии, легко свингует. Весь его мозг специализируется на музыке - это свойство называется синдромом саванта.

По ссылке можно найти первый ролик из пяти, остальные ютуб предлагает к просмотру автоматически.

Вот ещё один савант - обладает феноменальной зрительной памятью:

Глядя на это чувствуешь, что умственно неполноценные - это как раз не они, а всё человечество.

Остаётся только дождаться появления мокрецов из "Гадких лебедей" Стругацких, чтобы они начали строить свой мир, в котором нам не место.

воскресенье, 28 ноября 2010 г.

И тут Остапа понесло...

То, чего не покажут по телевидению:

Обычно по телевидению показывают только взвешенную, стройную и разумную речь нашего премьер-министра. Всё это похоже на хорошо срежиссированные ролики, идущие по заранее согласованному сценарию. Однако на этом ролике видно, что ничто человеческое Путину не чуждо и иногда он ведёт себя просто как последнее хамло.

А началось всё с того, что я захотел послушать речь Парфёнова:


Потом это навело меня на вопросы Шевчука с Путиным:


Расшифровка лжи Путина:


Марш несогласных, о котором спрашивал Шевчук. Показано, как разгоняли народ:


А вот и итог, подведённый в передаче "Неделя" на РенТВ.


Собственно, в чём цимес происходящего. Марш протеста - это акция, целью и смыслом которой является проверка 31 статьи конституции Российской Федерации.

Статья 31

Граждане Российской Федерации имеют право собираться мирно без оружия, проводить собрания, митинги и демонстрации, шествия и пикетирование.


По тому, как проходит акция, очень легко понять отношение нашей власти к конституции. Клала наша власть на конституцию с большим прибором.

четверг, 25 ноября 2010 г.

Чем вызван кризис научной фантастики?

Рекомендую к прочтению статью "Чем вызван кризис научной фантастики?". Запаситесь терпением - многабукф, но оно того стоит.

четверг, 18 ноября 2010 г.

Об идейных феминистках

Цитата моего комментария к Автоматизированная система утилизации противников матриархата:

Что меня всегда удивляло в идейных феминистках, так это красивое будущее, которого они сами для себя построить не смогут.

Достаточно сказать, что гигиенические тампоны в их современном виде изобрёл мужик, Эрл Хаас. И это не говоря о строительстве, электроэнергетике, автомобилях, стиральных машинах, компьютерах. Вот сидит авторша перед компьютером, пишет в ЖЖ и даже не задумывается, что 99% всего того, чем она пользуется, изобрели мужчины, включая компьютер, интернет и ЖЖ.

Я бы понял женщину-феминистку, которая работает генетиком и занимается исследованиями в области искусственного оплодотворения. Понял бы женщину-феминистку, которая разрабатывает заводы-автоматы, занимается проблемами искусственного интеллекта, распознаванием образов и т.п.

Но женщина, которая пишет отчёты для БД, создать того будущего, которое она хочет, не сможет. Вы и эту автоматизированную систему утилизации противников матриархата даже до проектной документации не доведёте. На что уж дальше рассчитывать?

Кстати, феминистки обычно сами умирают вполне естественным путём. Занимаясь однополой "любовью", они попросту не могут зачать потомства. Мужикам для этого даже газенваген придумывать не приходится. Принцип естественного биологического отбора работает против феминисток.


Скопировал сюда на память, т.к. практически уверен, что комментарий будет удалён.

Буквально месяц-полтора назад я прочитал книгу Александра Никонова с очень провокационным названием "Конец феминизма. Чем женщина отличается от человека". Я не в восторге от названия, оно мне очень не нравится, не хотелось светить обложкой книги перед женой. Но эту книгу я купил, т.к. до этого читал другую книгу того же автора "Апгрейд обезьяны. Большая история маленькой сингулярности" и по ней у меня сложилось впечатление об авторе, как о здравомыслящем человеке, способном на глубокие мысли.

На самом деле, автор в книге вовсе не хотел сказать, что женщина не является человеком. Это такая игра слов, суть которой понятна только на тех языках, где слово "человек" и слово "мужчина" имеют одинаковое написание и произношение. Правильно было бы читать так "Конец феминизма. Чем женщина отличается от мужчины", но книга от этого потеряла бы свою провокативность и способность к саморекламе. Согласитесь, что книга со вторым названием, продавалась бы гораздо хуже и привлекла бы меньше внимания.

Так вот, блог http://leyla-22.livejournal.com/, можно считать хрестоматийным примером идейной феминистки. Ровно такой, о каких речь идёт в книге Никонова. Хотя книга не только об этом, а о бессмысленности американской политкорректности, постепенно проникающей во все остальные страны и пререворачивающей основы современной цивилизации с ног на голову.

Благодаря игре в политкорректность в одни ворота, становится трудно быть умственно полноценным белым мужчиной традиционной сексуальной ориентации. Раньше это была основа, движущая сила человечества, теперь же эту движущую силу преследуют и обвиняют в бедах "меньшинств": гомосексуалистов, феминисток, чернокожих, умственно отсталых. И "угнетателям" приходится их кормить, бояться не обидеть, не унизить, выделять им квоты в школах, университетах, на государственных постах, упрощать ради них учебную программу. На мой взгляд, вполне явная тенденция к деградации общества.

Дополнение:

О! Да она, оказывается, прочитала ту же самую книгу! Только вот прочитанное не поняла и не осознала. Мой диагноз - к мышлению не способна, т.к. любые логические аргументы оценивает эмоциями. Впрочем, это неотъемлемая часть хрестоматийной радикальной феминистки.

суббота, 6 ноября 2010 г.

вторник, 2 ноября 2010 г.

Удаление объектов из видеопотоков в реальном времени

Возможно баян, но тем не менее:



Из видеопотока в реальном времени удаляется любой выбранный предмет. Отсутствующие пиксели картинки заполняются интерполированными пикселями. Если внимательно присмотреться, то можно увидеть, как меняется рисунок. Ощущения такие же, как при разглядывании картинок, демонстрирующих слепое пятно глаза - вроде бы точно там что-то есть, а вот разглядеть это что-то невозможно.

Ну и ещё прикол - мыло, убранное с раковины, не исчезло в зеркале. Прямо мыло-оборотень.

воскресенье, 31 октября 2010 г.

Лена Сквотер

Сегодня дочитал роман Леонида Каганова "Лена Сквотер и парагон возмездия".

Илена Сквотер - квинтэссенция офисных менеджеров-карьеристов. Образец паразита современности. Она обладает потрясающей коллекцией стереотипов для суждения о любом человеке по первому впечатлению. Она лихо рассортировывает людей по мусорным вёдрам, ориентируясь только лишь на модель мобильника, материал визитки и надпись на ней, по месту деловой встречи, по одежде, по речевым оборотам собеседника. Себя же она считает единственно правильным человеком и вершиной биологической и социальной эволюции. Если бы она встретилась мне в жизни, она оставила бы после себя невероятно гадливое впечатление.

Сам роман представляет собой скорее сборник небольших сатирических заметок обо всём, более пригодных скорее для блога, а не для романа. В книге последовательно рассмотрены следующие темы: офис и его обитатели, визитки, рекламные бренды, суши-бары, провинция, журналистика, социальные сети, феминизм, интеллектуалы, сектанты и страховые агенты, рекламный бизнес, неприспособленность российских реалий для проживания инвалидов, российские балконы, предательство, преданность. Всё это происходит на фоне сюжетной линии поиска главной героиней таинственного места, где происходит сбыча мечт - по одной на рыло.

По ходу чтения создаётся впечатление, что автор, как мог, увеличивал объём книги, наполняя её различными наблюдениями из жизни, легкомысленными суждениями и заблуждениями офисного планктона, сценами троллинга и кровопролития. Возникает опасение, как бы автор не положил все свои силы на эту книгу и не исписался.

Тем не менее, книга читается очень легко и не навевает скуки. Это развлекательное чтиво, которое однако, не стоит рекомендовать неокрепшим умам - они могут воспринять прочитанное скорее как образец для подражания, а не как едкую сатиру на героя нашего времени.

вторник, 26 октября 2010 г.

Ура, спама нет!

Раньше в GMail всегда в пустой папке со спамом отображалось сообщение: "Ура, спама нет!" Простое восклицание, которое мог произнести настоящий человек.

Потом на гугл напали роботы и надпись поменяли на "Ура, спам отсутствует!" Я пытался найти хоть какие-нибудь контакты для обратной связи с гуглом, чтобы сказать им, что русские люди не могут говорить таким суконным языком. Но похоже срать они хотели на обратную связь - нигде не указано ни одного емейла, ни формы обратной связи.

Прошло уже наверное полгода, я уже смирился с этой надписью. И вот сегодня заметил, что её опять заменили на человеческую: "Ура, спама нет!"

суббота, 11 сентября 2010 г.

Valgrind

Только что примерно час искал в своей программе на C ошибку при работе с памятью. В процессе работы программы периодически замусоривалась информация в одном массиве. Сначала некоторое время в массиве сохраняется правильная информация, потом некоторое время идёт мусор, а затем снова идёт правильная информация. Я долго не мог понять в чём дело, проверял каждый этап работы программы - вроде бы всё должно нормально работать. Создавалось ощущение, что память повреждалась где-то между вызовами двух функций, каждая из которых работала правильно.

Поставил valgrind, запустил свою программу под его управлением. Посмотрел лог и нашёл причину ошибки - неправильно расчитывался размер памяти при перевыделении памяти под массив с помощью realloc. При первом вызове realloc массив имел нулевой размер, поэтому первый же вызов realloc создавал некоторый запас памяти для дальнейшей правильной работы. Когда этот запас заканчивался, происходила запись информации куда-то за пределы распределённого пространства (повреждая при этом часть уже распределённых до этого структур). Потом происходил ещё один вызов realloc и памяти вновь становилось достаточно, дальше в массив вновь сохранялась правильная информация.

Очень глупая ошибка, но как сложно её было найти! Valgrind - прекрасная программа. Спасибо разработчикам за столь полезный инструмент.

пятница, 20 августа 2010 г.

Doom жив!

На этой неделе решил стряхнуть пыль с Doom'а и попробовать поиграть на уровнях, сделанных поклонниками этой игры. Поскольку уровни обычно распространяются в виде PWAD файлов, то есть Patch WAD, то им требуется основной WAD-файл - IWAD, Id software WAD. Я достал с полки компакт-диск с четырьмя официальными частями игры и собрал все WAD-файлы в одном каталоге:

  1. Ultimate Doom - doom.wad,

  2. Doom 2: Hell On Earth - doom2.wad,

  3. Final Doom: TNT Evilution - tnt.wad,

  4. Final Doom: Plutonia Experiment - plutonia.wad.


Далее, можете воспользоваться моей заметкой Музыка в PrBoom для настройки одного из современных портов Doom'а, одной из основных целей которого является достижение максимальной совместимости с оригинальной игрой. Достигнутая совместимость настолько высокая, что в порте PrBoom можно даже просматривать старые демо-записи из оригинальной игры, при том что демо-записи представляют собой поток записей с информацией о нажатых на клавиатуре клавишах. То есть малейшее несоответствие в поведении игрового мира приведёт к тому, что в демо-записи игрок будет невпопад идти, тыкаться в стенки, стрелять в пустоту и уворачиваться от невидимых монстров до тех пор, пока игрока не убьют.

Затем, я скачал на сайте iddqd.ru несколько wad-файлов:

  1. 1 Monster Megawad - 1monster.wad

  2. 10 sectors contest - 10sector.wad

  3. 1024 and 2 sectors - 2sectors.wad

  4. Grid 32 - grid32.wad


Эти 4 WAD-файла были сделаны в промежутке от 2000 до 2008 года - то есть сравнительно недавно. Люди до сих пор продолжают делать карты для Doom. Вот, например, на страничке с уровнями, сделанными неким Shadowman'ом можно найти уровни, датированные аж 21 июля 2010 года.

Конечно, много воды утекло с тех пор, когда существовал оригинальный Doom. Многие карты делаются в расчёте на современные порты Doom'а. Но, есть и классические карты, которые будут работать и в оригинальном Doom в DOS. Есть чуть менее классические, выполненные в так называемом формате Limit Removing - это карты, в которых используются только возможности исходного, оригинального Doom, но не обращается внимание на технические ограничения старого движка: карты иногда достигают огромных размеров, с большим количеством использованных текстур, что старый движок Doom не потянул бы.

Есть и независимые реализации движков Doom, например ZDoom. Они не преследуют цель достижения максимальной совместимости, а в большей мере рассчитаны на достижение максимальной гибкости и фичастости. Например, в них возможны многоэтажные уровни, прозрачные поверхности, скриптовое управление уровнем и т.д.

Люди даже продолжают рисовать монстров, оружие, наборы текстур, элементы обстановки, предметы.

18 августа 2010 года вышло очередное обновление редактора уровней Doom - Doom Builder. Что характерно, редактор написан для Windows с использованием .NET, позволяет редактировать уровне в режиме трёхмерного просмотра.

В 2005 году музыканты-энтузиасты записали два альбома ремиксов музыки из Doom: The Dark Side of Phobos. Музыка не является ремиксами в полном смысле слова: музыка творчески переосмыслена, аранжирована и исполнена на "настоящих" инструментах. Естественно, это не MIDI-файлы, пропущенные через сэмплер, это настоящая музыка, которую приятно слушать и вне игры. Альбомы доступны для бесплатного скачивания на самом сайте проекта в виде torrent-файла.

Существуют проекты по созданию трёхмерных моделей монстров, по рисованию текстур более высокого разрешения. Есть конверсия уровней Doom на движок Doom 3: Classic Doom 3, музыка перезаписана музыкантами в студии, на "настоящих" инструментах.

В общем, Doom жив как никогда. Удивительно, в этом году 10 декабря Doom'у исполнится уже 17 лет, но он всё никак не может покинуть сердца фанатов. В том числе моё сердце. Периодически мне хочется снова поиграть в эту игру, иногда хочется закончить свой WAD-файл с недоделанными уровнями, которые я делал ещё лет пять-шесть назад в до ужаса кривом DOS-редакторе WadEd. Doom продолжает жить.

среда, 11 августа 2010 г.

Поиск простых чисел

Откопал из закромов свою программу на Си для поиска простых чисел по алгоритму решета Эратосфена:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int MAX_NUMBER =1048576;
const unsigned long masks[32]={0x80000000,0x40000000,0x20000000,0x10000000,
0x08000000,0x04000000,0x02000000,0x01000000,
0x00800000,0x00400000,0x00200000,0x00100000,
0x00080000,0x00040000,0x00020000,0x00010000,
0x00008000,0x00004000,0x00002000,0x00001000,
0x00000800,0x00000400,0x00000200,0x00000100,
0x00000080,0x00000040,0x00000020,0x00000010,
0x00000008,0x00000004,0x00000002,0x00000001};
inline unsigned long getBit(unsigned long *ptr,unsigned long bit)
{
return ptr[bit>>5]&masks[bit&0x1f];
}
inline void setBit(unsigned long *ptr,unsigned long bit)
{
ptr[bit>>5]|=masks[bit&0x1f];
}
inline void resetBit(unsigned long *ptr,unsigned long bit)
{
ptr[bit>>5]&=~masks[bit&0x1f];
}
void main(void)
{
unsigned long maxNum=MAX_NUMBER;
unsigned long *ptr=(unsigned long *)malloc(maxNum/8);
if (ptr==NULL)
{
fprintf(stderr,"Can't get memory for buffer.\n");
return;
}
memset(ptr,0xff,maxNum/8);
for(unsigned long i=2;i<maxNum;i++)
if (getBit(ptr,i)!=0)
{
fprintf(stdout,"%ld\r",i);
fprintf(stderr,"%ld\r",i);
for(unsigned long j=2*i;j<maxNum;j+=i)
resetBit(ptr,j);
}
free(ptr);
}

Судя по отметке времени на файле, программа была написана 28 октября 2002 года. Ищет простые числа от 1 до 1048576. На хранение всего "решета" отводится 128 килобайт памяти. Для поиска чисел до миллиарда потребуется 128 мегабайт.

вторник, 10 августа 2010 г.

Национализация рубля

Национализация рубля - очень советую ознакомиться. Просто и понятно о том, почему России выгоднее продавать нефть за рубли. Кстати, похожая идея была озвучена в фильме "Бесценный доллар 2" (тоже советую посмотреть оба фильма).

среда, 14 июля 2010 г.

Самоорганизующаяся сеть связи

Я джва года хочу такую вещь: Австралийцы освободили мобильники от сети

Столлман мечтает о свободе от производителей программного обеспечения, а я иногда мечтаю о другой свободе - свободе от инфраструктуры, отдельные компоненты которой уже существуют. Это - собственный дом (чтобы избавиться от проблемных соседей), гараж (чтобы избавиться от проблемы с парковкой), топливный электрогенератор (избавиться от зависимости от центрального электроснабжения), водяная скважина с насосом (избавиться от городского водоснабжения). Отдельный пункт такой свободы - это связь, не зависящая от операторов связи. И вот оно. Правда это пока эксперимент энтузиаста, но однако очень многообещающий, на мой взгляд, эксперимент. Надеюсь, что проект доведут до промышленного производства, а различные операторы связи не смогут заблокировать распространение этого проекта на массовый рынок.

понедельник, 5 июля 2010 г.

Программы на Tcl/Tk

Сегодня захотелось поискать что интересного из программ написано с испольованием Tcl и Tk.

Для получения предварительной заготовки для поиска воспользовался следующей командой:
apt-rdepends -r tk tcl | grep -v "  " | xargs -n1 apt-cache show | grep -E "^Description:|^Package:" | cut -d" " -f2-

После компоновки результатов и исправления глюков в списке, получилось следующее:
tk - The Tk toolkit for Tcl and X11 (default version) - run-time files
bwidget - A set of extension widgets for Tcl/Tk
ferret - CASE tool for data model editing
password-gorilla - a cross-platform password manager
setools - инструменты анализа стратегий защиты SELinux
survex-svxedit - survey data editor for Survex
therion - Cave surveying - 2D and 3D drawing software
therion-viewer - Cave surveying - 3D viewer for therion models
tkabber - GUI client for XMPP (Jabber) instant messaging protocol
tkabber-plugins - standard plugins for Tkabber, an XMPP (Jabber) client
libtk-img - Extended image format support for Tcl/Tk (runtime)
libtk-img-dev - Extended image format support for Tcl/Tk (development files)
saods9 - image display tool for astronomy
libtktable2.9 - Table extension for Tcl/Tk
openverse - A graphical chat client/server written in tcl/tk
tk-dev - The Tk toolkit for Tcl and X11 (default version) - development files
libace-tkreactor-dev - ACE-GUI reactor integration for Tk development files
libtao-tkresource-dev - TAO-GUI reactor integration for Tk development files
tk-tile - A themed widget set provider library for Tk
tkcon - Enhanced interactive console for developing in Tcl
tklib - the standard Tk Library
tcl - The Tool Command Language (default version) - run-time files
cdrbq - graphical cd burning frontend
cdrtoaster - Dummy package for cdrbq (rename of package)
libmemchan-tcl - Tcl extension for in-memory channels - runtime library
libmemchan-tcl-dev - Tcl extension for in-memory channels - development files
libsnack2 - Sound extension to Tcl/Tk and Python/Tkinter - Tcl/Tk library
amsn - MSN интернет-пейджер написанный на TCL
libsnack2-dev - Sound extension to Tcl/Tk and Python/Tkinter - development files
python-tksnack - Sound extension to Tcl/Tk and Python/Tkinter - Python library
wavesurfer - Sound Manipulation Program
libsnack2-alsa - Sound extension to Tcl/Tk and Python/Tkinter - Tcl/Tk library
libtrf-tcl - Tcl data transformations - runtime library
libtrf-tcl-dev - Tcl data transformations - development files
libudp-tcl - UDP sockets for Tcl
mysqltcl - Interface to the MySQL database for the Tcl language
tcl-dev - The Tool Command Language (default version) - development files
aolserver4-dev - AOL Web Server 4 (Development Tools)
tcl-tls - the TLS OpenSSL extension to Tcl
tclcurl - Tcl bindings to libcurl
tclex - A lexical analyzer generator for Tcl
transcriber - Transcribe speech data using an integrated editor
tcllib - the Standard Tcl Library
gpsmanshp - A Tcl interface to shapelib
xastir - X Amateur Station Tracking and Information Reporting
tclxml - Tcl library for XML parsing
tkremind - Tk GUI interface to remind
tclodbc - The ODBC extension to Tcl
tclreadline - GNU Readline Extension for Tcl/Tk
tclthread - Tcl extension implementing script level access to Tcl threading capabilities
tclvfs - Exposes Tcl 8.4's virtual filesystem C API to the Tcl script level
tclxapian - Xapian search engine interface for Tcl
tdom - A fast XML/DOM/XPath/XSLT extension for Tcl written in C
tdom-dev - A fast XML/DOM/XPath/XSLT extension for Tcl written in C - development files
xotcl - Extended Object Tcl (XOTcl): Object orientation for Tcl - shared library
aolserver4-xotcl - Extended Object Tcl (XOTcl): Object orientation for AOLServer - module
xotcl-dev - Extended Object Tcl (XOTcl): Object orientation for Tcl - development files
xotcl-shells - Extended Object Tcl (XOTcl): Object orientation for Tcl - shells

Из всего этого списка меня заинтересовали следующие программы:

1. ferret - программа для рисования UML-диаграмм. Привожу скриншоты.

Задаём настройки проекта:

Создаём таблицы с описанием полей, указываем взаимосвязи:

Смотрим на UML-схему для распечатки:

Генерируем схему БД для MySQL:

2. password-gorilla - программа для хранения паролей. В программе проявился всё тот же глюк со шрифтами, потому это убожество даже снимать не стал. Да и вообще, идея хранения паролей в одной программе мне кажется не особо привлекательной.

3. survex-svxedit - какая-то программа для рисования карт пещер. Спелеологией я не увлекаюсь, а потому программа меня не заинтересовала.

4. therion - похоже, что это то же самое, но здесь карты можно смотреть в объёме. При запуске программа ругнулась на отсутствие программы cavern. Дальше смотреть не стал, за отсутствием интереса к картам пещер.

5. tkabber - уже смотрел.

6. cdrbq и cdrtoaster - два брата-близнеца, программа для записи CD-дисков. Запись DVD не поддерживает, интерфейс прост как 5 копеек. Не заинтересовало.

7. amsn - программа обмена мгновенными сообщениями по Microsoft'овскому протоколу MSN. Заинтересовало. Попробовал зарегистрироваться в MSN - не получилось, разбираться лень. Программа не интересна.

8. wavesurfer - аудиоредактор. Обладал всё тем же шрифтовым глюком. Не интересно.

9. tkremind - календарь-напоминалка. Выглядит так:


Итог - ничего интересного. Пожалуй для любой из интересных программ можно найти более интересные и удобные аналоги, написанные на чём-нибудь вроде Python и GTK или C++ и Qt.

воскресенье, 4 июля 2010 г.

Красота

Вот тут Красота Витус Вагенр задаётся вопросом, чего же такого некрасивого в Tk? И приводит следующий сравнительный рисунок разных тулкитов:



Отвечаю. Вот что:



Это вид tkabber в моей системе по умолчанию. Увидев такое, сразу же исчезает желание копаться в настройках, дабы привести это чудо в подобающий вид. Первая и последняя реакция (прошу прощения за мат): "ну уж нахуй-нахуй" с последующим незамедлительным сносом tkabber.

P.S. А вот и решение нашлось: Нормальный русский шрифт в Tk-приложениях

Ставим Tk версии 8.5:
# apt-get install tk8.5

Выбираем Wish версии 8.5 в качестве используемого по умолчанию:
update-alternatives --config wish

После этого tkabber выглядит значительно лучше:

понедельник, 28 июня 2010 г.

Грядут очередные "нанотехнологии"?

Давеча Медвед в Калифорнию ездил, дабы приобщиться к опыту прогрессивной "Кремниевой долины". Даже с говно-твиттером поиграл, видимо думая что это венец эволюции всех информационных технологий.

В кремниевой долине работает полмиллиона русскоязычных эмигрантов, а Медвед поехал, видимо, выяснить, хорошо ли им там живётся? Или захотел переманить русских обратно в Россию, чтобы они поднимали микроэлектронную и программную промышленность на родине? Вот уж дудки, обратно они не поедут.

Не думаю, что многие люди готовы выучить чужой язык, бросить свою родину и родственников и мчаться галопом на чужбину, если им и на родине хорошо. Было бы хорошо - не уезжали бы. А это значит, что была бы у нас своя кремниевая долина, если бы талантливым людям не вставляли палки в колёса.

Вы думаете с чего начинались фирмы Hewlett Packard и Apple? С небольшой мастерской в гараже! То есть чтобы у нас появилась Кремниевая долина, нужно просто не мешать талантливым людям. А сейчас всё обстоит ну просто невыносимо плохо, катастрофически плохо. Обязательно прочитайте следующие статьи, чтобы проникнуться абсурдностью нашей бюрократии:
1. Полная версия статьи "Два берега - две реформы"
2. Продолжение полной версии статьи "Два берега - две реформы"
3. Заключительная часть статьи "Два берега - две реформы"

А что там, интересно, с "нанотехнологиями"? Результаты какие-нибудь есть? Если нет, то и с русской кремниевой долиной тоже ничего не получится, как пить дать.

пятница, 25 июня 2010 г.

Робот, играющий в бильярд

Подаренные PR2 различным исследовательским группам, уже дают отдачу: Персонального робота обучили игре в бильярд. Пересказывать не буду, я всё равно не знаю больше, чем написано по ссылке. Судя по ролику, робот не виртуоз, но по крайней мере хоть один шар в лузу загоняет при каждом ударе. А этого вроде бы вполне достаточно для того, чтобы выиграть всю партию, начиная игру первым.

вторник, 22 июня 2010 г.

"Поиск предназначения" и "Бессильные мира сего"

Прочитал два сольных романа Бориса Стругацкого.

Поиск предназначения или двадцать седьмая теорема этики

Цитирую свой отзыв на fantlab.ru:

К сожалению, книга в целом разочаровала. Очень понравилось описание блокадного Ленинграда, понравилось описание следственного допроса, очень заинтриговала сюжетная линия со следователем Красногорским. Я ждал продолжения, мне казалось, что вот-вот уже начнётся самое интересное. Однако автор то-ли не осилил продолжить сюжетную линию в прежнем направлении, то ли решил, что «и так сожрут» и концовка получилась неправдоподобной, бездарно скомканной и какой-то мутной.

Каков смысл книги, что хотел сказать автор? Главный герой практически с молодости стал понимать, что ему судьбой уготована какая-то миссия. В чём суть его предназначения — понять он не мог, судьба лишь обозначала границы, в рамках которых он мог делать всё, что ему угодно. Правда и о существовании границ он догадался не сразу и не сразу понял в чём заключаются эти границы. Почувствовав покровительство неведомых сил, он стал им пользоваться. Однако всё оказалось не так просто: в шахматной игре под названием жизнь он оказался очень крупной, но тем не менее проходной фигурой. Игрок, передвигавший фигуры по шахматной доске, дорожил ценной фигурой, однако спасать эту фигуру от любых опасностей у неведомого игрока намерений не было. Как только фигура стала угрожать исходу партии, игрок немедленно ей пожертвовал. Поэтому вывод такой: никто не может заранее знать своей судьбы, даже если судьба тебя оберегает.


К этому можно присовокупить ещё одну шикарную цитату о философии:

Жека презирал философию. Станислав, надо признаться, тоже. Он честно и безуспешно, еще с аспирантских времен, тщился понять: что такое философия и зачем она нужна? Пустой номер. У него все время получалось, что философия – это не более чем многословные рассуждения о Мире, не подкрепляемые никакими конкретными фактами. Причем не подкрепляемые как бы из принципа. Рассуждения, важнейшим свойством коих является то обстоятельство, что их невозможно ни опровергнуть, ни подтвердить. Их даже и не пытаются ни опровергать, ни подтверждать, словно договорившись заранее, что будут иметь дело с набором исключительно и только Гёделевских утверждений и никаких других. В лучшем случае философ (Тейяр де Шарден, скажем) оставлял по себе странное и противоестественное впечатление писателя-фантаста с недурным воображением, который решил почему-то писать (на основе осенившей его фантастической идеи) не роман, а некое гигантское эссе – как Лем со своей «Суммой технологии»... Видимо, философия, по самой сути своей, не приспособлена была отвечать на вопросы, она умела их разве что обсуждать.

Вот и всё, что можно сказать о романе. Читать не советую - зря потратите время. Не понимаю множества восторженных отзывов о книге на том-же fantlab.ru

Бессильные мира сего

Книга тоже, в общем, ни о чём. Жил-был некто, его называли "сенсей". Он умел определять самую главную способность человека. Занимался он исключительно мальчиками. За свою долгую биографию он определил главные способности у многих-многих мальчиков. Способности были самые разные, в том числе у некоторых - сверхъестественные. Один обладает абсолютной памятью - может запоминать дословно всё, что когда-либо слышал или читал. Другой умел предвидеть будущее и даже умел управлять им, только он об этом не догадывался. Третий был гипнотизёром. Четвёртый ненавидел людей и умел убивать их на расстоянии силой мысли. Пятый легко отличал правду от лжи - ходячий полиграф.

И вот одного из них, того который предсказывал будущее, заставили изменить исход президентских выборов. Он наложил в штаны и обратился за помощью к друзьям. Друзья пошумели-пошумели, но в конце концов предсказатель поменял результат выборов сам, а помощь друзей ему не понадобилась. Другой, который ненавидел людей, убил новоизбранного президента силой своей мысли, не специально - он вообще был не в курсе всей этой истории. Вот и всё.

Ну и вот ещё, с поганой овцы - хоть шерсти клок:

Почему-то все современные философы оставляют у меня впечатление безответственных говорунов. Никакой солидности. Никакой, понимаете ли, обстоятельности. И даже спецтерминология (испытанное оружие классиков) им не помогает – только возрастает протестное ощущение, что тебя, кроме всего прочего, еще и дурят. Что-то кашпировское вдруг обнаруживается в серьезном тексте, что-то чумаковское...

В целом книга - ещё хуже предыдущей. Есть такая фраза: "Сначала ты работаешь на репутацию, потом репутация работает на тебя." С моей точки зрения автор воспользовался былой репутацией и выпустил фуфло. Хотя, может кому-то это и понравится. На мой же взгляд из литературы подобного жанра лучше почитать Харуки Мураками - там есть все те же ингредиенты: философские размышления о жизни, мистика, психоделические сцены, абсурдные повороты сюжета и т.п. Это вообще сейчас довольно модный жанр. К сожалению, я затрудняюсь его назвать - просто не знаю как бы это могло называться?

В целом о Стругацких можно сказать, что они дискредитируют понятие научной фантастики. Если это считать фантастикой, то фантастику писал и Роберт Льюис Стивенсон. Его "Странная история доктора Джекилла и мистера Хайда" по жанру вполне укладывается в большую часть произведений Стругацких.

среда, 16 июня 2010 г.

Архитектурные диверсии Unix

Unix был бы прекрасной операционной системой, если бы не множество архитектурных диверсий, повлиявших на него.

К ним можно причислить следующие вещи:

1. Система сокетов. Система сокетов не вписывается в идеологию Unix "всё есть файл", т.к. для создания сокетов используются дополнительные системные вызовы. Можно сказать, что сокеты существуют параллельно с файлами, в чём-то даже пересекаясь с ними, но тем не менее не становясь от этого файлами в полном смысле.

2. Графическая система X. Основана на всё тех же сокетах. Предоставляет к устройствам типа клавиатуры, мыши и дисплея не файловый, а всё тот же доступ через сокеты, систему событий и собственную клиентскую библиотеку.

3. Файловая система устройств. Как ни странно, но эта архитектурная диверсия была создана самими авторами Unix. В чём заключаются претензии к файловой системе устройств? А претензии всё те же - файловая система устройств существует как бы отдельно от простой файловой системы, лишь пересекаясь с ней. Нельзя создать новое устройство на файловой системе устройств тем же образом, каким создаётся файл.

Эти три архитектурных диверсии привели в конечном итоге к тому, что для того, чтобы вывести звук на другой компьютер, стало необходимо придумывать, например, звуковые серверы (NAS, PulseAudio). Для доступа к блочным устройствам стало необходимо придумывать различные специальные протоколы (iSCSI, AoE - ATA Over Eternet). Для доступа к учётным данным были придуманы NIS, LDAP, Kerberos. Для обмена файлами - HTTP, FTP, SMTP, POP3, IMAP. Для удалённого вызова процедур и взаимодействия объектов - RPC, CORBA, COM.

А ведь для доступа к любому устройству (звуковому устройству, графической плате, дисковому устройству, клавиатуре, мыши) по сети или просто для обмена информацией с другой системой можно было бы использовать единый интерфейс - интерфейс файловой системы. Протоколы бы от этого никуда не делись бы, но количество необходимых библиотек для работы по каждому протоколу стало бы гораздо меньше: достаточно было бы одного API доступа к файлам.

Авторы Unix поняли это слишком поздно. Когда они представили миру свою Plan 9, Unix уже оказался "достаточно хорош". То есть, с помощью уже имеющейся системы можно было решать большинство практических задач.

Архитектурные диверсии в Unix продолжаются и сейчас. Среди них можно назвать следующие:

1. Отрисовка шрифтов на стороне X-клиента. Стало невозможно использовать единый сервер шрифтов группой машин.

2. Игнорирование протокола XDMCP некоторыми Display Manager'ами, например slim.

3. Реестр. Вы уж простите, но это именно реестр. Настройки среды Gnome хранятся не в файлах, а в отдельном хранилище, доступ к которому осуществляется использованием специальной библиотеки через специальный демон.

4. Наличие HAL, управляющего правами доступа к устройствам и представляющее иерархию устройств в своём собственном виде,

5. API для доступа к файлам, продвигаемое Gnome. Программы, получающие доступ к файлам на дисках посредством этого API, похоже даже не монтируют диск в терминах Unix.

6. DRI - Direct Rendering Infrastructure. Эта штука позволяет рисовать на экране минуя X-сервер. С одной стороны, она кажется необходимой, т.к. протокол X - сетевой и поэтому непозволительно понижает производительность рисования на экране. А с другой стороны кажется этой самой диверсией, поскольку не позволяет программе, пользующейся DRI, обращаться единообразно к экрану локального компьютера и сетевого компьютера.

В настоящее время очарование Unix в значительной мере утрачено. Ныне это не та компактная стройная система, каковой она была с рождения. Сейчас практически любой Unix является нагромождением нелепостей в не меньшей мере, чем, например, Windows.

воскресенье, 6 июня 2010 г.

Продолжая читать Стругацких

После прошлой заметки я прочитал ещё несколько романов и повестей братьев Стругацких. Опишу впечатления.

Град обреченный

Действие романа происходит в единственном обитаемом городе непонятного мира, ограниченного со всех сторон многокилометровой высоты стенами или не меньшей глубины отвесными обрывами. Солнце над городом не встаёт и садится, а включается и выключается. В городе живут люди разных национальностей, которые на Земле жили примерно во второй половине двадцатого века. Все эти люди непонятно каким образом легко понимают друг друга, хотя каждый из них думает, что все вокруг говорят на его собственном родном языке: русский разговаривает с окружающими на русском, немец - думает что все вокруг говорят на немецком и т.д.

Все эти люди попали в этот город, согласившись на некий Эксперимент. В чём заключается суть эксперимента - объявлено не было. Время от времени в городе происходят различные непонятные вещи, люди в городе законодательно обязаны периодически менять работу.

Когда я приступил к чтению, мне вспомнилась книга Святослава Логинова "Многорукий бог далайна", которую я читал лет семь назад. Почему она мне вспомнилась? Действие обеих книг происходит в ограниченных стенками мирах, существующих в некоем "сферическом вакууме", то есть - не понятно где, то ли в воображении автора, то ли в другом измерении, то ли в моделируемой компьютером виртуальной реальности.

Однако, не смотря на всю бредовость мира, в нём живут вполне себе настоящие люди, каждый - со своим характером, своими жизненными стереотипами. Каждый из них пытается вписать происходящее вокруг в узкие рамки своего мышления, переделать окружающую действительность в привычное для каждого из них состояние. Можно сказать, что город этот является микроминиатюрой Земли. Бывший немецкий фашист стремится навести в городе порядок, укрепить боевую мощь, ожидая нападения неизвестных сил извне города. Бывший русский солдат по инерции продолжает думать, что в рамках Эксперимента строится новый, коммунистический рай. Еврея Изю не интересует построение нового порядка - ему просто интересно жить, изучать окружающий мир. В трудные, переломные моменты жизни человека, к нему может явиться Наставник, который поддержит, подбодрит и опять исчезнет.

Что же это за мир? На протяжении книги высказываются самые разные предположения. Возможно весь их мир представляет собой огромный аквариум, в котором высшие существа изучают людей. Возможно этот мир является одним из кругов Ада, который невозможно покинуть, а можно лишь перейти на следующий круг. Главные действующие лица разными путями приходят к власти и организуют экспедицию вовне города, в надежде выяснить форму поверхности их мира, примерные размеры мира, наличие потенциальных врагов и т.д. Из экспедиции в живых остаются два человека, которые находят райский город, но не остаются в нём, а продолжают странствия. В конце концов они найдут выход из этого мира, но вот куда же он приведёт - остаётся по-прежнему не ясным.

Книга хороша прежде всего не своим оригинальным миром, а внимательным изучением сути человека: о чём думает, чем он живёт, каков смысл его жизни. Абсурдность происходящего подталкивает людей к тому, чтобы задуматься об этом самим. Но задумываются далеко не все. Людям страшно задавать себе такие вопросы, они часто предпочитают жить не думая, предпочитают создать для себя привычный уклад жизни и жить им. А что если жизнь в этом мире бесконечна? Скоро ли тебе это надоест, в какой момент ты почувствуешь себя в аду? Прожив тысячу лет, десять тысяч? Видимо для того, чтобы начать задумываться, нужно как следует устать от однообразия и абсурда. Но стоит ли понимать это? Ведь впереди тебя всё равно ждут бесконечные скитания и всё тот же неизбежный абсурд! Кто прав, кто мудрее? Тот, кто думает о смысле жизни или всё-таки тот, кто пытается жить привычными истинами?

Отягощённые злом, или сорок лет спустя

Этот роман состоит из двух параллельных сюжетных линий, связь между которыми становится видна только ближе к концу. Видна явная аналогия между этим романом и романом Михаила Булгакова "Мастер и Маргарита". Действие романа Михаила Булгакова происходит в Москве первой половины двадцатого века. Действие романа Стругацких происходит в провинциальном городке Ташлы. Часть романа происходит во второй половине двадцатого века, часть - в первой половине двадцать первого. В буглаковском романе в Москву приезжает сатана, а в романе Стругацких в Ташлы приезжает демиург со своим верным помощником. Демиург этот возможно является одним из воплощений христианского господа бога, а точнее христианский бог - является одним из воплощений демиурга. Возможно демиург ранее воплощался в образе Иисуса Христа, а помощник его был апостолом Иоанном. Спустя два тысячелетия демиург воплощается совсем в другом, наводящем ужас, образе.

Итак, демиург снова воплотился на Земле. На сей раз его цель - найти людей, желающих изменить человеческое общество. Люди приносят ему свои проекты преобразования человечества, а демиург... не спешит помогать этим людям. В его съёмной квартире поселяются несколько таких людей, каждый из которых располагает своим проектом преобразования человечества. Что они так долго делают в его квартире - не понятно. Может быть демиург не доволен ими и заставляет людей дорабатывать свои проекты? Параллельно происходит другое действо: бывший апостол Иоанн, прожив долгую жизнь, занялся коллекционированием. Необычен предмет его коллекционирования - он выкупает у людей их души.

И вот однажды к демиургу приходит провинциальный учитель, на чём одна из линий повествования прерывается.

Вторая линия повествования рассказывает уже о жизни этого учителя после встречи с демиургом. Видимо провинциальный учитель пожелал достичь совершенства в педагогике или же стал основателем нового учения. Тем или иным образом, в городе появилось движение Флора - движение молодых людей, исповедующих возврат к природе.

Однако, там где новое соседствует со старым, неизбежен конфликт. Старое, обладая численным превосходством, побеждает, угнетает новое, в результате чего всё возвращается на круги своя. Видимо общество не может развиваться скачками, он должно развиваться постепенно, так чтобы новое не вступало в конфликт со старым, а было лишь немногим выше его. Когда старое отомрёт само собой, свершится один небольшой виток развития и уже то, что было новым, становится старым и в свою очередь должно уступить свою дорогу очередному новому.

Экспедиция в преисподнюю

Сказка авторства Аркадия Стругацкого для детей не понятной возрастной категории. Может быть именно в таком возрасте прививается любовь к научной фантастике? Я думаю, что сказка выглядела бы просто неотразимо в виде мультфильма вроде Тайны третьей планеты. Но мультфильма нет, а читать, к сожалению, не интересно.

Единственное, чем можно похвастаться после прочтения книги, так это тем, что я научился без запинки произносить имя шпиона, носимого с собой - "Ятуркенженсинхирв" :)

Повесть о дружбе и недружбе

Предновогодний сон заболевшего ангиной школьника. Добрый рассказ о дружбе. Прочитать вечерком от нечего делать - самое то.

Гадкие лебеди

Ещё одна попытка описать момент перехода от общества старой формации к новой.

Некий писатель Виктор Банев приезжает в родной город и обнаруживает, что в городе уже много лет не прекращаясь идёт дождь. В городе построен лепрозорий для генетически больных. У больных появляются тёмные круги вокруг глаз, из-за чего их болезни иногда называют очковой, на коже появляются синяки, опухлости и даже волдыри. Больных в городе называют мокрецами - они прекрасно чувствуют себя в местном климате.

Лепрозорий обнесён забором, колючей проволокой, его охраняют солдаты. Внутрь территории лепрозория не пускают никого, кроме мокрецов и детей. Дети, общающиеся с мокрецами, становятся не то вундеркиндами, не то просто акселератами - в свои небольшие годы они рассуждают подчас лучше взрослых.

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

В книге великолепно описывается контраст между новым обществом и старым. Старое общество - общество, элитой которого являются алкаши, развратники, бездельники, фашисты. Новое общество - общество равных, оно монолитно, не может жить без чтения, его цели - воспитание нового человека, изучение природы, разумное её использование.

Между старым и новым обществом разрывается писатель Банев. С одной стороны он понимает, что не может стать частью нового общества, а с другой - не может оставаться частью прежнего. Для него страшнее всего - самому стать не нужным.

В конце книги Банев направляется в новый, преобразившийся город, чтобы посмотреть на него, а затем вернуться к своей прежней жизни, которая хоть и противна ему, но понятна и привычна.

Вот и диалектике досталось!

Некоторые предметы в школе, а затем в институте у меня всегда вызывали отвращение. Отвращение это бывало интуитивным, неосознанным. Некоторые из этих предметов, а точнее - чуть менее, чем все, назывались науками, от чего отвращение принимало ещё более невыносимые формы.

В спорах с людьми, каковые иногда случаются, очень хочется аргументированно, взвешенно и без эмоций объяснить, почему некий предмет не является наукой. Рыночной макроэкономике уже досталось - я нашёл прекрасную иллюстрацию, коей уже поделился в заметке Как (не) работает рыночная экономика.

Теперь же я наткнулся на прекрасное объяснение, почему чушью является и диалектика: в заметке Диалектика объясняется бесполезность трёх законов диалектики.

Кстати, сам сайт тоже весьма интересен. Он посвящён вопросам на грани логики и психологии. Психологию, кстати, я тоже не приветствую, потому как у психологов на каждую психологическую проблему будет десяток толкований с точки зрения пяти-семи психологических школ: по Фрейду, по Юнгу и т.п. Да вы только полюбуйтесь на них: Школы психологии. Но при всём при этом, автор (Мирослав Войнаровский) не погружается в психологические учения, а рассматривает особенности человеческого мышления, которые приводят к неверным логическим выводам. Рассматриваются объяснения логических парадоксов с практической и математической точек зрения. В общем - рекомендую.

четверг, 3 июня 2010 г.

Обожаю командную строку!

Только с её помощью я могу на коленке написать нечто такое:

find . -name torrent | cut -d/ -f3 | sed -e 's/tor//g' - | \
sort -n | sed -e 's/^\(.*\)$/cp .\/ktorrent\/tor\1\/torrent \1.torrent/g' - | sh -

Что делает эта строчка?

Начну с начала. У KTorrent есть каталог, в котором хранится сохранённая сессия. Там же хранятся все torrent-файлы в каталогах типа ktorrent/torНОМЕР/torrent. Однажды KTorrent при добавлении очередного torrent-файла гавкнулся так сильно, что при каждом запуске моментально зависал, даже не отображая список torrent'ов. В результате этого я мог бы лишь удалять из каталога сессий файлы по одному и пытаться запустить KTorrent.

Но я решил забить на KTorrent и воспользоваться другими программами. Для этого мне нужно собрать все torrent-файлы в одном каталоге, чтобы потом их скопом добавить в новый torrent-клиент. В результате я написал приведённую выше строчку, которая обошла каталог сессии KTorrent, составила список torrent-файлов, вычленила номера torrent'ов, отсортировала их, сформировала для каждого torrent'а команду вида cp ./ktorrent/torНОМЕР/torrent НОМЕР.torrent и выполнила все эти команды в оболочке. Таким образом все torrent-файлы оказались собраны в одном месте.

Но и это ещё не всё. На работе я написал ещё несколько скриптов, помогающих мне в осуществлении плановой работы.

Например, следующий скрипт переименовывает пользователя в базе данных почтового сервера Postfix, переименовывает каталог с почтой и создаёт пересылку со старого адреса на новый, чтобы люди успели привыкнуть к новому адресу, прописать в адресные книги и т.п.

#!/bin/sh

MAILDIR='/var/mail/virtual'
DOMAIN='domain.ru'
USER=$1
USER_NEW=$2

if test x$USER = x -o x$USER_NEW = x
then
echo "Usage: rename_user.sh "
exit
fi

echo "Enter root password of mysql"

mysql -u root -p <<END
use mail;

update users set
login = '$USER_NEW@$DOMAIN',
maildir = '$DOMAIN/$USER_NEW/'
where login = '$USER@$DOMAIN';

insert into aliases(alias,rcpt)
values('$USER@$DOMAIN','$USER_NEW@$DOMAIN');

update aliases set
rcpt = '$USER_NEW@$DOMAIN'
where rcpt = '$USER@$DOMAIN';

END

mv $MAILDIR/$DOMAIN/$USER $MAILDIR/$DOMAIN/$USER_NEW

или ещё один скриптик, олицетворяющий вопиющий случай деревенской наколеночной автоматизации:

#!/bin/sh

TMP=/var/tmp/name
NAME=$1

echo $1 > $TMP
sed -f - $TMP > $TMP.1 <<END
s/ъа/ia/g
s/ъе/ie/g
s/ъё/ie/g
s/ъи/ii/g
s/ъй/ij/g
s/ъо/io/g
s/ъу/iu/g
s/ъы/iy/g
s/ъэ/ie/g
s/ъю/iyu/g
s/ъя/iya/g

s/ияА/iaA/g
s/ияБ/iaB/g
s/ияВ/iaV/g
s/ияГ/iaG/g
s/ияД/iaD/g
s/ияЕ/iaE/g
s/ияЁ/iaE/g
s/ияЖ/iaZ/g
s/ияЗ/iaZ/g
s/ияИ/iaI/g
s/ияЙ/iaJ/g
s/ияК/iaK/g
s/ияЛ/iaL/g
s/ияМ/iaM/g
s/ияН/iaN/g
s/ияО/iaO/g
s/ияП/iaP/g
s/ияР/iaR/g
s/ияС/iaS/g
s/ияТ/iaT/g
s/ияУ/iaY/g
s/ияФ/iaF/g
s/ияХ/iaH/g
s/ияЦ/iaT/g
s/ияЧ/iaC/g
s/ияШ/iaS/g
s/ияЩ/iaS/g
s/ияЫ/iaY/g
s/ияЭ/iaE/g
s/ияЮ/iaY/g
s/ияЯ/iaY/g

s/ия/ya/g
s/ий/y/g
s/ыя/y/g
s/ая/aya/g
s/яя/aya/g
s/ья/ya/g
s/ьи/ii/g
s/ью/ju/g
s/ье/ie/g
s/ьё/ie/g
s/ие/ie/g

s/а/a/g
s/А/A/g
s/б/b/g
s/Б/B/g
s/в/v/g
s/В/V/g
s/г/g/g
s/Г/G/g
s/д/d/g
s/Д/D/g
s/е/e/g
s/Е/E/g
s/ё/e/g
s/Ё/E/g
s/ж/zh/g
s/Ж/Zh/g
s/з/z/g
s/З/Z/g
s/и/i/g
s/И/I/g
s/й/j/g
s/Й/J/g
s/к/k/g
s/К/K/g
s/л/l/g
s/Л/L/g
s/м/m/g
s/М/M/g
s/н/n/g
s/Н/N/g
s/о/o/g
s/О/O/g
s/п/p/g
s/П/P/g
s/р/r/g
s/Р/R/g
s/с/s/g
s/С/S/g
s/т/t/g
s/Т/T/g
s/у/u/g
s/У/U/g
s/ф/f/g
s/Ф/F/g
s/х/kh/g
s/Х/Kh/g
s/ц/ts/g
s/Ц/Ts/g
s/ч/ch/g
s/Ч/Ch/g
s/ш/sh/g
s/Ш/Sh/g
s/щ/sch/g
s/Щ/Sch/g
s/ы/y/g
s/Ы/Y/g
s/э/e/g
s/Э/E/g
s/ю/yu/g
s/Ю/Yu/g
s/я/ya/g
s/Я/Ya/g

s/ь//g
s/ъ//g
END
cat $TMP.1
rm -f $TMP $TMP.1

Этот скрипт транскрибирует имя пользователя из русского написания в латинское, в соответствии с корпоративными правилами.

Вот примеры его работы:

$ ./standart_name.sh СтупинВА
StupinVA
$ ./standart_name.sh ЧернышковДЮ
ChernyshkovDYu

Есть правда ещё требования к длине логина и к буквам-инициалам, но скрипт делает 98% самой нудной работы, на которой легко ошибиться.

P.S. Совсем недавно я ещё писал о том, как можно сохранить одним скриптом все настройки сервера: Резервная копия настроек сервера

вторник, 18 мая 2010 г.

История строки User-Agent в браузерах

Любопытная статья История строки User-Agent в браузерах повествует о том, почему некоторые браузеры притворяются друг другом и почему все они притворяются браузером Mozilla.

понедельник, 17 мая 2010 г.

Common Lisp. Цикл против рекурсии

Пробуем писать простейшие циклы с помощью do. Циклы в большинстве случаев могут выполнять полезную работу только вместе с переменными, поэтому переменные, изученные в прошлых примерах, для освоения цикла будут как нельзя кстати.

1. Вычисления Факториала в цикле
;; Рекурсивное вычисление факториала
(defun fact (n)
       (if (= 1 n)
           1
           (* n (fact (- n 1)))))

;; Рекурсивное вычисление факториала
;; с использованием хвостовой рекурсии
(defun fact2 (counter &optional (val 1))
       (if (= counter 0)
           val
           (fact2 (- counter 1) (* val counter))))

;; Вычисление факториала с помощью цикла do
(defun fact3 (n)
       (let ((f 1))
            (do ((i 2 (+ i 1)))
                ((> i n) f)
                (setf f (* f i)))))

;;; Сравниваем результат вычислений и
;;; ресурсоёмкость трёх функций
(= (time (fact 20000))
   (time (fact2 20000))
   (time (fact3 20000)))
Результат выполнения:
Evaluation took:
  0.426 seconds of real time
  0.420026 seconds of total run time (0.400025 user, 0.020001 system)
  [ Run times consist of 0.064 seconds GC time, and 0.357 seconds non-GC time. ]
  98.59% CPU
  855,372,860 processor cycles
  303,248,336 bytes consed
Evaluation took:
  0.437 seconds of real time
  0.436027 seconds of total run time (0.436027 user, 0.000000 system)
  [ Run times consist of 0.044 seconds GC time, and 0.393 seconds non-GC time. ]
  99.77% CPU
  877,747,980 processor cycles
  339,314,808 bytes consed
Evaluation took:
  0.402 seconds of real time
  0.400025 seconds of total run time (0.380023 user, 0.020002 system)
  [ Run times consist of 0.076 seconds GC time, and 0.325 seconds non-GC time. ]
  99.50% CPU
  807,685,920 processor cycles
  303,254,160 bytes consed
T
Вариант вычисления при помощи цикла самый быстрый, на втором месте идёт рекурсивная функция, на третьем - рекурсивная с хвостовой рекурсией.

2. Вычисление чисел Фибоначчи
;; Вычисление чисел Фибоначчи рекурсией
(defun fib (num &key (a 1) (b 1))
       (if (= num 1)
           a
           (fib (- num 1) :a b :b (+ a b))))

;; Вычисление чисел Фибоначчи с использованием цикла do
(defun fib2 (n &key (a 1) (b 1))
       (cond ((= n 1) a)
             ((= n 2) b)
             (T (do ((i 3 (+ i 1)))
                    ((= i n) (+ a b))
                    (shiftf a b b (+ a b))))))

;;; Сравниваем результат вычислений и
;;; ресурсоёмкость функций
(= (time (fib 20000))
   (time (fib2 20000)))
Результат выполнения программы:
Evaluation took:
  0.030 seconds of real time
  0.032002 seconds of total run time (0.032002 user, 0.000000 system)
  [ Run times consist of 0.012 seconds GC time, and 0.021 seconds non-GC time. ]
  106.67% CPU
  60,564,250 processor cycles
  17,588,392 bytes consed
Evaluation took:
  0.025 seconds of real time
  0.024001 seconds of total run time (0.024001 user, 0.000000 system)
  [ Run times consist of 0.004 seconds GC time, and 0.021 seconds non-GC time. ]
  96.00% CPU
  48,908,280 processor cycles
  17,597,480 bytes consed
T
Вычисление с помощью циклов оказалось быстрее. Хотя, если производительность - не главное, то я выбрал бы рекурсивный вариант - он легче читается и красивее выглядит.

пятница, 14 мая 2010 г.

Продолжаем мучить Common Lisp

Продолжаю мучить Common Lisp, хотя ему всё равно - он железный, а вот себя я мучаю гораздо сильнее. Уж слишком головоломный язык, даже небольшой изученной мной частичке Common Lisp трудно уместиться в моей голове, это что-то находящееся за гранью моего предыдущего опыта.

1. Пересчёт секунд, минут и часов

Закрепляем уже пройденный материал, пытаясь применить уже известное в чуть-чуть более практической, приземлённой задаче.
;; Переводит часы, минуты и секунды в секунды
(defun hms-to-seconds (h m s)
       (+ (* h 3600) (* m 60) s))

;; Переводит секунды в часы, минуты и секунды
(defun seconds-to-hms (sec)
       (list (floor (/ sec 3600))
             (floor (/ (mod sec 3600) 60))
             (mod sec 60)))

;; Проверка правильности показаний часов:
;; часы не показывают отрицательные числа
;; а минуты и секунды не могут быть больше 59
(defun hms-ok (h m s)
       (and (>= h 0)
            (>= m 0)
            (>= s 0)
            (< m 60)
            (< s 60)))

;; Нормализовать часы, минуты и секунды:
;; перевести их в вид, пригодный для
;; отображения на часах
(defun normalize-hms (h m s)
       (seconds-to-hms (hms-to-seconds h m s)))

;; Перевести секунды в минуты,
;; возвращается количество полных минут
(defun seconds-to-minutes (sec)
       (floor (/ sec 60))) 

;; Перевести секунды в часы,
;; возвращается количество полных часов
(defun seconds-to-hours (sec)
       (floor (/ sec 3600)))

;; Получить показания секундной стрелки часов
(defun s-from-seconds (sec)
       (mod sec 60))

;; Получить показания минутной стрелки часов
(defun m-from-seconds (sec)
       (mod (floor (/ sec 60)) 60))

;; другой вариант одноимённой функции
;(defun m-from-seconds (sec)
;       (floor (/ (mod sec 3600) 60)))

;; Получить показания часовой стрелки часов
(defun h-from-seconds (sec)
       (floor (/ sec 3600)))

;; другой вариант одноимённой функции
;(defun seconds-to-hms (sec)
;       (list (h-from-seconds sec)
;             (m-from-seconds sec)
;             (s-from-seconds sec)))
2. Пример использования замыканий

Трудно объяснить всю нижеследующую магию простыми словами. Здесь используются анонимные функции (они же lambda), передача ссылки на функцию - это ещё можно понять. Но вот переменные в Common Lisp довольно необычны.

Я толком не усвоил терминологию, но своими словами могу сказать следующее: существуют глобальные переменные и локальные переменные. Глобальные переменные доступны из любого места программы, локальные - только в пределах области видимости.

Интересная особенность заключается в том, что можно в любом месте программы создать дополнительную область видимости, внутри которой переопределить значение переменной. Это делается с помощью оператора let. Все обращения к этой переменной внутри блока будут происходить к локальному же значению этой переменной. Вне оператора let переменная восстанавливает своё прежнее значение. Но при этом, в нижеследующем примере, анонимная функция сохраняет внутри себя переопределённую с помощью оператора let переменную и её значение. Это и называется замыканием. Очень необычно.
;;;; Пример использования замыканий

;; Функция, возвращающая фукцию-счётчик
;; Начальное значение счётчика - 0
(defun get-counter ()
       (let ((n 0))
            (function (lambda ()
                              (setf n (+ n 1))))))

;; Более лаконичный аналог предыдущей функции
;(defun get-counter ()
;       (let ((n 0))
;            #'(lambda ()
;                      (incf n))))

;; Переменная с первой функцией-счётчиком
(setf counter1 (get-counter))

;; Переменная со второй функцией-счётчиком
(setf counter2 (get-counter))

;; Более лаконичный вариант двух предыдущих присваиваний
;(setf counter1 (get-counter)
;      counter2 (get-counter))

;;; Попеременно вызываем счётчики
;;; Счётчики при каждом вызове увеличиваются на 1
(funcall counter1)

(funcall counter2)

(funcall counter1)

(funcall counter1)

(funcall counter1)

(funcall counter2)
В этом примере функция counter1 будет наращивать значение своего счётчика, а функция counter2 - значение своего.

3. Чуть более сложный пример использования замыканий

Здесь уже используются ассоциативные массивы, а функция get-counter-methods возвращает в ассоциативном массиве три функции, замкнутые на одной переменной.
;;;; Ещё один пример использования замыканий

;; Функция возвращает ассоциативный список
;; из трёх функций, замкнутых на одну переменную
(defun get-counter-methods ()
  (let ((n 0))
    (list
     :increase #'(lambda () (incf n))
     :decrease #'(lambda () (decf n))
     :value #'(lambda () n))))

;; Создаём счётчик, содержащий ассоциативный
;; список трёх функций
(setf counter (get-counter-methods))

;;; Далее вызываем функции и следим
;;; за состоянием счётчика
(funcall (getf counter :increase))

(funcall (getf counter :value))

(funcall (getf counter :decrease))

(funcall (getf counter :value))

Light Bot

Предлагаю поиграть в Light Bot. Игрушка для программистов. Мой результат: на всю игру я потратил 198 команд.

среда, 12 мая 2010 г.

Продолжаем упражняться в Common Lisp

На этот раз я пробую освоить переменное количество аргументов функций, именованные аргументы и значения по умолчанию.

1. Вычисление квадратного корня с необязательным указанием точности и приближённого значения корня
;;;; Приближённое вычисление квадратного корня

;; Модуль числа
(defun abs-value (num)
(if (> num 0.0)
num
(- 0.0 num)))

;; Логическая функция, возвращающая истину,
;; если числа a и b отличаются друг от друга
;; менее, чем на precision
(defun precision-ok (a b &optional (precision 0.001))
(< (abs-value (- a b)) precision))

;; Рекурсивная функция, использующая root
;; как приближённое значение корня num.
;; Функция вызывает сама себя до тех пор,
;; пока точность результата не достигнет precision
;; По умолчанию использует 1.0 в качестве приближённого
;; значения корня и 0.001 как значение точности
(defun square-root (num &optional (root 1.0))
(if (precision-ok num (* root root))
root
(square-root num (/ (+ (/ num root) root) 2))))

;; Вычисление квадратного корня 25
(square-root 25.0)

;; Вычисление квадратного корня с указанием его
;; приближённого значения
(square-root 25.0 3.0)

Этот вариант программы плох тем, что нельзя указать при вычислении корня необходимую точность результата. Поэтому перепишем программу в следующем виде:

2. Вычисление квадратного корня с необязательным указанием точности и приближённого значения корня
;;;; Приближённое вычисление квадратного корня

;; Модуль числа
(defun abs-value (num)
(if (> num 0.0)
num
(- 0.0 num)))

;; Логическая функция, возвращающая истину,
;; если числа a и b отличаются друг от друга
;; менее, чем на precision
(defun precision-ok (a b precision)
(< (abs-value (- a b)) precision))

;; Рекурсивная функция, использующая root
;; как приближённое значение корня num.
;; Функция вызывает сама себя до тех пор,
;; пока точность результата не достигнет precision
;; По умолчанию использует 1.0 в качестве приближённого
;; значения корня и 0.001 как значение точности
(defun square-root (num &optional (root 1.0) (precision 0.001))
(if (precision-ok num (* root root) precision)
root
(square-root num (/ (+ (/ num root) root) 2) precision)))

;; Вычисление квадратного корня 25
(square-root 25.0)

;; Вычисление квадратного корня с указанием его
;; приближённого значения
(square-root 25.0 3.0)

;; Вычисление квадратного корня с указанием его
;; приближённого значения и необходимой точности
(square-root 25.0 3.0 0.00001)

По-моему гораздо удобнее. Однако если мы хотим указать точность, то необходимо также указать и приближённое значение корня. Исправим это при помощи именованных аргументов.

3. Вычисление квадратного корня с необязательным указанием точности или приближённого значения корня
;;;; Приближённое вычисление квадратного корня

;; Модуль числа
(defun abs-value (num)
(if (> num 0.0)
num
(- 0.0 num)))

;; Логическая функция, возвращающая истину,
;; если числа a и b отличаются друг от друга
;; менее, чем на precision
(defun precision-ok (a b precision)
(< (abs-value (- a b)) precision))

;; Рекурсивная функция, использующая root
;; как приближённое значение корня num.
;; Функция вызывает сама себя до тех пор,
;; пока точность результата не достигнет precision
;; По умолчанию использует 1.0 в качестве приближённого
;; значения корня и 0.001 как значение точности
(defun square-root (num &key (root 1.0) (precision 0.001))
(if (precision-ok num (* root root) precision)
root
(square-root num
:root (/ (+ (/ num root) root) 2)
:precision precision)))

;; Вычисление квадратного корня 25
(square-root 25.0)

;; Вычисление квадратного корня с указанием его
;; приближённого значения
(square-root 25.0 :root 3.0)

;; Вычисление квадратного корня с указанием
;; необходимой точности
(square-root 25.0 :precision 0.000001)

;; Вычисление квадратного корня с указанием его
;; приближённого значения и необходимой точности
(square-root 25.0 :precision 0.000001 :root 25.0)

Вот так-то. Теперь можно просто вычислить корень, можно вычислить с указанием необходимой точности, можно вычислить с указанием приближённого значения корня и, наконец, можно вычислить корень указав и необходимую точность и приближённое значение корня.

4. Вычисление квадратных корней списка чисел

Дополним программу из предыдущего пункта следующей функцией:
;;Вычисление квадратных корней списка чисел
(defun square-roots (&rest rest)
(if (eql rest nil)
nil
(cons (square-root (car rest))
(apply (function square-roots) (cdr rest)))))

;; Вычисление корней 25, 64 и 121
(square-roots 25.0 64.0 121.0)

Или можно записать немного короче, заменив оператор function на его сокращённую запись:

;; То же самое, но с использованием краткой записи
;; оператора function
(defun square-roots (&rest rest)
(if (eql rest nil)
nil
(cons (square-root (car rest))
(apply #'square-roots (cdr rest)))))

;; Вычисление корней 25, 64 и 121
(square-roots 25.0 64.0 121.0)

5. Вычисление чисел Фибоначчи

Именованные аргументы со значением по умолчанию можно использовать и для сокращения других программ. Например, уже рассмотренной ранее программы для вычисления чисел из ряда Фибоначчи:
;;;; Вычисление 20000-го числа в ряду Фибоначчи

;; Рекурсивная функция, вычисляющая число Фибоначчи
;; Вызывает себя num раз, используя a и b в качестве
;; двух предыдущих чисел в ряду
(defun fib (num &key (a 1) (b 1))
(if (eql num 1)
a
(fib (- num 1) :a b :b (+ a b))))

;; Вычисление 20000-го числа в ряду Фибоначчи
(fib 20000)

;; То же самое
(fib 20000 :a 1 :b 1)

6. Вычисление числа Фи ("Золотого сечения")
;; Вычисление числа Фи
;; Совмещённое вычисление двух последовательных
;; чисел в ряду Фибоначчи с последующим делением
;; следующего числа на предыдущее
(defun phi (&key (num 200) (a 1) (b 1))
(if (eql num 1)
(* 1.0 (/ b a))
(phi :num (- num 1) :a b :b (+ a b))))

(phi)

7. Вычисление факториала

И даже вычисление факториала, написанное в расчёте на оптимизацию хвостовой рекурсии, можно переписать в подобном же виде:

;;;; Вычисление факториала 20000

;; Вычисление факториала с применением хвостовой рекурсии
(defun fact (counter &optional (val 1))
(if (eql counter 0)
val
(fact (- counter 1) (* val counter))))

;; Вычисляем факториал 20000
(fact 20000)

вторник, 11 мая 2010 г.

Немножко упражнений на Common Lisp

Решил поупражняться тут в Lisp'е, пописать математических функций в функциональном же стиле.

1. Вычисление квадратного корня

Я специально определил собственный вариант функции abs, мне так интереснее :)

;;;; Приближённое вычисление квадратного корня

;; Модуль числа
(defun abs-value (num)
(if (> num 0.0)
num
(- 0.0 num)))

;; Логическая функция, возвращающая истину,
;; если числа a и b отличаются друг от друга
;; менее, чем на precision
(defun precision-ok (a b precision)
(< (abs-value (- a b)) precision))

;; Рекурсивная функция, использующая root
;; как приближённое значение корня num.
;; Функция вызывает сама себя до тех пор,
;; пока точность результата не достигнет precision
(defun square-root-iter (num root precision)
(if (precision-ok num (* root root) precision)
root
(square-root-iter num (/ (+ (/ num root) root) 2) precision)))

;; "Лицо" функции вычисления квадратного корня
;; Использует 1.0 в качестве приближённого значения корня
;; и точность 0.001
(defun square-root (num)
(square-root-iter num 1.0 0.001))

;; Вычисление квадратного корня 25
(square-root 25.0)

2. Вычисление числа из ряда Фибоначчи

Для примера я решил вычислить двдацатитысячное по порядку число в ряду Фибоначчи.

;;;; Вычисление 20000-го числа в ряду Фибоначчи

;; Рекурсивная функция, вычисляющая число Фибоначчи
;; Вызывает себя num раз, используя a и b в качестве
;; двух предыдущих чисел в ряду
(defun fib-iter (a b num)
(if (eql num 1)
a
(fib-iter b (+ a b) (- num 1))))

;; "Лицо" функции вычисления числа Фибоначчи
(defun fib (num)
(fib-iter 1 1 num))

;; Вычисление 20000-го числа в ряду Фибоначчи
(fib 20000)

3. Вычисление числа Фи ("Золотого сечения") двумя способами

Сначала я воспользовался для вычислений уже полученной в прошлом примере функцией для вычисления чисел Фибоначчи, а затем написал второй вариант функции, более оптимизированный.

;;;; Сравнение двух способов вычисления числа Фи
;;;; - "Золотого сечения"

;; Рекурсивная функция, вычисляющая число Фибоначчи
;; Вызывает себя num раз, используя a и b в качестве
;; двух предыдущих чисел в ряду
(defun fib-iter (a b num)
(if (eql num 1)
a
(fib-iter b (+ a b) (- num 1))))

;; "Лицо" функции вычисления числа Фибоначчи
(defun fib (num)
(fib-iter 1 1 num))

;; Вычисление числа Фи через два вызова функции,
;; вычисляющей число в ряду Фибоначчи
(defun phi ()
(* 1.0 (/ (fib 2000) (fib 1999))))

;; Вычисление числа Фи
;; Совмещённое вычисление двух последовательных
;; чисел в ряду Фибоначчи с последующим делением
;; следующего числа на предыдущее
(defun phi2-iter (a b num)
(if (eql num 1)
(* 1.0 (/ b a))
(phi2-iter b (+ a b) (- num 1))))

;; "Лицо" функции вычисления числа Фи
(defun phi2 ()
(phi2-iter 1 1 2000))

;; Сравниваем результаты вычисления обеих функций,
;; попутно измеряя время, потраченное на вычисления
;; Первая функция должна быть медленнее в 2 раза
;; второй
(eql (time (phi)) (time (phi2)))

А вот и результаты работы программы:

Evaluation took:
0.001 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
0.00% CPU
2,279,699 processor cycles
400,944 bytes consed
Evaluation took:
0.001 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
0.00% CPU
1,470,207 processor cycles
204,584 bytes consed
T

Первая функция не только отработала медленнее, но и затребовала для своего выполнения почти в два раза больше памяти.

Сравнение скорости вычисления факториала на Scheme и Common Lisp

Scheme

Рекурсивное вычисление факториала на Scheme:
(define (fact n)
(if (= n 0)
1
(* n (fact (- n 1)))))

(fact 20000)

Итеративное вычисление факториала на Scheme:
(define (fact n)
(fact-iter 1 n))

(define (fact-iter val counter)
(if (= counter 0)
val
(fact-iter (* val counter) (- counter 1))))

Теперь создаём две программы, в первой из которых определяется рекурсивный вариант функции вычисления факториала, а во второй - итеративный. Добавляем в каждый из файлов вычисление факториала 20000:
(= 1 (fact 20000))

Я намеренно добавил сравнение результата вычисления с единицей, дабы избежать потерь времени на перевод числа в десятичную систему и вывод результата на экран.

Запускаем обе программы следующим образом и получаем время выполнения каждой из них:
time mit-scheme < fact.scheme > /dev/null ; time mit-scheme < fact2.scheme > /dev/null

real    0m3.760s
user    0m3.712s
sys     0m0.048s

real    0m3.379s
user    0m3.344s
sys     0m0.036s

То было на MIT'овской реализации, а теперь попробуем на PLT:
time plt-r5rs < fact.scheme > /dev/null ; time plt-r5rs < fact2.scheme > /dev/null

real    0m1.363s
user    0m1.256s
sys     0m0.108s

real    0m1.235s
user    0m1.152s
sys     0m0.080s

Рекурсивный код оказался немного быстрее в обоих случаях. Реализация PLT обгоняет MIT'овскую на этой задаче.

Common Lisp

Рекурсивное вычисление факториала на Common Lisp:
(defun fact (n)
(if (eql n 0)
1
(* n (fact (- n 1)))))

(fact 20000)

Итеративное вычисление факториала в Common Lisp. Процесс вычисления факториала происходит итеративно за счёт применения в компиляторе оптимизации хвостовой рекурсии:
(defun fact (n)
(fact-iter 1 n))

(defun fact-iter (val counter)
(if (eql counter 0)
val
(fact-iter (* val counter) (- counter 1))))

(fact 20000)

Программа для сравнения рекурсивного и итеративного вариантов вычисления факториала:
;;; Итеративное вычисление факториала.
;;; Ожидается именно итеративное вычисление за счёт возможности
;;; применить хвостовую рекурсию
(defun fact (n)
(fact-iter 1 n))

(defun fact-iter (val counter)
(if (eql counter 0)
val
(fact-iter (* val counter) (- counter 1))))

;;; Рекурсивное вычисление факториала.
(defun fact2 (n)
(if (eql n 0)
1
(* n (fact2 (- n 1)))))

;;;; Пробуем сравнить оба варианта вычисления по идентичности полученного
;;;; результата и времени выполнения
(eql (time (fact 20000))
(time (fact2 20000)))

(quit)

Здесь сравнивая результаты вычисления между собой я одновременно выполняю правильность обеих функций и избегаю перевода результатов вычислений в десятичную систему и вывода результатов на экран.

Результат выполнения программы:
Evaluation took:
0.408 seconds of real time
0.408026 seconds of total run time (0.392025 user, 0.016001 system)
[ Run times consist of 0.040 seconds GC time, and 0.369 seconds non-GC time. ]
100.00% CPU
819,948,580 processor cycles
339,303,792 bytes consed
Evaluation took:
0.383 seconds of real time
0.380023 seconds of total run time (0.376023 user, 0.004000 system)
[ Run times consist of 0.072 seconds GC time, and 0.309 seconds non-GC time. ]
99.22% CPU
769,179,220 processor cycles
303,251,800 bytes consed
T

Рекурсивный вариант оказался немного быстрее. Код тестировался на реализации SBCL, которая компилирует программу в машинный код платформы x86. Есть ещё реализация CMUCL, являющаяся предком SBCL, она компилирует программу в код собственной виртуальной машины. Не стоит говорить, что SBCL оказался быстрее, чем CMUCL.

Какие из всего этого можно сделать выводы? Либо в этих компиляторах оптимизация хвостовой рекурсии не выполняется, и поэтому итеративные функции показывают сравнимое и даже большее время вычисления, либо оптимизация выполняется настолько качественно, что компилятору удаётся свести рекурсивные функции к итеративным.

Как (не) работает рыночная экономика

Несколько недель назад наткнулся на такой вот сайт http://knukim-edu.kiev.ua/. Настолько элементарного изложения проблем современной рыночной экономики я ещё не видел. Это букварь макроэкономики для дошкольников. Обязательно прочитайте цитату. Вы поймёте, почему общепризнанная экономика не является наукой: микроэкономика и макроэкономика противоречат друг другу и вообще не могут создать непротиворечивую картину мира. Они не могут даже объяснить происходящего, а потому и речи быть не может о том, чтобы с их помощью вывести рецепты достижения равновесного положения экономики.

Элементарнейший пример:

Представьте себе "остров", в котором существует замкнутая экономика в виде одной деревни (Наша земля это тот же остров, только побольше), которая на заводике производит некую "еду" и продает ее в своем "сельпо". Вся наша деревня работает (возможно, сама с себя собирает налог, с которого кормит этой "едой" десяток пенсионеров, одного инвалида, детский садик и сторожа возле леса).

Работающие получают зарплату (часть ее уходит в виде налогов на содержание вышеперечисленных "нетрудоспособных" и "армии"), еда раскупается, все довольны.

Если кто-то из работающих "недоедает", - остается после работы на сверхурочные... производит больше "еды", получает больше зарплаты (и соответственно больше налогов и больше тратит в магазине). Ест и сам больше и больше остается другим (нетрудоспособным).

Идиллия. Деньги вращаются по кругу. Каждый работает ровно на столько, чтобы ему хватало.

А теперь представим, что у нашего заводика появился "хозяин".

Заводик за месяц произвел необходимое количество еды. Цена ее известна и устоялась, налоги уплачены, но... тут "хозяин" накидывает в цену 20% своей законной(!) прибыли, и выставляет "еду" на продажу в магазине.

Что происходит дальше?

Правильно. Продано будет только около ~ 80%. (Строго говоря, сам хозяин также является потребителем. Но весь избыток он все равно не съест. Лопнет.)

Потому что только на эту сумму выплачено зарплат и налогов. На остальные 20% деревня просто будет недоедать. Не потому что «еды» нет. Есть. Но купить ее, - нет денег. На их возмущение, он им порекомендует не лениться, а лучше и больше работать.

В следующем месяце хозяин произведет только 80% от количества необходимой еды. (Зачем больше? У него и те 20% остались нераспроданными.) Соответственно и его работающие будут заняты на 20% меньше времени, и естественно получат настолько же меньшую зарплату...

С каждым циклом производство будет сворачиваться.

В пределе этой сходящейся последовательности мы получим:

1. Остановившееся производство.

2. Полный склад товара ("еды"). (А мы еще удивлялись в Советском Союзе, откуда такое изобилие на витринах капитализма? Да просто денег у населения меньше, чем суммарная стоимость товара. Недальновидный Госкомцен, следивший за соответствием суммарной заработной платы – товарной массе, мог организовать изобилие витрин одним росчерком пера. Заодно и стимулы к интенсивной работе.)

3. Все деньги стекшиеся к "хозяину".

4. Голодную, безработную деревню, которой конечно можно посоветовать побольше работать, чтобы заработать денег, но особого смысла в этом нет. В нашей модели экономики просто не осталось денег. Они все выведены из нее и сосредоточились на одном из полюсов.

... пропущено ...

Можно ли что-то сделать, чтобы наша экономическая система не сколлапсировала а продолжала работать?

Да, можно.

1. Если хозяин, к примеру, купит у самого голодного «сарай с курями». Тот получит немного денег. Отдаст долги, отправит перевод матери, даст сынишке на карманные расходы… То есть в обороте нашей экономики снова появились деньги. В магазине купят еды. Значит, появился спрос. Раз есть спрос, - хозяин срочно наймет работников, раскрутит производство, появятся зарплаты и экономика оживет… - но!

Денег за сарай надолго не хватит. Через несколько циклов производства, чтобы его не останавливать, нужно будет покупать сарай уже у другого. Потом дома, землю… и так далее. Через какое-то количество времени, все снова вернется к состоянию «Великой Депрессии», но ни у кого уже не будет ни земли, ни недвижимости, ни имущества.

Можно ли в этой ситуации что-то сделать, чтобы продолжить производство еды?

Да, можно.

2. Можно еще взять денег в долг у хозяина, но взамен предложить ему свою долговую расписку.

Это снова оживит экономику, на какое-то время. Пока хозяину не надоест давать в долг. Он назовет всех дармоедами, лентяями, вечными должниками и остановит «кредит».

Вот тут уже сделать ничего нельзя. Если это остров, - то все. Можно считать, что пришел пушистый северный зверек. Даже натуральное хозяйство здесь уже невозможно, потому что у большинства не осталось ни товаров, ни собственности для обмена.


И вот тут уже неизбежна пролетарская революция. Опять повторится 1917 год. Вы понимаете? Если законными способами не забирать деньги у самого богатого и не возвращать их снова в обращение, то остаётся только революция.

Почитайте статью по ссылке, там есть ещё очень много интересного. Читать, правда, тяжело и долго. Возможно я со временем ещё выкину в свой блог несколько самых ёмких цитат.