Тег ‘программирование’

Слышали звон

Имел удовольствие прочитать вот такой текст:

При исправлении учтите пожалуйста сценарии использования поворота экрана, переключения оконного режима. Телефонный сафари очень любит издеваться над пользователями, а наибольший трафик на сайт идёт именно со свзяки iphone/safari 7.

Вы заметили слова “сценарии использования”? Вам ничего не показалось странным? Правильно – “поворот экрана” и “переключение оконного режима” – это не сценарии использования в их обычном понимании. Без чего не бывает настоящего сценария использования? Без цели. “Поворот экрана” и “переключение оконного режима” не служат для решения проблем пользователя, которого он ждет от разрабатываемой системы (в данном случае – сайта; естественно, в случае оконного менеджера все было бы по-другому).

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

При исправлении учтите, пожалуйста, поворот экрана и переключение оконного режима.

Удивительно, но совет учиться грамотной письменной речи я видел только в одной книжке по “околопрограммистским” вопросам – в “Практике программирования” Кернигана и Пайка. А ведь написание документации, комментирование кода или общение в системе учета ошибок требуют точности формулировок не меньшей, чем в случае подчиняющегося формальным правилам кода программ – с той лишь разницей, что вместо выскакивающих сразу ошибок компиляции здесь будут выявляющиеся не сразу ошибки непонимания между “писателем” и “читателем”.

PS Кстати, вопрос на засыпку “писателям” – чем цель отличается от задачи?

Про вики, SVN и всякое управление проектами

В рамках внедрения в коллективе погромистов модных штук типа системы тикетов и контроля версий остановил свой взгляд на Trac как на веб-морде для всей этой лабуды. Пощупал, понравилось – намного лучше отдельных Media или DocuWiki, websvn и Mantis (всех возможностей которого мы никогда не использовали, а написать инструкцию по его использованию “для идиотов” вообще не представляется возможным).

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

А вообще, чем дальше, тем больше прихожу к мысли, что все легкодоступные “системы управления проектами” типа Trac или Redmine удовлетворяют моим требованиям, хотелкам и заморочкам в лучшем случае на “удовлетворительно”. Вот скажите, почему нельзя нажать в каком-нибудь Trac одну кнопочку и получить в вики страницы типа “Руководство программиста” и все остальные документы, предусмотренные ГОСТами 34 серии? Я же даже не прошу о другой кнопочке, которая распечатает эти страницы в соответствии с ГОСТами 19 серии, переплетет и отнесет в нормоконтроль :)

Нет бога, кроме 3NF, и Тед Кодд пророк ее

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

И кто-то ведь доверяет деньги этим людям, неспособным понять слова “функциональная зависимость” и “нормальная форма”.

Японский автоматический лифчик

Пишут, что японцы изобрели саморасстегивающийся по команде через Bluetooth лифчик:

http://lenta.ru/news/2014/01/27/bra/

Очевидно, что обработку данных о ЧСС, уровне гормонов и прочем состоянии нервной системы надо проводить на самом лифчике, не добавляя в систему лишнего устройства – смартфона с каким-то “приложением”, которое можно подменить. Интересно, одному ли мне пришла в голову мысль об уязвимости устройства перед злохакерами?

Айтишный русский

Я очень не люблю невыносимо-отвратительное слово “функционал” – не имеющее никаких преимуществ перед “функциональностью” – в чем я, оказывается, не одинок. Но вообще, мне не очень нравится примерно 9/10 современной русскоязычной “околокомпьютерной” терминологии.

Возьмем, например, простое слово “директория”. Всякие линуксоиды употребляют его к месту и не к месту – при этом не вполне понимая, что это довольно грубая калька с английского термина directory – что буквально переводится, как “справочник”. И в самом деле, в файловой системе UNIX directory – это особый тип файла, содержащий список файлов, содержащихся “внутри” него. В книгах 80-х годов этот термин переводили словом “каталог”, что достаточно точно передает смысл. Слово “директория” или даже “директорий” (то же самое, но в мужском роде) появилось скорее в относительно массовой околокомпьютерной литературе 90-х, а через некоторое время превратилось в своеобразный “маркер”, отличающий настоящего компьютерщика от виндузятника (последний употреблял слово “папка”).

Из-за определенного снобизма я сейчас стараюсь везде и всюду использовать слово “каталог” – потому что “Директория“, если пользоваться определением из БСЭ, к файловым системам отношения вообще не имеет. Разумеется, я не хочу изобретать Язык Предельной Ясности, подобно Сологдину из “В круге первом” Солженицына – потому как тогда я должен был бы пользоваться словом “справочник”, а не птичьим словом “каталог” – но и не хочу опускаться до уровня брайтонского еврея, говорящего на странной смеси русского и английского.

Сейчас меня немного волнует тема всяких систем контроля версий. Есть ненулевая вероятность, что мне придется написать в недалеком будущем некую инструкцию для начинающих похапешников по использованию SVN или Git (пока склоняюсь к первому). Но обилие слов типа “репозиторий”, “коммит”, “ревизия” – хорошо, что branch перевели словом “ветка” – мне не вполне нравится. Мне кажется, что бездумное заимствование иностранного термина там, где, немного подумав, можно подобрать русский – свидетельство некоего скудоумия и лени.

Впрочем, признаюсь, что я пока что только задумался о таком “словарике” – и, например, еще не подобрал четкого перевода слова “commit”. Repository вполне официально (в svn-book, например) переводят словом “хранилище”, “ревизия” мне не нравится из-за отсылок к сантехнике. В общем, я хотел бы через некоторое время обсудить такой словарик – чтобы вы не удивлялись, с чего это вдруг я начал изобретать свою, ни на что не похожую терминологию.

А что вы финкаете про коммиты в репозиторий?

