<?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:voidbent</id>
  <title>Рассуждения о том, чего нет, и о смежных областях.</title>
  <subtitle>Vladimir Frolov</subtitle>
  <author>
    <email>voidbent@gmail.com</email>
    <name>Vladimir Frolov</name>
  </author>
  <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/"/>
  <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom"/>
  <updated>2008-07-02T20:47:33Z</updated>
  <lj:journal username="voidbent" type="personal"/>
  <link rel="service.feed" type="application/x.atom+xml" href="http://voidbent.livejournal.com/data/atom" title="Рассуждения о том, чего нет, и о смежных областях."/>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:53230</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/53230.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=53230"/>
    <title>Google C++ Style Guide</title>
    <published>2008-07-02T20:45:01Z</published>
    <updated>2008-07-02T20:47:33Z</updated>
    <category term="c++"/>
    <category term="programming"/>
    <category term="coding standard"/>
    <content type="html">&lt;a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml"&gt;Google C++ Style Guide&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Из смешного:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Do not overload operators except in rare, special circumstances.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Prefer small and focused functions.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;All parameters passed by reference must be labeled const.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;We do not allow default function parameters.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;We allow use of friend classes and functions, within reason.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;We do not use C++ exceptions.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;We do not use Run Time Type Information (RTTI).&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Constant Names: Use a k followed by mixed case: kDaysInAWeek.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Из того, что понравилось:&lt;ul&gt;&lt;li&gt;Spaces vs. Tabs: Use only spaces, and indent 2 spaces at a time.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Общие впечатления: Слишком много фраз, типа "whenever it makes sense", которые для coding guide-а губительны. Слишком много воды.&lt;br /&gt;&lt;br /&gt;Моя оценка coding guide-у: 3 с плюсом.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:52727</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/52727.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=52727"/>
    <title>Об организации пересылки сообщений в параллельных языках</title>
    <published>2008-07-01T21:10:14Z</published>
    <updated>2008-07-01T21:10:14Z</updated>
    <category term="programming"/>
    <category term="parallelism"/>
    <content type="html">Существует 2 очевидных способа представить в языке Message Passing:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;В виде конструкции, похожей на switch-case в обыкновенных языках. Подход, выбранный в Erlang.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Заявить, что вызовы методов у объекта это и есть на самом деле message passing. Если происходит вызов для пассивного объекта, то метод этот сапускается тут-же в вызвавшем потоке. Если вызов происходит для активного объекта, то происходит message passing уже между процессами.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;И тот и тот способ обладают преимуществами и недостатками, которые не дают сделать однозначный выбор в пользу одного из подходов. Первый подход перечёркивает весь полиморфизм, зато мы будем иметь место в коде, про которое мы сможем сказать: "Смотрите, а вот здесь наш процесс получает сообщение, потом сразу-же параллельно его обрабатывает, а сам тем временем получает ещё одно. А вот здесь, в другом процессе, вот тут в коде, происходит получение сообщения и тут же lock вокруг обработки этого сообщения". Это очень хорошо, потому что это приводит к локализации в коде важных с точки зрения системы аспектов.&lt;br /&gt;&lt;br /&gt;Во втором способе наоборот. Происходит полнейшая делокализация message passing-а по всему коду процесса, что может привести к зверским ошибкам, зато открываются возможности, для организации полиморфизма на базе message passing-а.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:52353</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/52353.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=52353"/>
    <title>LHC</title>
    <published>2008-07-01T20:11:48Z</published>
    <updated>2008-07-01T20:11:48Z</updated>
    <category term="жизнь"/>
    <content type="html">&lt;span class='ljuser' lj:user='sharpc' style='white-space: nowrap;'&gt;&lt;a href='http://sharpc.livejournal.com/profile'&gt;&lt;img src='http://p-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://sharpc.livejournal.com/'&gt;&lt;b&gt;sharpc&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; проводит &lt;a href="http://sharpc.livejournal.com/26697.html"&gt;ликбез по вопросу LHC&lt;/a&gt;. Интересненько почитать.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:52125</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/52125.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=52125"/>
    <title>real time computing</title>
    <published>2008-06-27T21:55:58Z</published>
    <updated>2008-06-27T21:55:58Z</updated>
    <category term="real time"/>
    <category term="multithreading"/>
    <category term="programming"/>
    <category term="parallelism"/>
    <content type="html">Моя модель обладает большой robustness и failure tolerance. Это хорошо. Но вся работа не будет иметь смысла до тех пор, пока я не докажу, что модель применима для real time систем. Как это вообще можно доказать я сейчас слабо себе представляю.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:51763</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/51763.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=51763"/>
    <title>optimal vs massive parallelism</title>
    <published>2008-06-27T21:51:24Z</published>
    <updated>2008-06-27T21:52:48Z</updated>
    <category term="multithreading"/>
    <category term="programming"/>
    <category term="parallelism"/>
    <content type="html">Моя модель позволяет автоматически распараллеливать как функциональный так и императивный код почти в любом месте. Естественно распараллеливать в каждом месте, где это можно сделать будет не оптимально, и не имеет смысла. Отсюда я определяю термин optimal parallelism, задача которого в отличие от massive parallelism-а распараллеливать код там, где это выгодно с точки зрения производительности. На сколько я понимаю задачу определения в каком месте лучше распараллеливать код можно решить при помощи эвристик, но это существенно усложнит имплементацию языка. Интересно, а что если попробовать решить эту задачу "жадным" методом? На сколько такой метод будет менее оптимален чем эвристики?&lt;br /&gt;&lt;br /&gt;Жадный алгоритм я представляю примерно так. Определяется количество процессоров n и создаётся пул x*n потоков. (Я так прикидываю х будет равен что-то около двух). Первый поток начинает исполнять программу.&lt;br /&gt;- Каждый свободный поток сигналит о том, что можно начинать распараллеливание.&lt;br /&gt;- Поток выполняется время delta t и распаралеливается если другие потоки об этом сигнаят.&lt;br /&gt;- Если есть свободные потоки, то распараллеливается тот поток, который дольше всех не распараллеливался, в том случае если он уже отработал время больше чем delta t.&lt;br /&gt;- Если поток завершил вычисления, то он "отдыхает" - спит время delta t и потом сигнализирует о том, что он готов снова начать работу.&lt;br /&gt;&lt;br /&gt;Была бы моя модель реализована, можно было-бы даже измерить оптимальные значения x и delta t.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:51612</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/51612.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=51612"/>
    <title>Статическая проверка race condition-ов.</title>
    <published>2008-06-27T21:30:00Z</published>
    <updated>2008-06-27T21:30:00Z</updated>
    <category term="multithreading"/>
    <category term="programming"/>
    <content type="html">Интересно, а возможна ли типизация, котороая статически проверяет отсутствие или наличие race condition-ов. Типа не даёт слинковать 2 куска кода, если вместе они приводят к race condition-ам.&lt;br /&gt;&lt;br /&gt;Сейчас для меня проблема race condition-ов выглядит на столько имеющей динамическую природу, что мне такую систему типов представить очень сложно. По крайней мере обе модели ручного параллелизма, и data sharing и message passing подвержены race condition-ам в одинаковой степени и я не представляю как их отсутствие можно &lt;b&gt;гарантировать&lt;/b&gt; статически.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:51426</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/51426.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=51426"/>
    <title>Methods overloading в Java</title>
    <published>2008-06-15T19:43:22Z</published>
    <updated>2008-06-15T19:53:23Z</updated>
    <category term="oop"/>
    <category term="c++"/>
    <category term="programming"/>
    <category term="java"/>
    <content type="html">Methods overloading в Java – это рудимент. Это единственный тип compile time polymorphism-а который достался Java в наследство от C++. Все другие compile time polymorphism-ы, которых в C++ имеется в изобилии убрали, упрощая язык, а этот убрать не смогли.&lt;br /&gt;&lt;br /&gt;Изначально, Java дизайнилась как простой язык, гораздо проще С++, с низким порогом вхождения. Всё, усложняющее C++ было из Java нещадно вычищено. Дальше на архитекторов Java начал действовать такой мощный enforcement в виде 100%-й поддержки обратной совместимости, что изменить сейчас поведение methods overloading-а будет очень сложно.&lt;br /&gt;&lt;br /&gt;Я вижу следующие причины по которым methods overloading остался в Java единственным в своём роде, не смотря на то, что от всех остальных compile time polymorphism-ов отказались:&lt;br /&gt;1. methods overloading это единственный способ отличать один конструктор от другого, в том случае, если конструкторы не имеют своего имени (т.е. если они анонимные, как в C++ и Java).&lt;br /&gt;2. Реализация &lt;a href="http://en.wikipedia.org/wiki/Multiple_dispatch"&gt;мультиметодов&lt;/a&gt; усложнила бы язык (возможно даже по сравнению с C++), в то время как изначально перед разработчиками стояла задача упростить, а не усложнить язык.&lt;br /&gt;3. Архитекторы испугались, что нахождение правильного метода во время компиляции существенно замедлит язык. Сейчас я думаю это уже не актуально, и механизм такого поиска был бы похож на поиск нужного блока catch, но для Java 1.0 это было актуально. Хотя с другой стороны архитекторы Java не испугались снижения производительности, и сделали все методы без исключения виртуальными, а архитекторы C# испугались и не сделали.&lt;br /&gt;&lt;br /&gt;Что бы я делал на месте архитекторов Java, чтобы немного развеять тучи вокруг methods overloading-а? Скорее всего, что я бы добавил аннотацию, что то типа @RuntimeOverload которая бы означала, что подходящий для вызова метод надо искать не во время компиляции а во время выполнения, а так же позволять наследникам специфицировать методы предка по параметрам более конкретно (т.е. родитель может объявить метод с параметром Object, а потомок перегрузить его только в том случае если актуальным типом параметра во время выполнения будет String. Во всех остальных случаях будет вызываться метод предка).</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:51132</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/51132.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=51132"/>
    <title>robustness и failure tolerance</title>
    <published>2008-06-15T18:47:09Z</published>
    <updated>2008-06-15T18:51:00Z</updated>
    <category term="failure tolerance"/>
    <category term="functional programming"/>
    <category term="programming"/>
    <category term="robustness"/>
    <category term="imperative programming"/>
    <category term="erlang"/>
    <category term="parallelism"/>
    <content type="html">Я утверждаю, что если на основе &lt;a href="http://community.livejournal.com/ru_declarative/57626.html"&gt; моей модели&lt;/a&gt; реализовать язык, то у такого языка и robustness и failure tolerance будут гораздо выше, чем у Erlang. У которого, кстати, эти свойства стоят на первом месте в дизайне языка. Основную роль здесь в дизайне модели играет отказ от stack based execution-а для stateful code-а. Стоит также отметить, что у меня в модели не будет понятия exception. По крайней мере в таком виде, как мы его видим в дизайне современных языков в нём точно нет необходимости.&lt;br /&gt;&lt;br /&gt;И всё же за счёт чего происходит значительное увеличение robustness и failure tolerance?&lt;br /&gt;&lt;br /&gt;Рассмотрим код, не важно на императивном или функциональном языке, не важно использующий исключения или коды ошибок. Код выполняется следующим образом:&lt;br /&gt;&lt;pre&gt;