Все правильно сделал

Наблюдаю в интернетиках очередную истерику по поводу найденного Навальным документа, где глава ростовского Минсвязи Герман Лопаткин рекомендует не использовать некоторые сервисы Google. Могу прокомментировать действия Лопаткина разве что заголовком этой записи.

Про обновления софта

Ссылка раз:

http://blogs.msdn.com/b/oldnewthing/archive/2013/10/31/10461992.aspx

Ссылка два:

http://dxdt.ru/2013/11/05/6290/

Если вы читали разборы причин катастроф на сайте НАСА, то несомненно нашли хотя бы один случай, где было нарушено прекрасное “общеинженерное” правило – “работает – не трогай!”. Применительно к софту один из его частных случаев звучит так – “не глючит – не обновляй”. И главное отличие Microsoft от разработчиков хистерского говнософта (к которому я отношу и Wordpress) – в том, что они это правило иногда соблюдают.

Я более чем уверен, что “современный” программист в ответ на претензию типа “в новой версии операционки не ставится очень Важная Программа версии 1996 года” сказал бы что-то типа “А вы ее обновите!” Сломали совместимость? Не беда, все быстренько поправят. Вопрос в том, кто будет поправлять и кто это оплатит. Подход “наплевать на совместимость, даешь новую версию” в глобальном масштабе приводит лишь к издержкам.

Про возврат денег за венду

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

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

И вот в этой ситуации я склонен понимать “охуевших барыг”, которые попросту не связываются с этой программой, а решение Microsoft считаю совершенно неправильным – не только по этой причине, но и исходя из несколько других соображений. Предлагаю попробовать осознать – что, если говорить бюрократически-гостовскими терминами, стоит на полках в ближайшем компьютерном магазине.

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

Согласитесь, что диковато выглядит ситуация, когда при покупке ноутбука покупатель просит – “А выковыряйте отсюда процессор, он мне не нужен, у меня свой есть”. Для “аппаратных” составляющих обычно не предусмотрено возможности замены “по выбору покупателя” – тогда почему так хотят поступать с “программными”?

Естественно, что подход “продаем аппаратно-программные комплексы” – не единственно возможный в торговле персональными компьютерами. Но он достаточно широко распространен, а на “смежных” рынках – типа мобильников или планшетов – вообще принципиально единственный. Из “мира ПК” хотелось бы обратить внимание на политику Apple – которая не продает ОС и “железо” только “в совокупности”. Конечно, можно поставить хакинтош на компьютер, собранный из дешевой комплектухи с Савеловского рынка, или вкорячить Windows на последний iMac, но ни один из вариантов Apple не одобряет и разумеется, не будет возвращать деньги за Mac OS, если вы решите ее “снести”.

А какие бывают другие подходы? Можно торговать комплектующими или – как промежуточный и более распространенный вариант – “сборка из комплектующих”. Как мне кажется, его просто путают с тем, что я описал. Да, если приравнять ОС к другим комплектующим – то возможность выбора таковой или покупки ПК “без ОС” (то есть с DOS или кастрированным Linux) не кажется такой уж дикой. Но выбор между двумя этими “режимами” осуществляет не пользователь – а производитель компьютера.

Чем какой-нибудь Asus или Acer хуже, чем Apple? Они имеют точно такое же право рассматривать ОС Windows в составе их продукции, как неотъемлемый компонент. А с другой стороны – даже некоторые производители ноутбуков, скажем, тот же Lenovo в той его части, которая “бывший IBM”, рассматривают свои ПК, как “комплектующие изделия” – и готовы продавать их без ОС. В случае так называемых “бизнес-ноутбуков” это происходит сплошь и рядом, в отличие от “массового” рынка. Там это, разумеется, оправдано – потому что иногда встречаются специфические требования к ПО, которые производителю компьютера выполнять неудобно.

Что я хочу сказать? “Возврат денег за предустановленный Windows” превращает рынок “Wintel-систем” в торговлю “наборами для сборки”. Чем хорош тот же iMac и вообще техника Apple, по рассказам ее фанатов? Там нет всяких “несовместимостей драйверов” и прочей знакомой пользователям Windows ерунды – и это достигается именно за счет того, что ОС и железо рассматриваются, как составляющие “комплекса” – который и предлагается пользователю целиком, без каких-то намеков типа “а вот это можно выкинуть и поменять”.

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

Вам, программистишки

Все равняемся на Диму Маликова: https://github.com/dmalikov, автора крайне полезных программ HaCh и loh. Кстати, вот он же на Stack Overflow: http://stackoverflow.com/users/570689/.

:)

Как я разговаривал с создателем Google Maps

[info]infowatch написал сегодня про “доморощенные” IT-сервисы и айтишную ревность:

Есть такая айтишная ревность. Нет пророка в своём отечестве, нет знатока на своём предприятии. То, что сделали далёкие незнакомые дядьки и продают за деньги, всегда воспринимается лучше, чем то, что бесплатно сварганили знакомые ребята в соседней комнате. “Ну, это же Лёха, я с ним пиво пил. Он, конечно, хороший парень, но куда ему до Гугла!” Лицезрение процесса изготовления ИТ-продукта не прибавляет уважения к результату. А внушительная цена – таки прибавляет. При прочих равных. А эти “прочие” чаще всего примерно равны, поскольку чего-то кардинального и революционного изобрести трудно, все продукты и сервисы очень близки по эффективности.

А я вспомнил, что как раз недавно пил пиво с таким вот “Лёхой”, который единолично создал целый Google Maps. История очень простая. Есть Предприятие, из тех, что выпускают исключительно Изделия, а на предприятии – локальная сеть. Выхода в интернет нет, за чем неукоснительно следят. По некоторым слухам, кстати, в такого рода локальных сетях очень модно использовать IP-адреса из диапазонов, принадлежащих американским госучреждениям. Скажем, бухгалтерия сидит на IP-адресах Минфина, отдел режима – Минобороны и так далее.

В принципе, в этой сети есть довольно оживленная жизнь – пара форумов, “для начальства” и не очень, FTP-шки с фильмами и варезом, жаббер-серверы, некоторое количество веб-серверов “для разработки” и так далее. Не знаю, есть ли доморощенный Tor, но вполне может быть. И вот как-то Лёхе – будем называть его так – понадобилось посмотреть на рабочем месте ролики с его видеорегистратора. Программа для просмотра (наверное, что-то типа Registrator Viewer) умеет показывать путь на гугловских картах, но за ненахождением оных нецензурно ругалась. Что сделал бы нормальный человек? Подключил бы йотовский модем и радовался бы жизни.

Но патологически честный Лёха простых путей не искал, к тому же, тратить деньги на йотовский модем его заела бы жаба. Вместо этого он решил сделать свой Google Maps. Для начала на одном из доступных Лёхе “бесхозных” серверов был поднят Apache, а знакомый админ за бутылку сделал на локальном DNS зону .com (отданную в полное распоряжение Лёхе). Сами же “карты” изготовлялись с помощью cgi-приложения на основе ГИС “Панорама” (в принципе, уже можно догадаться о направлениях деятельности Предприятия – нормальный человек с этим поделием добровольно связываться не будет). Метод запроса тайлов карты у Гугла довольно прост, и реализовать его особого труда не составило. Все это было дополнено парой утащенных у “большого” Google скриптов (зачем-то они были там нужны) и “главной страничкой” на основе Leaflet. Карту Лёха взял откуда-то из “закромов Родины”, с ней проблем было меньше всего (тем более, что для начала достаточно было только Москвы и окрестностей).

Все это заняло буквально два дня – после чего, разумеется, было забыто и заброшено. Но если что – то Лёха, с которым я пил пиво, еще и переплюнет этот ваш Гугл.

Про экзамены по ПДД

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

Вопрос такой: откуда в программе, или даже аппаратно-программном комплексе для сдачи экзамена по ПДД такая крутая фича? Прописана ли она в ТЗ на разработку софта, отражена ли в документации или является “недекларированной возможностью”?

Интересное мнение про Яндекс и компьютерную лингвистику

Яндекс и Гугль многое сделали для материальной поддержки компьютерных лингвистов – только эта помощь не бескорыстная, как пытаются сейчас “представить дело” апологеты крупных поисковых систем, в связи со смертью Сегаловича. И как мне кажется, эта помощь очень сильно затормозила развитие программистских решений: потому что корпорации “подгребли” под себя значительную часть компьютерных лингвистов, и ориентировали программы на свои нужды, на нужды поисковых систем. У них есть деньги, у них есть воля, что сказать еще?

Отсюда: http://caps-lo.livejournal.com/187148.html. Как мне кажется, довольно оригинальный в наше время взгляд на “корпорации добра”.

Про операционные системы

В ходе обсуждения пользовательских привычек и механизмов их формирования у [info]infowatch плавненько перешли к обсуждению разнообразных принципов, реализованных внутри разных операционных систем. Мне кажется, что для ноосферы в целом будет скорее полезно описать мои взгляды на проблему.

Начнем, разумеется, с азов. Любое взаимодействие человека с компьютером укладывается в простенькую схему – человек вводит в компьютер команду, тот что-то делает и каким-то образом выводит результат. Очень важная для понимания сути происходящего вещь – богатство пространств команд и ответов, сравнимое с таковым у “естественного языка”. Это позволяет, например, применять к взаимодействию человека и компьютера слово “общение” – пусть даже и в переносном смысле.

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

Перейдем к более содержательным примерам. Для начала – в духе книжки 1958 года “Автоматические цифровые машины“. Ввод здесь – это записанная на перфокартах последовательность команд, вывод – распечатка с цифрами. В разделе этой брошюры, посвященном описанию процесса программирования, описывается шесть команд некоей вычислительной машины. И уже эти шесть команд, вместе с правилами их записи, называются “языком” – пока в кавычках. В более современной литературе это слово вполне заслуженно пишется без кавычек, а “классические” примеры языков, на которых пользователь общается с компьютером – это “текстовые” языки – командная строка Unix, REPL в Lisp-системах, языки программирования типа C/C++/Java/whatever. Тут комментарии, в общем, не требуются. Скажу лишь только, что эти языки пытались даже исследовать методами лингвистики – и вполне успешно. Что более сложно – так это восприятие в качестве “языка” графического пользовательского интерфейса. Но если задуматься – то это тоже язык, состоящий из простых надписей и пиктограмм.

В принципе, сейчас мы вплотную подошли к одному из фундаментальных свойств операционной системы. Все современные компьютеры (за довольно редким исключением) недалеко ушли в плане “машинного языка” от существовавших в 1958 году. Но “язык”, на котором пользователь общается с машиной изменился до неузнаваемости. Не нужно набирать программу с помощью кучи тумблеров или пробиванием перфокарт. Не нужно, в большинстве случаев, заниматься “программированием”. Более того, программирование распалось на “низко-” и “высокоуровневое”. Можно прекрасно пользоваться современным компьютером, умея лишь тыкать мышкой или даже пальцем в нужные места на “экране”. Можно предположить, что в компьютере живет “что-то”, что принимает ввод на одном языке, переводит его на “машинный”, а затем – проделывает обратный процесс с “ответом”. Это “что-то” и называется “операционной системой”. Вот, скажем, определение из книжки Таненбаума:

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