инициализация обработчика ошибок --&amp;gt; 
   функция A --&amp;gt;
      функция B --&amp;gt;
         фукнция C --&amp;gt;
            ошибка --&amp;gt;
         возврат в C(точка слома) --&amp;gt;
      возврат в B(точка слома) --&amp;gt;
   возврат в А(точка слома) --&amp;gt;
обработчик ошибки&lt;/pre&gt;&lt;br /&gt;В моей модели выполнение кода будет происходить следующим образом:&lt;br /&gt;&lt;pre&gt;инициализация обработчика ошибок --&amp;gt;
   процедура A --&amp;gt;
   процедура B --&amp;gt;
   процедура C --&amp;gt;
   ошибка --&amp;gt;
обработчик ошибки&lt;/pre&gt;&lt;br /&gt;В моей модели выполнение stateful code-а происходит прямолинейно, в то время как во всех других языках выполнение кода постоянно возвращается назад по стеку.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:50776</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/50776.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=50776"/>
    <title>Strong opinion weakly held</title>
    <published>2008-06-13T20:48:03Z</published>
    <updated>2008-06-13T20:48:03Z</updated>
    <category term="жизнь"/>
    <content type="html">Понравилась фраза - &lt;a href="http://www.codinghorror.com/blog/archives/001124.html"&gt;"strong opinion weakly held"&lt;/a&gt;.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:50656</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/50656.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=50656"/>
    <title>Локализируемость свойств программных систем</title>
    <published>2008-06-13T20:27:25Z</published>
    <updated>2008-06-13T20:51:09Z</updated>
    <category term="programming"/>
    <category term="paradigm"/>
    <content type="html">Когда то давно я высказывал такую мысль:&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://voidbent.livejournal.com/46104.html"&gt;"Любое, сколько нибудь важное с точки зрения бизнес логики, свойство программной системы должно быть локализированно в коде. Если языкам не хватает способов локализации свойств программных систем, то эти способы в языки надо добавить" © Я.&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;Теперь я высказываю следующую гипотезу: как бы много фичей в языке не было, всё равно будут находится свойства и атрибуты программных систем, которые не возможно лоализировать в коде средствами языка. Другими словами - универсальное средство локализации любых свойств не возможно. Однако это ни в коем случае не значит что надо забрасывать все попытки добавить в язык фичи, способствующие локализации различных свойств.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:50206</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/50206.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=50206"/>
    <title>Возвращаясь к С++ template methaprogramming-у.</title>
    <published>2008-06-13T20:16:12Z</published>
    <updated>2008-06-13T20:16:12Z</updated>
    <category term="c++"/>
    <category term="programming"/>
    <category term="template metaprogramming"/>
    <content type="html">Обоснования по поводу применимости С++ template methaprogramming-а звучат так: "Использование типов внутри реализации других типов есть hardcode. С++ template methaprogramming позволяет избавиться от этого вида hardcode-а и обеспечить параметризацию типами". Это - правда; так оно и есть.&lt;br /&gt;&lt;br /&gt;Проблема в том, что hardcode не всегда несёт вред. Во многих случаях hardcode выступает в виде фундамента программной системы. Более того, совсем без hardcode написать систему просто нельзя. Просто в одном случае это будет hardcode типов, а в другом случае (С++ template methaprogramming) это будет hardcode &lt;b&gt;имен&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Осталось теперь только разобраться, в каких случаях нам hardcode типов жизненно необходим, а в каких будет мешать. Есть конечный код (т.е. не библиотека а готовый к выполнению модуль), есть специализированные библиотеки, есть библиотеки общего назначения. По моему опыту, чем более общее назначение имеет библиотека (например STL), тем больше для её реализации подходит С++ template methaprogramming. Чем более у библиотеки назначение конкретное, тем больше нужно hardcode-ить типов при её реализации. В идеале С++ template methaprogramming отлично подходит для super-flexible super-scalable библиотек и вообще не подходит для конечного кода.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:50133</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/50133.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=50133"/>
    <title>Автовыведение типов.</title>
    <published>2008-05-22T19:48:34Z</published>
    <updated>2008-05-24T08:52:51Z</updated>
    <category term="typing"/>
    <category term="programming"/>
    <content type="html">У меня получилось абсолютно точно выразить словами своё отношение к автовыведению типов.&lt;br /&gt;&lt;br /&gt;Автовыведение типов должно быть представленно в IDE виде автоматического средства рефакторинга. В строго типизированный язык автовыведение типов нельзя добавлять ни в коем случае. Т.е. идеальное автовыведение типов я вижу в виде плагина к Eclipse-у. Такое отношение к автовыведению типов идеально вписывается в моё понимание типизации (сверх-строгая типизация, и мощные автоматические средства рефакторинга облегчающие жизнь с такой типизацией).&lt;br /&gt;&lt;br /&gt;Т.е. я должен писать: Object myvar = сложный generic; и Eclipse должен заменять мне Object на тип этого сложного generic-а.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:49436</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/49436.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=49436"/>
    <title>Функциональные языки? Спасибо, мне не нужно!</title>
    <published>2008-05-13T22:25:33Z</published>
    <updated>2008-05-13T22:26:44Z</updated>
    <content type="html">Оцените плиз текст по трёхбальной системе "хорошо, нормально, плохо".&lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;&lt;br /&gt;Я работаю Software Architect-ом и большинство своего времени на работе я провожу за преодолением сложности предметной области. Не архитектурной как можно было подумать, не алгоритмической, не математической, а именно сложности предметной области. Нашему продукту уже не один десяток лет и он перегружен требованиями. Код сложен из-за того, что он удовлетворяет огромному количеству требований. Из всех этих требований о половине уже никто ничего не помнит. Не известно когда они появились и зачем они нужны. Многих требований не сохранилось даже в письменном виде. Тем не менее код, по крайней мере старый, продолжает всем этим требованиям удовлетворять.&lt;br /&gt;&lt;br /&gt;У нас серьёзно поговаривают о том, чтобы начать параллельно всё переписывать с нуля. Знаете зачем? Для того чтобы избавится от той кучи никому не нужных старых требований, которым код всё ещё удовлетворяет. Из-за того, что код удовлетворяет огромной куче требований, его практически не возможно менять. Когда меняешь код, никогда не знаешь наперёд, ты выбрасываешь какое то требование, которое никому не нужно, либо же ты выбрасываешь требование, которому код начал удовлетворять неделю назад, по просьбе самого важного из клиентов.&lt;br /&gt;&lt;br /&gt;Не надо мне рассказывать о системах контроля версий. Когда у файла двести ревизий и при этом ещё двести было потеряно при переходе с одной системы контроля версий на другую восемь лет назад, не станешь каждый раз заглядывать в историю файла для того, чтобы понять, откуда какие требования берут начало. Не надо мне рассказывать о системах контроля требований. Я боюсь в эту систему заглядывать. В ней больше десяти тысяч требований, и это далеко не полный список. В эти требования попадают только самые важные из них. Нужны клиента проще понять, читая код, чем читая эти требования. Есть люди, которых называют Business Analyst-ы. Так вот они код читать не умеют и от безысходности научились читать и писать те каракули, которые хранит система контроля требований. Архитекторам, умеющим читать код, эти каракули чужды.&lt;br /&gt;&lt;br /&gt;Так вот ... мне на работе не нужны ни Haskell, ни Erlang, ни F#, ни C++ template metaprogramming, мне на работе хорошо и без них. Мне на работе нужна Java, в которой C++ template metaprogramming не возможен в принципе. У меня тогда отпадёт необходимость объяснять каждый раз молодым, почему в конкретно данной ситуации использование шаблонов не уместно. Генерики? Генерики и аннотации вместе взятые и близко не предоставляют той мощности, которую предоставляет template metaprogramming в том виде, в каком его предлагают для С++0х. Генерики – это естественное продолжение ООП в общем и типизации в частности. А template metaprogramming идёт в обход типизации, нарушая её, в обход удобству описания предметной области. Template metaprogramming как и Haskell как и Erlang даёт гибкость для тех решений, в которых я лично не нуждаюсь. В ущерб тем аспектам системы, которые для меня лично жизненно важны.&lt;br /&gt;&lt;br /&gt;Почему я отдаю приоритет императивным языкам? Всё очень просто. Я привык, что все предметы в окружающей меня действительности могут и должны меняться со временем. Я не нуждаюсь в том, чтобы у меня сначала отобрали возможность менять предметы, а потом дали какую то замену этому в виде монад. Я только что выпил чашку кофе. Чашка поменялась безо всяких монад. По крайней мере, в процессе того, как чашка становилась пустой, я этих монад не заметил. Я хочу программировать чашку точно так же, как я её воспринимаю. Даже в угоду производительности и масштабируемости я не могу пойти на то, чтобы между мной и чашкой была ещё какая-то монада. Мне хватает итераторов, которые есть в императивных языках, и которых нет в предметной области. Дополнительно к итераторам терпеть монады я не собираюсь.&lt;br /&gt;&lt;br /&gt;Функциональные языки и технологии предлагают мне решение от другой задачи. Они мне дают ответ на тот вопрос, который меня не волнует, и который для меня второстепенный. Я сталкиваюсь с алгоритмической сложностью раз в месяц и прекрасно преодолеваю её, используя старые дедовские императивные методы. Мне на работе не нужен С# 3.0 с его новым могучим автовыведением типов и ключевым словом var. Спасибо, я этого уже наелся, пытаясь понять, каким именно требованиям удовлетворяет шаблонный код на С++ в котором типы не указаны явно. Мне нужен старый добрый ООП. Он не для всех ситуаций хорош, но он был создан для преодоления именно сложности предметной области. Именно для того, в чём я нуждаюсь. LINQ отличная штука, но я не собираюсь из за неё терпеть в языке дополнительно автовыведение типов. Придут молодые и наавтовыводят столько типов, что потом за всю жизнь не разберёшься. &lt;br /&gt;&lt;br /&gt;Возможно, я бы и хотел работать в проекте, в котором алгоритмические требования и требования по производительности стоят на первом месте. Там бы мне пришлось использовать Erlang и радоваться тому, насколько хорошо моя система масштабируется на многопроцессорных и распределённых платформах. Но в текущем моём проекте мне не нужны ни Haskell, ни Erlang, ни вся остальная функциональная ересь вместе взятая. Производительность для меня не самый важный из атрибутов качества системы. Важный конечно, но основные риски связанны далеко не с тем, что наша система не производительна. Основные риски связанны с тем, что мы в систему новые требования вводим очень медленно. И мне нужны средства, которые помогают преодолевать сложность предметной области. Я не хочу в процессе преодоления этой сложности отвлекаться ещё и на какие то функциональные заморочки.&lt;br /&gt;&lt;br /&gt;ООП открыло ногой дверь в mainstream из-за того, что оно помогало преодолевать сложность предметной области. По началу ООП критиковали из-за того, что оно не делает программы ни компактнее, ни быстрее. Как оказалось ни то ни другое для ООП не было важным. Важным было то, что ООП позволяло программировать чашку, точно также как я её вижу.&lt;br /&gt;&lt;br /&gt;Не смотря на то, что первые реализации сборщика мусора были чудовищны по производительности, не смотря на то, что эти реализации были сделаны по принципу «stop the world» и не умели обращаться с циклическими зависимостями, сборка мусора открыла дверь в mainstream ногой, вошла в mainstream и осталась там навсегда. Сборка мусора избавляла программиста от ручного управления памятью. В реальном мире актёры и активные объекты нигде и никогда никакой памятью не управляют, поэтому этого не нужно нам делать и в языках программирования. Современные реализации сборки мусора по производительности ушли далеко от своих первобытных собратьев, однако это абсолютно не важно. Производительность при сборке мусора это уже дело десятое, а основное это то, что повысилась выразительность и читаемость кода.&lt;br /&gt;&lt;br /&gt;Я так понимаю, что точно также откроет дверь в mainstream ногой и технология, которая будет избавлять программиста от ручного распараллеливания своего кода. И у меня возникает стойкое предчувствие, что эта технология будет называться не Erlang.&lt;br /&gt;&lt;br /&gt;И в этом месте, что я ожидаю от mainstream-а новых выразительных языков. И новым выразительным языком будет далеко не Haskell, которому место в докторских диссертациях по алгоритмическому анализу, но не в mainstream-е. Все серьёзные и решённые алгоритмические проблемы, с которыми столкнулось человечество можно пересчитать по пальцам. Алгоритмических проблем конечно в науке много, но проблем во всех предметных областях несоизмеримо больше.&lt;br /&gt;&lt;br /&gt;Если для повышения выразительности нужно будет сделать эти языки тьюринг-неполными, придётся это сделать, никуда не денешься. Придётся отказаться от алгоритмической мощности новых языков в угоду выразительности.&lt;br /&gt;&lt;br /&gt;Но как же так? Ведь программа, написанная на Haskell, получается гораздо короче, чем аналогичная, написанная на той же, восхваляемой мной, Java? Да, это правда. Но ведь вы предпочитаете читать текст в разархивированном виде, не смотря на то, что в заархивированном zip-ом виде он занимает гораздо меньше места. Так и я предпочитаю читать незаархивированный оригинал текста, а не заниматься автоподстановкой типов в голове. Я не компилятор. Возможно, компилятору это и просто автовывести тип какого-то там выражения, а мне, обычному человеку, это очень сложно. Мне надо для этого открывать много файлов, смотреть, вникать. У компилятора на автовыведение типа какого то выражения, может, уйдёт пол секунды, в то время как у меня на то же самое уйдёт неделя. Мне гораздо проще, когда возле выражения сразу написан его тип, и мне самому уже не надо ничего выводить. Мне проще когда всё уже выведено, и когда мне самому не надо заниматься разархивацией требований, заключённых в коде. Возможно, в будущем будут системы контроля версий, которые будут сами заниматься автовыведением типов, и будут предоставлять разные версии исходников для чтения и для записи, возможно. Но до тех пор, пока таких систем контроля версий не появилось, я отказываюсь заниматься автовыведением типов в голове.&lt;br /&gt;&lt;br /&gt;Я не спорю с тем, что с функциональными языками связана особая романтика. Эта же романтика связана и с high performance computation-ами и с massive parallelism-ом. Эта романтика заставляет людей учить языки если не Unlambda то, по крайней мере, Prolog. Чем больше я изучал Unlambda и комбинаторную логику, чем больше я изучал Prolog и логическое программирование, тем больше я понимал, что им место дома, а не на работе. А на моей работе место Java c её предсказуемым неромантичным ООП и сборкой мусора.&lt;br /&gt;&lt;br /&gt;Есть, однако, и работы, на которых место Haskell-у и Erlang-у. Я слышал о том, что есть весьма удачная реализация jabber server-а на Erlang-е. Для меня это абсолютно не удивительно. Собственно Erlang то и был спроектирован для телекоммуникаций. Не удивительно, что Erlang справился на-отлично, с таким видом коммуникаций, как Instant Messaging. Очень важно понимать, для каких задач Erlang подходит, а для каких нет. Не верьте, что Erlang подходит для большинства задач. Erlang, в отличие от Java, язык не универсальный, он concurrent-oriented, и для большинства задач он, как раз, не подходит.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:49386</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/49386.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=49386"/>
    <title>clen (Clipboard Enhanced)</title>
    <published>2008-04-29T20:30:26Z</published>
    <updated>2008-04-29T20:30:26Z</updated>
    <category term="clipboard"/>
    <category term="programming"/>
    <category term="autohotkey"/>
    <content type="html">Я пару месяцев назад написал &lt;a href="http://code.google.com/p/clen"&gt;clen (Clipboard Enhanced)&lt;/a&gt;, и вот решил его выложить на критику общественности. Clen - это скрипт для &lt;a href="http://www.autohotkey.com"&gt;AutoHotkey&lt;/a&gt;. Сейчас clen мне кажется таким базовым, что я трудно себе представляю как без этого вообще можно программировать.&lt;br /&gt;&lt;br /&gt;clen - это скрипт, который предоставляет много буферов обмена. clen состоит из 2-х частей, статической и динамической.&lt;br /&gt;&lt;br /&gt;Статическая часть clen это 10 постоянных буферов обмена в добавок к одному стандартному. Копировать в один из статических буферов обмена можно нажав комбинацию Left Win Key + цифра (от 1 до 0). Вставить из одного из статических буферов обмена можно нажав комбинацию Right Win Key + цифра. Посмотреть содержимое статических буферов обмена (в виде всплывающей из трея подсказки) можно нажав просто Right Win Key.&lt;br /&gt;&lt;br /&gt;Динамическая часть clen может быть использована как стек или очередь значений. Копировать в начало очереди можно нажав Left Win Key + Insert. Вставить из начала очереди можно нажав Right Win Key + Insert. Вставить из конца очереди (т.е. использовать clen как стек) можно нажав Right Win Key + Delete. Посмотреть содержимое динамической очереди можно нажав просто Left Win Key. В отличие от статической части, после вставки из динамической значение исчезает из очереди. Т.е. если очередь содержит много значений, то нажимая Right Win Key + Insert все значения будут вставляться последовательно.&lt;br /&gt;&lt;br /&gt;Пожелания, предложения и жалобы для будующих версий clen приветствуются.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:48799</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/48799.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=48799"/>
    <title>InstallShield</title>
    <published>2008-04-14T14:42:42Z</published>
    <updated>2008-04-14T14:42:42Z</updated>
    <category term="programming"/>
    <category term="installation"/>
    <content type="html">&lt;a href="http://www.acresso.com/products/installation/installshield.htm"&gt;InstallShield&lt;/a&gt; - самый низкокачественный (читай отвратительный) комерчески успешный продукт который я когда либо видел. Сколько лет уж как мы с ним воюем, покупаем новые версии, а конца-края проэктным рискам, связанным с багами InstallShield-а не видно.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:48576</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/48576.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=48576"/>
    <title>Свободное время на работе.</title>
    <published>2008-04-11T18:13:09Z</published>
    <updated>2008-04-11T18:13:09Z</updated>
    <category term="process"/>
    <category term="programming"/>
    <content type="html">&lt;span class='ljuser' lj:user='nponeccop' style='white-space: nowrap;'&gt;&lt;a href='http://nponeccop.livejournal.com/profile'&gt;&lt;img src='http://p-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://nponeccop.livejournal.com/'&gt;&lt;b&gt;nponeccop&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; &lt;a href="http://voidbent.livejournal.com/45920.html?thread=608096#t608096"&gt;пишет&lt;/a&gt; а я с ним полностью согласен:&lt;br /&gt;&lt;blockquote&gt;Свободное время вредно. Если род занятий диктуется не рынком, а собственными предпочтениями, ты получаешь бесполезные знания, которые никак не влияют на твою конкурентоспособность на рынке, не влияют на способность поставлять заказчику решения его проблем. Так что в ситуации свободного времени я чувствую не развитие, а гниение.&lt;/blockquote&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:48131</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/48131.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=48131"/>
    <title>4 подхода в типизации.</title>
    <published>2008-04-11T14:35:05Z</published>
    <updated>2008-04-11T14:35:05Z</updated>
    <category term="oop"/>
    <category term="programming"/>
    <category term="paradigm"/>
    <content type="html">I. Сильно типизированный объектный подход (С with Objects, Pascal): Мы можем работать с объектом, только зная его точный тип.&lt;br /&gt;&lt;br /&gt;II. Сильно типизированный объектно-ориентированный подход (Java, C#): Мы можем работать с объектом, не зная его точного типа, но зная тип его предка или интерфейса.&lt;br /&gt;&lt;br /&gt;III. Слабо типизированный объектный подход (C++ template metaprogramming): Мы можем работать с объектом вообще не зная его типа и не делая о его типе предположений. Все типы будут выводиться и подставляться сами во время компиляции.&lt;br /&gt;&lt;br /&gt;IV. Нетипизированный объектный подход (JavaScript): Мы можем работать с объектами у которых вообще нету никакого типа. Мы можем добавлять\удалять\проверять наличие методов\полей данных у объектов во время выполнения.&lt;br /&gt;&lt;br /&gt;Так вот.&lt;br /&gt;&lt;br /&gt;Во-первых, я думаю, что прилагая "среднее количество усилий" найболее читаемым будет получаться код использующий средний между I и II подход.&lt;br /&gt;&lt;br /&gt;Во-вторых, я думаю, что при помощи подходов III и IV можно полуичть гораздо более читаемый код, чем при применении подходов I и II но при этом с линейным ростом читаемости, количество прилагаемых усилий на написание\потдежку такого кода растёт экспоненциально. Это делает подходы III и IV мение применимыми для промышленных систем чем подходы I и II.&lt;br /&gt;&lt;br /&gt;В-третьих, я думаю, что автовыведение типов хоть и устраняет избыточность кода, но при этом делает его плохо читаемым. Особенно это касается языков, придерживающихся подхода I и II. Таким образом ключевое слово var в C# приведёт к более плачевным результатам, чем ключевое слово auto в С++0х. Даже не смотря на то, что var применимо только к локальным переменным а auto почти везде в языке где требуется тип. Проблемы избыточности в языках I и II подходов, должны решаться автоматическими средствами рефакторинга а не нормализацией самого языка.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:48065</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/48065.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=48065"/>
    <title>Опять итераторы и опять LINQ</title>
    <published>2008-04-07T12:03:39Z</published>
    <updated>2008-04-07T12:07:04Z</updated>
    <category term="oop"/>
    <category term="jquery"/>
    <category term="linq"/>
    <category term="programming"/>
    <content type="html">И всё таки я хочу писать так:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
List&amp;lt;MyClass&amp;gt; AllMyObjects = // ...
List&amp;lt;MyClass&amp;gt; SomeMyObjects = AllMyObjects.select // ...

// Тут начинается магия

List&amp;lt;Integer&amp;gt; Values = SomeMyObjects.each().CalculateSomeValue(10);
// CalculateSomeValue is a non-static member of a MyClass : public Integer CalculateSomeValue(Integer target);

Integer MaxValue = SomeMyObjects.each().CalculateSomeValue(10).Max();

List&amp;lt;MyClass&amp;gt; EmptyObjectsList = CreateEmptyObjectsList();

EmptyObjectsList.each().DoSomethingGood();
// DoSomethingGood is a non-static member of a MyClass : public void DoSomethingGood();
// null pointer exception wasn't throwed inside expression EmptyObjectsList.each().DoSomethingGood().
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;На мой взгляд такая форма записи была-бы более выразительна.&lt;br /&gt;&lt;br /&gt;Обратите внимание, что вызов EmptyObjectsList.each().DoSomethingGood() не должен приводить к выбросу NullPointerException. Такой вызов должен просто не производить никакого эффекта.&lt;br /&gt;&lt;br /&gt;Таким образом при помощи конструкций "select ... where ..." и Iterable.each().DoSomethingGood() можно избавится от большинства неочевидных циклов и if выражений внутри кода.&lt;br /&gt;&lt;br /&gt;Для того, что-бы LINQ стал возможным сам язык C# существенно расширили. Так вот, на сколько я понимаю, эти расширения не позволяют реализовать мой описанный выше вариант работы с группами объектов. Поправте меня если я не прав. Зато в jQuery реализован примерно этот вариант.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:47746</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/47746.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=47746"/>
    <title>typing vs test driven development</title>
    <published>2008-04-04T21:53:31Z</published>
    <updated>2008-04-04T21:53:31Z</updated>
    <category term="normalization"/>
    <category term="oop"/>
    <category term="mainstream"/>
    <category term="typing"/>
    <category term="tdd"/>
    <content type="html">&lt;span class='ljuser' lj:user='nponeccop' style='white-space: nowrap;'&gt;&lt;a href='http://nponeccop.livejournal.com/profile'&gt;&lt;img src='http://p-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://nponeccop.livejournal.com/'&gt;&lt;b&gt;nponeccop&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; &lt;a href="http://voidbent.livejournal.com/47015.html?thread=595367#t595367"&gt;пишет&lt;/a&gt;:&lt;blockquote&gt;Взаимозаменяемость тестов и типизации широко известна - почитайте какие-нибудь споры питонистов или эрлангистов с людьми, возмущающимися нетипизированностью этих языков.&lt;/blockquote&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;Естественно, он ошибается.&lt;br /&gt;&lt;br /&gt;Существует &lt;b&gt;три&lt;/b&gt; mainstream подхода для верификации целосности и правильности программного кода.&lt;br /&gt;&lt;br /&gt;Самый мощный и самый универсальный из них это test driven development. 100%-ное покрытие всех возможных сценариев кода 100%-но правильными тестами даёт 100%-ную гарантию правильности самого кода. При разработке бизнесс систем никакой речи о 100%-ном покрытии кода тестами не идёт. Для простоты будем рассматривать объект для которого необходимо гарантировать соблюдение инварианта. Каждый объект обладает в той или иной степени таким атрибутом качества как тестируемость. При достаточном уровне тестируемости для объекта мы можем проверить любой вид инварианта, каким-бы он нибыл. Естественно, тестируемость за свою мощность расплачивается невыразительностью. Тесты пишутся отдельно от тестируемой сущности. Принципиально код тестов прочитать так-же тяжело как и код объекта. Код тестов сам подвержен ошибкам. И т.д.&lt;br /&gt;&lt;br /&gt;Самый выразительный но при этом самый маломощный метод верификации это типизация. При помощи типизации можно гарантировать далеко не любой вид инвариантов, какой бы при этом "склонностью к типизации" объект не обладал. 100%-ная типизированность кода (а многие mainstream языки требуют именно 100%-ную типизированность кода) и близко не гарантирует его правильность. Зато типизация не отделима от типизированного объекта и является частью того, как мы воспринимаем объект. Более того, типизация облегчает восприятие нами объекта.&lt;br /&gt;&lt;br /&gt;Тут стоит сказать, что привлекательность типизации для mainstream-а состоит именно в её выразительности. Существуют более мощные виды типизаций, чем классическая Java-типизация. Они позволяют, например, проверять на уровне системы типов принадлежность числа к определённому диапазону, гарантированно утверждать что список не является пустым и т.д. Такие типизации более мощные и из за этого мение выразительные, а значит мение привлекательные. В любом случае даже самая мощная типизация гораздо мение мощная чем test driven development. Самый мощный (и, соответственно, самый невыразительный) вид типизации который мне знаком - это concept-ы в С++0x. Но даже они, из за ограничений, связанных тем, что их проверка будет осуществляться только статически и только во время компиляции, гораздо мение мощные чем test driven development (хотя по выразительности они примерно одинаковые, и соответственно практическая ценность concept-ов С++0x гораздо ниже ценности test driven development-а).&lt;br /&gt;&lt;br /&gt;Да, типизация иногда мешает своей обязательностью. Для решения этой проблемы придумали duck typing, который тоже является разновидностью типизации.&lt;br /&gt;&lt;br /&gt;На этом можно было-бы закончить и сформулировать упрощённый вариант правила имени меня: "Типизация приоритетнее тестирования. Всё, что может быть гарантированно при помощи типизации должно быть гарантированно именно при помощи типизации. Всё остальное может (но не должно) быть гарантированно при помощи тестирования".&lt;br /&gt;&lt;br /&gt;Однако для полноты картины нужно рассмотреть и третий подход, тем более что он тоже мейнстрим.&lt;br /&gt;&lt;br /&gt;Система primary key/foreign key плюс нормализация (а нормализировать можно не только данные, но и програмный код, я потом напишу как именно это надо делать) позволяют гарантировать некоторые инварианты, которые не может гарантировать классический вариант типизации, т.е. эта система заметно мощнее типизации, но при этом всё ещё довольно выразительна. Например, при помощи key-ев можно гарантировать существование в системе только одного объекта определённого вида (например, только одного юзера с логином "voidbent"), либо гарантировать просто наличие (not null) определённого вида данных.&lt;br /&gt;&lt;br /&gt;Итак, полный вариант правила имени меня будет звучать так: "Типизация имеет найвысший приоритет. Всё, что потдаётся (классической) типизации должно быть типизированно. Нормализация имеет более низкий приоритет, чем типизация. Нормализация программного кода до первой нормальной формы необходима, до второй настойчиво рекомендуема, до третьей желательна. Тестирование имеет меньший приоритет чем нормализация. Степень покрытия кода тестами и выбор самого кода и сценариев которые необходимо покрыть, должны определяться архитектурой и стратегией развития проэтка".&lt;br /&gt;&lt;br /&gt;И ещё, поддержку primary key/foreign key/not null неплохо было-бы иметь прямо в типизированном языке. Жалко что SQL почти не типизирован а Java почти не имеет никакой потдержки системы primary key/foreign key/нормализации.&lt;br /&gt;</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:47474</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/47474.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=47474"/>
    <title>LINQ</title>
    <published>2008-03-28T22:00:58Z</published>
    <updated>2008-03-28T22:00:58Z</updated>
    <category term="linq"/>
    <category term="programming"/>
    <content type="html">Почитал на RSDN-e статью &lt;a href="http://rsdn.ru/article/csharp/Csharp3_Linq.xml"&gt;C# 3.0 и LINQ&lt;/a&gt;. Мне этот LINQ понравился. Собственно, как и &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; это шаг вперёд по сравнению с классическим подходом с итератораторами. Вообщем - рекомендую для общего развития.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:47015</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/47015.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=47015"/>
    <title>сверхвыразительность</title>
    <published>2008-03-25T21:18:56Z</published>
    <updated>2008-03-25T21:18:56Z</updated>
    <category term="programming"/>
    <content type="html">Мейнстриму нужна сверхвыразительность даже возможно в ущерб мощности концепции. Именно по-этому ООП в своё время открыло ногой дверь в мейнстрим, и находится там до сих пор, не смотря на то, что оно не привносит в язык никакой мощности, а только выразительность. Именно по этому С++ со своим мощным но невыразительным template metaprogramming-ом уходит из мейнстрима, а Haskell со своими монадами там (в мейнстриме) никогда не окажется.&lt;br /&gt;&lt;br /&gt;И похоже из тюринг-полных концепций в плане выразительности уже выжали всё что можно. И вот именно поэтому я думаю что в будущем мейнстримом будут рулить тюринг-неполные сверхвыразительные для прикладных задач языки.&lt;br /&gt;&lt;br /&gt;А вот искуственному интеллекту, в противоположность мейнстриму, наоборот нужна мощность даже возможно в ущерб выразительности. Например нейронные сети - это computation model у которого выразительность стремится к минус бесконечности. Похоже ИИ и мейнстрим пойдут развиваться в противоположных направлениях.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:46648</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/46648.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=46648"/>
    <title>Атрибуты качества</title>
    <published>2008-02-26T21:47:35Z</published>
    <updated>2008-02-26T21:47:35Z</updated>
    <category term="architecture"/>
    <category term="programming"/>
    <content type="html">Что такое &amp;laquo;архитектура программной системы&amp;raquo; и зачем её вообще принимать во внимание? У каждого архитектора найдётся свой ответ на этот вопрос. Мой один из ответов будет примерно следующий: Программную систему можно оценивать при помощи атрибутов качества. К атрибутам качества можно отнести производительность, безопасность, настраиваемость, тестируемость, модифицируемость, отказоустойчивость. Этот список, кстати, далеко не полон. К системе можно предъявлять как функциональные требования, так и требования по обеспечению некоторых из атрибутов качества. Так вот, очень часто получается именно так, что конкретный важный атрибут качества может быть обеспечен только в том случае, если на самом верхнем (вся система в целом) уровне были приняты правильные, способствующие обеспечению этого атрибута, решения. И этот атрибут качества не может быть обеспечен на уровне дизайна (на уровне единицы декомпозиции системы – компонента, класса и т.д.).&lt;br /&gt;&lt;br /&gt;&lt;a name="cutid1"&gt;&lt;/a&gt;Приведу свой любимый пример. Допустим, есть готовая система, в которой существует API для написания plugin-ов но это API не включает в себя функций для обеспечения взаимодействия с пользователем. Грубо говоря, каждый plugin показывает GUI окна на своё усмотрение, как ему захочется и когда ему захочется. Если мы перед такой системой поставим требование настраиваемости GUI (например, мы хотим создавать темы и применять их ко всем окнам системы) то возможно мы захотим применить архитектурный паттерн Model-View-Controller. И вот тут начинается самое интересное. Оказывается, если мы применим MVC на уровне одного plugin-а то настраиваемость системы от этого не увеличится. Даже если каждый из plugin-ов будет иметь своё собственное MVC, то GUI системы в целом всё равно будет плохо настраиваемым. Польза от таких локальных MVC будет мизерной.  Но как только мы расширим API системы функциональностью, которая поддерживает MVC, и используем новую часть API во всех plugin-ах, как тут же у нас GUI всей системы в целом станет настраиваемым.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Домашнее задание - привести пример, в котором производительность всей системы в целом можно обеспечить только на архитектурном уровне, и нельзя обеспечить, даже если каждый компонент сам по себе будет производительным.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:46578</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/46578.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=46578"/>
    <title>Инкапсуляция</title>
    <published>2008-02-24T17:30:49Z</published>
    <updated>2008-02-24T17:30:49Z</updated>
    <category term="oop"/>
    <category term="programming"/>
    <content type="html">Одно из полезных свойств инкапсуляции в том, что она позволяет локализировать внутри одного класса/объекта набор материальных свойств, представляющих из себя важное с точки зрения поведения системы понятие. &lt;a href="http://voidbent.livejournal.com/43916.html"&gt;"Диффузия понятий между слоями"&lt;/a&gt; нарушает эту локализацию, а соответственно нарушает инкапсуляцию.&lt;br /&gt;&lt;br /&gt;Прикол в том, что нарушение инкапсуляции, как понятия уровня дизайна системы происходит уровнем выше - на уровне архитектуры.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:46104</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/46104.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=46104"/>
    <title>Aspect-oriented programming</title>
    <published>2008-02-22T11:57:16Z</published>
    <updated>2008-02-22T11:57:16Z</updated>
    <category term="programming"/>
    <content type="html">Основная идея, которая заставляет искать aspect-oriented способы написания систем, будет звучать примерно так: &lt;br /&gt;&lt;br /&gt;"Любое, сколько нибудь важное с точки зрения бизнес логики, свойство программной системы должно быть локализированно в коде. Если языкам не хватает способов локализации свойств программных систем, то эти способы в языки надо добавить" &amp;copy; Я.&lt;br /&gt;&lt;br /&gt;"Необходимость в аспект-ориентированном программировании возникает там, где мы не можем локализировать свойство программной системы в виде класса или объекта" &amp;copy; Я.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Кстати текущее состояние &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming"&gt;Aspect-oriented programming&lt;/a&gt;-а мне совершенно не нравится. &lt;a href="http://en.wikipedia.org/wiki/AspectJ"&gt;AspectJ&lt;/a&gt; выглядит больше как часный случай моих слов.</content>
  </entry>
  <entry>
    <id>urn:lj:livejournal.com:atom1:voidbent:45920</id>
    <link rel="alternate" type="text/html" href="http://voidbent.livejournal.com/45920.html"/>
    <link rel="self" type="text/xml" href="http://voidbent.livejournal.com/data/atom/?itemid=45920"/>
    <title>Прогноз погоды</title>
    <published>2008-02-17T21:14:47Z</published>
    <updated>2008-02-17T21:32:36Z</updated>
    <category term="haskell"/>
    <category term="programming"/>
    <category term="erlang"/>
    <content type="html">Похоже, что я оказался полностью не прав в своих прогнозах, говоря, что миру скоро (тогда, год назад, я думал что скоро - это в течение года) понадобятся толпы параллельных программистов. Уже сейчас попытки протолкнуть Erlang поближе к main stream-у выглядят как борьба с ветряными мельницами. Теперь я меняю прогнозы (только не кидайте в меня тапками) - через пять лет Erlang и Haskell займут своё почётное место рядом с С++ на мусорной куче отходов производства и начнут представлять из себя академическую ценность.&lt;br /&gt;&lt;br /&gt;С одной стороны драконы, против которых борются эти языки, фундаментальны, непобедимы и злопамятны. А с другой стороны функциональность продаётся немного лучше, чем производительность, поэтому за добавление в систему новой функциональности будут платить немного больше, чем за (бесконечную) оптимизацию производительности старой. Другое дело, что есть боги, заинтересованные в проталкивании идеи многопоточности в массы, поэтому думаю всё таки в ближайшее года 3 можно будет срубить легкого бабла по-быстрому, организовав Erlang workshop и продавая Erlang development and support. Кстати, по поводу целесообразности открытия такого workshop-а мне было бы очень интересно услышать Ваши мнения, хочу взвесить все за и против такого шага, и понять стоит ли в это ввязываться. А вот у Haskell, думаю, нет никаких шансов пододвинуться ближе к main stream-у вообще и в принципе. Haskell - это противоположность тому, что сейчас требуется рынку. На самом деле шансов нет и у гибридных языков (привет Nemerle, Scala, &lt;a href="http://community.livejournal.com/ru_declarative/57626.html"&gt;придуманная мною гибридная модель&lt;/a&gt;), на которые я делал ставку в прошлом году.&lt;br /&gt;&lt;br /&gt;Так вот, мой новый прогноз: скоро (в течение нескольких лет) появятся Тьюринг-неполные неуниверсальные языки, и рулить main stream-ом будут они.</content>
  </entry>
</feed>