Замечу, что оговорка о “виртуальной машине” очень важна – в очень многих случаях “языки” ввода и вывода в машине, реализуемой с помощью операционной системы, не являются “расширениями” таковых на аппаратном уровне. При этом о ней иногда попросту забывают – например, заголовок раздела, где приводится это определение, у Таненбаума звучит “Операционная система как расширенная машина”. В этом определении можно дойти до определенного “экстремизма”. Например, Windows с установленной Visual Studio – это отличная от “голой” Windows операционная система. Входной язык ее расширяется с помощью некоторого диалекта C++ – поэтому они и разные :) В принципе, ничему это не мешает – так что не будем заморачиваться.

Попробуем теперь описать “языки”, которые поддерживает, скажем, относительно современный дистрибутив Linux “из коробки”. Оказывается, что таковых – довольно много. Для начала – какое-то подобие машинного языка в исполняемых файлах. Затем – C (и даже C++) с POSIX и еще некоторыми расширениями. Обычно доступен и какой-нибудь “скриптовый” язык – типа Perl, Python – да хоть Emacs Lisp! Нельзя забывать и о языке командной строки, и о языке “коротких надписей и пиктограмм”, реализованном в графическом интерфейсе пользователя.

Но все эти “языки” очень серьезно отличаются своими “базовыми” понятиями – в “машинном” языке речь идет о ячейках памяти, в C – о процедурах, переменных и структурах, в Emacs Lisp – о функциях, в командной строке – о каталогах, файлах и командах, в графическом интерфейсе – о папках и документах (несмотря на то, что рьяные линуксоиды отрицают существование последних двух понятий). Эти вещи поддерживаются в архитектуре операционной системы по-разному. Например, во всех Unix-подобных (читай “современных”) ОС “файловая система” с файлами и каталогами – одна из фундаментальных частей архитектуры. А вот документы и папки из графического интерфейса – они реализованы с помощью файловой системы. Следовательно, применительно к “относительно современному дистрибутиву Linux” абстракцию “файловой системы” следует считать более “фундаментальной”, чем абстракцию “рабочего стола”.

В некотором смысле “наиболее фундаментальные” абстракции современной операционной системы лучше всего описываются с помощью языка, который можно условно назвать “C + POSIX” (Windows API с его понятиями тоже в некоторой степени похож на него). Но, как несложно догадаться, можно объявить “фундаментальным” любой более-менее приличный язык взаимодействия человека с компьютером и его абстракции взять за основу. Вернемся к примеру с “рабочим столом”. В “оригинале” – как его видели в Xerox PARC – графический интерфейс типа “окошечки и значки” довольно сильно отлдичается от современных реализаций. На “рабочем столе” находятся значки, представляющие “папки” и “документы”. При щелчке мышкой на значок либо “документ”, либо содержимое папки показывается целиком, в виде “окна”. Вроде бы все прекрасно? Но ровно до тех пор, пока кто-то не углядит параллелей между папками и документами с одной стороны и каталогами с файлами – с другой.

Разница между каталогом и папкой, может быть, и не так ужасна – благо в развитой ФС вполне можно представить и “виртуальные папки” Windows в виде каталогоа, но вот отличия файла в смысле Unix-подобной файловой системы и документа – просто катастрофические. Например, html-файл – это документ? А является ли он документом без кучки картинок (файлы jpg, gif и т. п.)? А один и тот же текст в Word, PDF и HTML – это один документ или три разных? А кучка html-файлов, представляющих собой страничку Васи Пупкина на narod.ru – это один документ или несколько? Можно дать ответы на эти вопросы в рамках абстракции “рабочего стола” – но тогда потребуется отказаться от кучи вещей, которые существуют в “файловой системе”.

Ужасная катастрофа в области всех теоретических наработок в области операционных систем – это появление и триумф UNIX. Его довольно примитивные, расчитанные прежде всего на простоту реализации, решения стали определяющими во всех современных ОС. Более того, трудно даже помыслить “непохожую” на Unix операционную систему (за исключением разве что каких-то IBMовских динозавров). Например, замечательная концепция “обменивающихся сообщениями объектов” и весь связанный с ней объектно-ориентированный подход (в варианте Smalltalk, а не C++/Java) прекрасно ложатся на техническую реализацию в виде микроядерной ОС. Лямбда-исчисление Лиспа, одинаковое представление “программ” и “данных”, изменчивость и первых, и вторых – это лисп-машины или Emacs. Да-да, последний тоже можно и нужно называть “операционной системой”. Но “микроядро” в современном понимании превратилось в “еще одну реализацию Unix”, лисп-машины – в Emacs, появившийся в Xerox PARC прекрасный пользовательский интерфейс с метафорой “рабочего стола” – в его ужасные подобия в Windows и нынешних Linux. Все более-менее жизнеспособные идеи попросту натягиваются на порой слабо совместимые с ними принципы Unix – а затем все голосят о “дырявых абстракциях”.

Из более-менее современных ОС, предлагающих (да пусть даже и на “пользовательском” уровне) альтернативы Unix-подобной файловой системе можно назвать разве что PalmOS – с ее желанием “запихать все в базы данных”, да Apple iOS – где над “файловой системой” надругались самым беспощадным образом. Но в сравнении с теоретическими разработками начала 80-х – это маленькое изменение.

Короче говоря, восприятие Unix как “единственно правильной” операционной системы остановило всякое “экстенсивное” развитие этой области Computer Science на десятки лет. “Интенсивное” развитие – то есть попытки сделать “еще лучший Unix” продолжается, но есть ли в нем смысл – я сказать затрудняюсь.

Про криптографию и программистов

Мне кажется, статейка заcлуживает внимания:

http://happybearsoftware.com/you-are-dangerously-bad-at-cryptography.html

Собственно, об этом писал [info]sporaw:

стали неумело применять “тяжелую криптографию”, воспринимая ее как “серебряную пулю”, но ничерта не понимающие в ней и в особенностях ее использования

Нет, функция md5() в PHP не решит ваших проблем.

Railway Oriented Programming

В подтверждение записи о том, что работа программиста – это придумывание языков программирования. В одном англоязычном блоге обнаружил пример этого подхода, так сказать, в действии. Рассматривается простая задачка, элементарная последовательность действий, каждый шаг в которой может привести к какой-либо ошибке. Постановка задачи и начало ее решения, прямо скажем, не впечатляют. Но во второй части, как раз и названной “Railway Oriented Programming” – как раз и происходит самое интересное.

Диаграммка типа “поток данных” в принципе, выглядит вполне привычно для многих. Слева вход, справа выход(ы), в квадратиках написаны какие-то функции – все замечательно. Но для того, чтобы перевести ее в реальный программный код на “классическом” ЯП – нужно выполнить некоторую формальную процедуру. Предлагается что-то типа “универсального” языка – который одновременно и изображает конструкции с диаграммы (используются железнодорожные аналогии – типа “стрелка”, “тупик” и т. п.) – и одновременно позволяет записывать программы. Что это, если не язык программирования?

Не так давно мне пришлось освоить одну систему “программирования мышкой”. Нет, это не мейнстримное “визуальное программирование”, обычно понимаемое, как “накидать компонентов на форму”. Та система, с которой мне пришлось столкнуться (что-то типа “русского LabVIEW на коленке”) – это в чистом виде “программирование мышкой”, но идеологически очень близкое к вышеописанному подходу. Изображенные на некоей двумерной схеме “виртуальные приборы” соединяются линиями (”виртуальными проводами”). Авторы утверждают, что с помощью подобной системы можно разрабатывать какие угодно SCADA-приложения (SCADA – это Supervisory Control and Data Acquisition, “диспетчесрское управление и сбор данных”). Как может убедиться практически любой, “каркас” такой системы реализуется на подходящем языке программирования с помощью нескольких десятков строк кода.

Автопилот

Фирма Cisco провела опрос потребителей в разных странах – доверяют ли они “автоматизированным автомобилям и автомобилям без водителей”, а также – посадили бы они своего ребенка в такой автомобиль.

driverless-cars

На сайте Cisco приведен такой вот довольно смешной, учитывая результаты опроса, текстик:

Пользователи доверяют автоматизированным автомобилям и автомобилям без водителей

Автомобили без водителей. 57 процентов опрошенных заявили о своей готовности ездить на автомобилях, полностью управляемых не человеком, а техническими средствами. Больше всего таким автомобилям доверяют в Бразилии (95 процентов опрошенных), Индии (86 процентов) и Китае (70 процентов). В России – 57 процентов. В этом отношении самые осторожные – немцы и японцы.

Дети в салоне автомобиля. При ответе на вопрос о том, готовы ли респонденты посадить в автомобиль с автопилотом своего ребенка, уровень доверия к таким машинам сократился до 46 процентов. Наибольшую осторожность в этом плане выразили японцы, французы и немцы. В этих странах лишь 6 процентов опрошенных решились бы посадить своего ребенка в автомобиль с автопилотом.

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

Могу в качестве примера привести и одну из баек преподававшего на мехмате “программирование и работу на ЭВМ” А. Г. Кушниренко, который рассказывал о своем ужасе, когда увидел в Копенгагене вагон метро без машиниста, и вчерашнюю же статью А. Венедюхина “Автомобиль для разумных“, где тот приводит несколько “нехороших” для автоматики сценариев и даже утверждает: “Почему-то менее радужный сценарий представляется наиболее вероятным.”

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

Адские самодельные языки программирования

У [info]metaclass наметился срачик по поводу “самодельных” языков программирования. Естественно, вся прогрессивная общественность в едином порыве осуждает эту порочную практику. Я же хочу предложить взгляд на проблему с несколько другой стороны – а именно, начать с замечания о том, что деятельность программиста как нельзя лучше описывается фразой “разработка языков програмирования” и разобраться, к чему приведет эта посылка.

Разумеется, что она выглядит несколько провокационно. Поэтому придется ее несколько прокомментировать. Начну со своих личных впечатлений от изучения некоего подмножества Computer Science на мехмате МГУ. Студенты мехмата по отношению к этой науке делятся на две части – первым она дается легко и непринужденно, вторым – с большим трудом (но зачет эти вторые все же как-то сдают). Отличить первых от вторых можно по тексту тех программ, которые они пишут. В большинстве случаев студент, которому программирование дается легко, определит в программе какое-то количество функций и процедур, иногда – пару-тройку макросов для часто встречающихся конструкций, попытается разбить задачу на независимые части. Его не любящий программирование коллега скорее обойдется единственной функцией main().

В чем различие? Первый студент просто владеет главным методом процедурного программирования – “реши, какие требуются процедуры, используй наилучшие доступные алгоритмы”. Как только определен набор процедур для решения задачи – то мы просто пользуемся ими наравне со “штатными” средствами языка программирования. Например, в типичной для третьего курса мехмата задаче “обратить матрицу методом Гаусса” можно выделить следующие элементарные действия с матрицей – “вычесть из строки n строку m, умноженную на какой-то коэффициент” и “поменять местами строки n и m“. Если мы храним матрицу, как массив размера N*M, то логично будет написать макрос, вычисляющий индекс элемента an,m в этом массиве. В общем, реализовав несколько таких процедур, мы получим удобный “язык программирования” для работы с матрицами. Фактически, отличие “программиста” от “не-программиста” сводится к умению такой язык построить.

Каждый раз, когда мы выделяем повторяющуюся последовательность действий в “подпрограмму” – мы повторяем эту операцию. Хороший набор таких подпрограмм – это “библиотека” или “фреймворк”. Учебную задачу из предыдущего пункта вполне можно развить аж до полноценной системы линейной алгебры. От полноценного языка программирования она будет отличаться лишь использованием синтаксиса и управляющих конструкций языка реализации. Но никто не запрещает нам говорить, скажем, о языке “C с линейной алгеброй” – в конце концов, “стандартная библиотека” – это тоже часть языка, и расширяя ее – мы расширяем и язык.

Что же ограничивает программиста, который занят созданием такого языка? Его ограничивает только “расширяемый” язык. Скажем, если мы вдруг вспомним, что матрица – это линейный оператор, и операция называется не “умножить матрицу на вектор”, а “применить оператор к вектору” – то в случае языка типа C или Pascal мы попали, причем конкретно (это не говоря о том, что написать y = Ax мы все равно не можем, а можем писать лишь y = multiply(A, x)). C++ предоставляет новую возможность – определим Matrix::operator*(Vector) и слегка упростим себе жизнь. В более “абстрактных” языках программирования доступны и другие средства манипуляции с объектами из определенного нами языка, в том числе – делающие его действительно частью исходного (это возможно не всегда, приведу чисто “программистский” пример – при всем богатстве std::string в C++ мы не можем написать string s = "foo" + "bar").

Так или иначе, но “главный метод программирования” можно сформулировать в виде (спертом у [info]lionet):

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

…а затем прочитать продолжение:

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

Соответственно, если в проекте возникает необходимость в выделении какого-то “внешнего” по отношению к нему скриптового языка, то можно сделать простой вывод – “основной” язык недостаточно хорош и гибок. В подавляющем большинстве случаев – это ошибка при выборе этого языка (я сразу же исключаю из рассмотрения патологические случаи типа 3D-шутеров со сложными внутренними скриптами – как только в каком-нибудь Lua можно будет обеспечить быстродействие графики на уровне нынешних движков iD Software, Quake N+1 будет написан именно на нем).

Теперь выводы. Вместо того, чтобы заниматься разработкой “скриптового языка”, желательно попытаться описать API проекта – и сделать его доступным для всех желающих. Вариант второй. Если применение чего-то неповоротливого и низкоуровневого неизбежно (допустим, мы пишем Quake), а API хочется реализовать по принципам высокоуровневых языков – то следует разделить “механизм и политику”. При этом вся функциональность должна быть реализована на “удобном” языке. При этом в последнем случае всегда можно дать пользователям возможность менять код, реализующий ее – во всяком случае, при наличии большого числа высококвалифицированных пользователей или же при наличии у последних “крайне специфических” требований, это очень удобно.

Кстати, очень интересно выглядит в свете этого “десятое правило Гринспена” – про то, что каждая достаточно сложная программа на C содержит заново написанную, неспецифицированную, глючную и медленную реализацию половины языка Common Lisp. Замените этот “глючный и медленный” Common Lisp на “настоящий” Lisp, Python, Lua, Javascript – да на все что угодно! – и получите огромное количество удобств. Выдайте пользователю REPL этого языка – и получите полноценный скриптовый язык в вашем приложении “малыми силами”.

Ад, заборы, коровники, ржавые запчасти от трактора

А вот хочется рассказать о граблях, на которые я неоднократно понаступал, пока делал “Каталог запчастей и их аналогов для ГАЗ-3111“. Вроде бы все просто, скажете вы? Да и в самом деле – чего тут сложного, табличка в Excel и всего делов.

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

Дальше – больше. Где-то в начале 40-х, наверное (если судить по легковым ГАЗам – на М-11 этого не было, на М-20 появилось) в СССР была введена единая система нумерации автомобильных запчастей. Любая запчасть – от копеечного резинового сальника до кузова в сборе маркировалась как-то типа 12-2401060-Б или 31113-5000016-100. Здесь цифры до дефиса – номер модели (соответственно это ГАЗ М-12, он же ЗИМ и ГАЗ-31113). Семь цифр после дефиса разбиваются на три группы. Первые две – номер группы деталей (24 – задний мост, 50 – кузов), дальше – номер подгруппы (2401 – это картер и кожухи полуосей, 5000 – все тот же кузов), последние три цифры – номер детали в подгруппе. После второго дефиса идут цифровые или буквенные указания на комплектацию, взаимозаменяемость – в общем, все сложно.

Ничего сложного! – скажет “теоретик” от построения баз данных. Все же уже сделано, все каталогизировано, красота! Вот тут нас поджидает первый облом. Оказывается, что если на новой модели используется деталь от старой, то новый номер не присваивается. Соответственно, сальник заднего моста от ЗИМа, перекочевавший впоследствии на все легковые модели ГАЗ, даже будучи выпущенным в 2001 году и установленным на “Волгу”, все равно будет обозначаться 12-2401060. А опора вилки сцепления от довоенного еще ГАЗ М-11 – когда этот стандарт еще не ввели – на протяжении 70 лет обозначается 11-7576. Прикольно, да? Но это еще не все! Какие-нибудь резиновые шланги на одной модели могут использоваться в системе питания, а на другой – в системе охлаждения (при этом “топливный шланг для Чайки” в магазине не найдут, а “пароотводящий шланг от термостата на Волгу” – покопаются и отыщут).

Меняются со временем группы и подгруппы. Скажем, когда все электрооборудование ограничивается стартером и генератором – то для него достаточно одной группы. А когда электросхема с трудом помещается на 12 листах A4 – то логика, требующая засунуть в одну группу “все датчики системы управления двигателем, кроме ДТОЖ”, а в другую – “все три имеющихся датчика температурного состояния двигателя”, оказывается совершенно инопланетно-непонятной. В “историческом” разрезе, правда, все выглядит проще – пока датчики использовались только для индикации на приборной панели, то всем им выделили по отдельной подгруппе. Отдельно – датчик давления масла, отдельно – датчик температуры, отдельно – дачик скорости – да вроде и все. Выделять же по подгруппе для каждого из десятка датчиков в системе управления двигателем – явное расточительство. Впрочем, от этого не легче.

Я уже мельком упоминал про то, что не все детали имеют маркировку “модель-семь цифр-фигня всякая”. Скажу больше – такую маркировку имеет все электрооборудование. Что значит, скажем, 7702.3701? Это генератор (что подсказывают цифры 3701) модели 7702 (этот номер вообще ни о чем не говорит – просто порядковый номер разработки). Часть кнопочек и переключателей может обозначаться, например, как 2003.3769 (его обозначение “в стиле электрики”), 3111.3709 (еще одно его “электрическое” обозначение), и как 3111-3709300 (а это “автопромовское”). Переключатель этот ставился впоследствии на “Газели” и в магазинах может встречаться под любым из трех обозначений.

В общем, полагаться на то, что номер детали по каталога отражает то, где она применяется, как-то глупо. Для полноты картины добавлю, что метизы и подшипники обозначаются по “своим” стандартам. Правда, часть подшипников все-таки имеет номер “по стандартам автопрома”.

Короче говоря, имеем еще две “сущности” – детали и их обозначения. Говоря языком “отношений” – у нас имеются следующие отношения: деталь такая-то показана на картинке такой-то, деталь такая-то стоит там-то (имеется в виду “подгруппа” из ее обозначения), и деталь такая-то обозначена так-то. Вроде бы все просто? Но не забывайте, что речь идет только об одной модели автомобиля. Если добавить к нашему каталогу, скажем, “Чайку”, то придется столкнуться с тем, что одна и та же деталь на разных машинах называется по-разному. От кажущейся простоты задачи не остается практически ничего.

Я регулярно смотрю на всякие интернет-магазины автозапчастей. Самые примитивные – на каком-нибудь стандартном движке типа какого-нибудь OpenCart. Найти нужную деталь в таких – искусство. Немного лучше – те, кто сподобился поставить каталог “Автософта”. Там хотя бы можно найти “оригинальные” запчасти (хотя каталог – точнее, ссылки из него в “магазин” – абсолютно не учитывает взаимозаменяемость, предусмотренную в обозначениях типа 12-2401060-Б). Иномарочные магазины – в основном адский ад. Да, есть каталоги производителей с разбивкой по группам – но номера деталей там идут в произвольном порядке (есть, кстати, подозрение что одинаковые детали могут иногда иметь разные номера – даже у одного производителя). Есть огромное число “неоригинала” всех типов, цветов и размеров. Всякие Febi или Lemforder применяют свои системы нумерации. Даже в крупнейших каталогах неоригинала встречаются ошибки.

Короче, автору “идеальной” схемы БД для “идеального” интернет-магазина запчастей надо будет ставить памятник при жизни. И самое главное – не думайте, что тут поможет какой-то “опенсорс” типа OpenCart. Создается такое впечатление, что все “доступные и бесплатные” движки интернет-магазинов рассчитаны максимум на два-три десятка товаров. Ассортимент же любого придорожного ларька с “левыми” запчастями для “Жигулей” на порядок сложнее того, что может представить себе воображение типичного программиста-опенсорсника.

Если вы еще не верите – то вот контрольный вопрос – почему деталь с номером 24-1702144-01 в магазинах в диком виде не встречается, а только в составе “Ремкомплекта рычага КПП для ВАЗ-2101″?

ООП и структурки

В очередной раз прочитал в качестве определения “объектно-ориентированности” что-то типа “это структурки и код для работы с ними“. Удивительно, как популярная (но не единственная) реализация так повлияла на понимание термина. Речь идет прежде всего о том, как “объектно-ориентированность” реализована в C++.

Для начала – попытаемся понять, что же такое “объектно-ориентированность” в программировании. Мне очень нравится определение из SICP:

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

Таким образом, способ, которым мы организуем большую программу, в значительной степени диктуется нашим восприятием моделируемой системы. В этой главе (3 глава SICP) мы исследуем две важных организационных структуры, которые соответствуют двум достаточно различным взглядам на мир и структуру систем. Первая из них сосредотачивается на объектах (objects) и большая система рассматривается как собрание индивидуальных объектов, поведение которых может меняться со временем.

Объектно-ориентированное программирование (а точнее, проектирование) в классическом его понимании – это представление “предметной области” в виде множества объектов, каждый из которых обладает своим внутренним состоянием. В том же классическом представлении предполагается, что объекты могут обмениваться сообщениями – и изменяют свое состояние только реагируя на эти сообщения.

Эта модель в явной форме была реализована в языках типа Simula или Smalltalk. Из более современного можно назвать, например, VRML – это не просто “формат файлов” типа Autocad или 3D Studio, а практически полноценная реализация вышеназванного принципа. Из “настоящих” языков программирования – можно привести в качестве примера Objective C. Очень похожи на модель с обменом сообщениями “сигналы” и “слоты” библиотеки Qt – но в данном случае речь идет о диком смешении двух подходов к ООП, и вряд ли это стоит считать подходящим примером.

Па-а-азвольте, скажут тут знатоки современных языков программирования – где же тут private и public переменные, где здесь методы? И вот тут придется вспомнить про то, что C++ – первый широко используемый “объектно-ориентированный” язык, но создавался он исключительно как “C с классами”, причем эти “классы”, как и все объектно-ориентированные возможности раннего C++, были лишь имитацией таких возможностей в “настоящих” объектно-ориентированных языках.

Важно понимать, что “вызов метода” в C++ – это лишь реализация “передачи сообщения” от одного объекта другому. Фактически, в C++ вместо передачи сообщений используются три разных “примитива”. Например, возьмем вот такой класс:

class A {
public:
	int x;
	int f(int y);
private:
	int z;
};

… и вот такой код, работающий с ним:

A a;
int b;
a.x = 2;
b = a.x;
b = a.f(3);

В С++ эти три строчки – принципиально разные операции. На самом деле все они могут быть рассмотрены, как частный случай “посылки сообщения” (а ее мы будем записывать в виде адресат.сообщение(аргументы)):

class A {
public:
	int get_x();
	void set_x(int new_x);
	int f(int y);
private:
	int x, z;
};

... 

A a;
int b;
a.set_x(2);
b = a.get_x();
b = a.f(3);

Замечу, что “накладные расходы” второго способа оказываются несколько больше. Но “идеологически” и присваивание, и чтение значения, и вызов метода – это одна и та же операция. Все переменные-члены класса перемещаются в секцию private – и состояние объекта действительно становится “внутренним”.

В “настоящих” объектно-ориентированных языках, типа Smalltalk, с помощью модели передачи сообщений реализовывались даже такие вещи, как индексация массивов или циклы. В принципе, несложно подобным образом реализовать и арифметические вычисления – с помощью каких-нибудь специально созданных объектов, типа “сумма” (я тут перейду на “русский” псевдокод):

объект Формула {
методы:
	Число вычислить() - чисто виртуальный;
}

объект Сумма : Формула {
методы:
	Число вычислить();
	задатьПервоеСлагаемое();
	задатьВтороеСлагаемое();
переменные состояния:
	Формула первоеСлагаемое, второеСлагаемое;
}

объект Константа : Формула {
методы:
	Число вычислить();
	задатьЗначение(Число);
переменные состояния:
	Число значение;
}

Думаю, что реализации расписывать не надо? А вот как это можно использовать:

Константа к1, к2, к3;
Сумма с1, с2;
Число результат;
к1.задатьЗначение(1);
к2.задатьЗначение(2);
к3.задатьЗначение(3);
с1.задатьПервоеСлагаемое(к1);
с1.задатьВтороеСлагаемое(к2);
с2.задатьПервоеСлагаемое(с1);
с2.задатьВтороеСлагаемое(к3);
результат = с2.вычислить();

Естественно, что вышеописанное – это некоторое извращение, и все соответствующие объекты должны создаваться сразу, как только мы напишем результат = (1+2)+3;. “Метод” в нашей терминологии – это не более чем описание “формата” получаемого сообщения и реакции на него.

С++ – это попытка “приделать” объекты к существующему “необъектному” языку C. В C уже были и структурки, и функции – именно поэтому в C++ “классы” – это некоторое обобщение структур C. После того, как C++ стал действительно распространен – аналогичный подход “взяли на вооружение” разработчики других языков. Именно поэтому в “современном” ООП практически нельзя встретить “чистую” передачу сообщений – только подход “объект – это данные плюс функции”.

Жутким монстром на фоне этого всего выглядит Qt – где умудрились объединить и обмен сообщениями (в виде сигналов и слотов), и “объекты в стиле C++”. Получилось что-то в духе чудовища Франкенштейна – хотя иногда и довольно удобное в использовании.

О госзакупках и ИТ

Почитал я на днях “РосПил”, поинтересовался, что же там удалось предотвратить банде Навального. Профессиональный, можно сказать, интерес вызвали несколько “айтишных” проектов – типа “Разработка автоматизированной системы учета норок и соболей в интересах Министерства по делам норок и соболей Задрищенской области”.

Так как “РосПил” действует искючительно в рамках 94-ФЗ, то внимание навальнят привлекло то, что выложенные в рамках соответствующих объявлений ТЗ неявно подразумевают выполнение заказа заранее определенным исполнителем. Естественно, это адская коррупция, безусловно плохо, и вообще, должно быть наказано. Берусь утверждать, что это – единственный способ действительно разработать пресловутую “автоматизированную систему”, и отличить по этому критерию “нормальный” и “коррупционный” заказы не представляется возможным.

Возьмем любое руководство по пресловутым “методологиям разработки” – за исключением разве что Getting Real (оно в случае хоть сколько-то “ответственных” систем неприменимо). Все RUP, Agile, Scrum и им подобные начинаются с критики мифической “модели водопада” – когда ТЗ на разработку спускается сверху, исполнитель отвечает – “Есть!” и с упорством идиота принимается воплощать что-то, изложенное заказчиком. В современных методологиях разработка ТЗ (где она есть) – первый этап, или стадия реализации проекта. Он включает работу с заказчиком, выявление его требований, согласование пожеланий заказчика с возможностями разработчиков и заканчивается в том числе и выпуском бумажки с заголовком “Техническое задание”. В более “экстремистском” случае даже такой бумажки не предусмотрено – точнее, вместо фиксации требований упор делается на “управлении требованиями” и прочем непрерывном взаимодействии с заказчиком.

Сейчас практически общепринято, что заказчик неспособен самостоятельно написать хоть сколько-то грамотное техническое задание на автоматизированную систему – если он сам не является разработчиком таких систем. Соответственно, само по себе наличие ТЗ подразумевает, что разработка ИС уже начата. Подчеркну, что даже наши советские ГОСТы 19 и 34 серии предусматривают, что ТЗ согласуется между обеими сторонами – заказчиком и исполнителем. Процедура же “госзакупок” подразумевает, что исполнитель и заказчик взаимодействуют по принципу “Партия сказала – Надо! – Комсомол ответил – Есть!”.

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

PS Опять же, перед тем, как писать что-то в комменты, предлагаю попытаться написать ТЗ на аналог Google Reader :)