среда, 12 ноября 2014 г.

Линкопост #3

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

Для начала про хаскель и теорию:

Crash Course on Notation in Programming Language Theory - название говорит само за себя. Позволяет не пропускать разделы с формальной семантикой в современных статьях по теории ЯП. В принципе материал достаточно уникальный, я например больше нигде не видел описания этой нотации.

Также наткнулся на две статьи с нормальным описанием подхода к IO в Haskell. First-Class “Statements” и I/O Is Pure. Они наглядно показывают как устроен ввод-вывод в ленивых языках. Что такое тип IO и каков смысл основных операций с ним в терминах "read data" и "apply to result" а не выдуманнных эффектов и действий. Как небольшой побочный результат дают возможность понять что монады, функторы и прочие интересности которыми забиты все тьюториалы и ответы на SO никакого отношения к сути IO не имеют.

Нашлось за полгода и много интересного и про развитие языков программирования.

Всплыла демо-сессия посвящённая дебаггеру в Elm, Bret Victor style reactive debugging. Сейчас этот проект уже влит в основную ветку разработки и доступен как reactor.

Chris Granger написал пару стоящих прочтения статей о том что он дальше собирается делать с IDE. Первая, Toward a better programming, неплохо рассмотрено почему софт пишется медленно и заброшена пара идей что с этим можно сделать. Также было сделано объявление о старте EVE, по делу там достаточно мало, но всё-таки читать интересно. Фактически признано что Light Table превратился в "ещё один редактор" с парой секси фич. Чтож светлая ему память, у EVE есть все шансы таки сдвинуть идею "среды разработки" с мёртвой точки.

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

Небольшой флешбэк, The Mother of All Demos. Презентация руководителя ARC о результатах работы лаборатории 1968 года. Показывается ряд интерактивных систем и озвучиваются идеи их развития. Пользуясь случаем хочу передать пламенный привет всем свидетелям Джобса придумавшего ПК.

Отдельно стоит найденная мной серия лекция Хэмминга (того самого) Learning to Learn. Название говорит само за себя, Хэмминг рассказывает о том как он учился сам и советует как учиться студентам. Особого внимания достойна завершающая лекция You and Your Research.

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

понедельник, 11 августа 2014 г.

Опыт с Bullet Journal

Какое-то время назад я увидел сам и немного порекламировал окружающим аналоговую систему ведения списка дел: Bullet Journal. Суть кратко: автор предлагает типографскую нотацию легко воспроизводимую от руки для управления списками дел на бумаге без помощи компьютера.

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

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

Крупнейшее изменение которое я внёс состоит в разделении журнала на две книги. Одну для "текучки" и одну для "вечного". Первую я веду в блокноте чуть меньше А5, туда идут собственно кратковременные задачи и малозначимые заметки по разным топикам. Вторую я веду в обычной школьной тетради. Туда идут долговременные планы, эскизы по разным проектам, важные мысли. Обе книги оформлены как оригинальный журнал: содержат нумерацию страниц и оглавление.

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

Небольшим изменением подвергся набор иконок. Значок "звезда" долго рисовать и редко получается если пишешь на коленях. Иконка priority была заменена на восклицательный знак, соответственно для inspiration я использю простую молнию. Теперь все значки рисуются в пару касаний и узнаваемы даже когда добавлены в вагоне метро.

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

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

понедельник, 4 августа 2014 г.

"Mathematics for Computer Graphics" и "Computational Geometry: Algorithms and Applications"

Последние полгода очень сильно ленился в плане чтения и справился всего с двумя книжками.

Первая "Mathematics for Computer Graphics" - краткое ревью математики полезной для программирования графики. Книга в принципе неплоха как напоминание и как компактная коллекция полезных математических инструментов. В качестве книги для начального изучения чего либо она к сожалению не очень хороша по нескольким причинам.

Во-первых книге катастрофически не достаёт иллюстративного материала, что фатально сказывается на скорости начального восприятия. Ко многим выкладкам и доказательствам приходится рисовать картинки самостоятельно, что исключает чтение книги в транспорте или на отдыхе.

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

В общем книга приемлема для полки в качестве справочника и не может использоваться для начального ознакомления с мат. аппаратом.

Вторая, "Computational Geometry: Algorithms and Applications". Книга как раз противоположна предыдущей - она очень удачна в качестве учебника. Начинает с простого, продолжает непростым, заканчивает комбинацией ранее изложенного. Очень приятной деталью является отличное покрытие иллюстрациями. Все логические построения и алгоритмы сопровождаются удачными рисунками - мне практически не приходилось брать карандаш и бумагу в руки.

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

Чтение не требует знаний выходящих за первый семестр курса алгоритмов. Используются самые базовые вещи: деревья, кучи, списки. Анализ алгоритмов предполагает только знакомство с нотацией асимптот и умение решать "recurrences".

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

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

четверг, 19 июня 2014 г.

Что не так с Хаскелем

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

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

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

Лирическое отступление. Пару лет назад я проходил на курсере курс по алгоритмам. Начать попробовал на хаскеле. Первым заданием было посчитать inversions, то есть нарушения порядка в массиве. Решение я написал сравнительно быстро, мин 40. Проблемы начались при запуске - программа пожирала всю доступную память. Несколько ритуальных плясок в обходе списка позволили программе вмещаться в пару гигабайт памяти и 20 минут. И да, выдавать корректный ответ для пары тысяч чисел в первой версии, спустя полтора часа...

Обзор тематических ресурсов подходы к решению проблемы найти не позволил. Консультация с коллегой-фаном хаскеля, который кстати тоже получил что-то не вменяемое в первой версии программы, и перестановка чего-то там в паре выражений (перед глазами встал призрак 2003 студии где перестановка инклудов иногда чинила access violation)  позволили сократить время до нескольких минут. Для интереса сделал тоже на питоне за 10 мин, 20 или 30 секунд выполнения и символическое потребление памяти. Искать с помощью Хаскеля минимальный разрез графа из нескольких тысяч узлов я уже не рискнул.

Ну и главное: нет примеров полномасштабных приложений. Какая нибудь обработка исключений от трёх функций с помощью стрелок находится легко. Исходник простого веб-сервера, без расширений языка, без 90% закопанного в библиотеки найти сложно. Хотелось бы увидеть простой аналог рисовалки или текстового редактора. Что угодно что демонстрирует в рамках 3-4 экранов дизайн полноценного приложения которое читает, пишет, показывает что-то пользователю, реагирует на ошибки и нарушения форматов. Таких примеров нет, невозможно оценить какой массив знаний необходим для создания полноценного приложения. Теркат? Трансформеры? Дисер Окасаки? Свободная навигация по исходникам компилятора? Я за три года так и не понял.

Ещё для меня серьёзной проблемой является типографический кретинизм большинства авторов. Он проявляется в нескольких аспектах. Во-первых для функции нормально не иметь человеческого имени. Пишем <*>, в уме проговариваем "треугольна жопа", как описать код коллеге не понятно. Во-вторых статьи абсолютно всех уровней, от ICFP до очередного тьюториала по монадам в блоге программиста Васи наполнены типографскими аналогами собственно операторов языка, то есть вместо -> везде . Какая-нибудь тау с нижним и верхним индексом - тоже святое дело. Вообще обучение на примере кода который не запускается - норма для данного сообщества. В том же LYHGG процентов 30 не работало ещё три года назад когда я его читал.

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

Чуть не забыл, данная заметка не претендует на полный охват предмета. Haskell имеет некоторое (конечное) количество положительных черт, но я тут про них умолчал. Жаждущие серебряных пуль могут найти их в интернете во множестве.

UPD: Буду сюда докидывать пруфы
  1. Need help - my haskell code is over 50 times slower than equivalent perl implementation
  2. The reasons I don’t write all my code in Haskell
  3. Where is Haskell going in industry?
  4. What's the performance bottleneck in this prime sieve function?
  5. Beginner - Parse Error on Input '='
  6. How do you avoid the Cabal Hell™? (третий пункт прекрасен, изящный функциональный дизайн типа)
  7. Complete roadmap from total novice to Haskell mastery?
  8. How do you structure a program to support logging?
  9. Why is foldl bad?

понедельник, 26 мая 2014 г.

Нетипичные IDE

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

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

Вот например Squeake, первый релиз 96 год. (Небось думали я с потолка год в прошлом посте взял? Правильно думали на самом деле, да и большинство обсуждаемых далее фич были в Smalltalk-80). Я наверно повторяю очень известную вещь, но всё таки: основной чертой Smalltalk является существование live image. В нём нет статического кода и времени исполнения, всё что делает программист порождает объекты в одном образе, этот образ несёт в себе и код и живые объекты на одинаковых правах. Образ содержит и ядро языка, и разрабатываемое приложение, и среду разработки одновременно, при поставке пользователю ненужные классы удаляются.

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

"Чего же тут такого интересного?" - многие спросят. Вроде и ничего, но вот 2014 год на дворе а все популярные среды разработки по-прежнему считают что цвет нормально показывать как десятизначное число.

Второй интересной наработкой Smalltalk является method finder. Первая его фича - поиск по ключевым словам более менее освоена современными IDE. А вот вторая, поиск по примеру и сейчас, спустя примерно 30 лет после создания насколько я знаю ни кем не повторена. Если кратко она позволяет ввести пример результата метода при заданных аргументах и получить список методов которые этому примеру удовлетворяют. Например на запрос ' trim my spaces '. 'trim my spaces' он ответит #withBlanksTrimmed.

Ладно, хватит истории, вот пара проектов которые прямо сейчас в разработке. Первый, собравший 300k$ на кикстартере, Light table. Это IDE которая должна решить несколько известных проблем и серьёзно пересмотреть постановку других. На данный момент она нацелена на поддержку Clojure, JavaScript и Python. Среди наиболее интересных фичей:
  • Абстрагирование от файлов проекта, редактор показывает и даёт редактировать функции динамически компонуя их по мере просмотра и редактирования исходников.
  • Автоматический показ документации и/или исходников связанных функций.
  • Интерактивная отладка, как через горячую подмену кода так и через 'watches' которые позволяют записывать и отображать состояние программы в отдельных точках.
Текущие релизы правда пока сконцентрированы на разработке тюнингуемого редактора. Но разрабы полны решимости довести первоначальную идею до конца, вплоть до запила своего языка с блэкджеком и монадами.

Проект Lamdu параллельно развивает язык и среду разработки для него. Язык построен на основе Haskell с изменениями направленными на большую явность конструкций и адаптацию для визуального представления структуры программ. В частности он вводит обязательные имена параметров для функций и явно отображает типы в лямбда-выражениях.

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

Редактор автоматически применяет визуальную свёртку сложных языковых конструкций (вроде лямбд и аннотаций параметров как на картинке). Среди целей проекта предоставление билиотекам возможности настраивать отображение для своих структур данных и функций.

Также предполагается поддержка "regression debugging", то есть автоматический контроль хода выполнения теста и поиск изменения которое сломало тест. Примерно можно сказать что IDE будет запоминать все промежуточные результаты вычисления функций и сравнивать их для каждой версии. Хотя в контексте ленивости языка всё явно будет хитрее.

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

Вот например Projucer, инструмент визуальный разработки для Juce. Ничего сверхъестественного, просто быстрая связь кода и картинки, но всё-таки поживее многочисленных SWING-дизайнеров, а пишется одним человеком.

Ещё один проект, коммерческий, Chronon. Включает в себя "Time Traveling Debugger". Это забавный инструмент который работает с полной записью исполнения программы. Записи получаются с помощью чёрной магии и второго компонента Chronon'а - "Recording Server". Нам же тут интересен дебаггер.

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

Последний пример с совсем неожиданного направления, из мира железячных корпораций и кровавого геймдева. PhysX debugger - инструмент для физического движка от nVidia. Он создан для отладки поведения физической модели в сложных сценах. И демонстрирует очень высокий уровень использования различных визуализаций. Если вам интересно визуальное программирование я рекомендую потратить 15 мин и посмотреть обзорный ролик целиком: PVD tutorial video.

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

Напоследок уже в который раз не могу не дать ссылку на сайт Bret Victor'а, которого авторы большинства описанных выше проектов называют в числе основных источников идей: worrydream.com. Если Вы ещё не изучили все его материалы стоит немедленно начать.

вторник, 8 апреля 2014 г.

Альтернативная среда для Racket

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

В принципе это не так и мало, но хотелось большего. А именно:
  1. Полноценного REPL который бы помнил историю команд и умел подгружать изменения без полного перезапуска.
  2. Быстрой навигации по именам функций и структур.
  3. Богатого функционалом текстового редактора, в частности мультивыделения и быстрого поиска.
  4. Поддержки проектов, по крайней мере коллекций файлов по которым можно искать.
REPL достаточно быстро нашёлся, xrepl. Он прекрасно помнит историю, умеет (пере)загружать файлы, заходить в них чтобы тестировать не экспортированные функции и органично встраивается в shell. Инструкция по установке на сайте хорошо работает, для полного счастья только пришлось добавить в bash_aliases следующую строчку: "xracket="racket -il xrepl"". Она запускает Racket в интерактивном режиме и загружает модуль xrepl. Модуль написан таким образом что сам применяет все необходимые хаки для создания полноценной оболочки.

Однако не сразу всё идеально заработало. Файлы с константами было невозможно перезагружать ,rr - Racket выдавал ошибку переопределения имён. Небольшое исследование вопроса показало что это связано с включенными по умолчанию оптимизациями и легко может быть исправлено одной командой, алиас принял вид "xracket="racket -il xrepl --eval '(compile-enforce-module-constants #f)'"".

Остальные 3 функции поставляет Sublime оставалось только подружить его немного с ЛИСПом, благо я не первый кто этим озадачился. Установка пары плагинов налаживает между крепкую дружбу между Racket и Sublime. Для упрощения жизни я использовал Package Control.

Первый и самый насущный - конечно отступы :) lispindent - отлично справляется с этой задачей и даже не пугается квадратных скобок.

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

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

Для того чтобы всё это дружило потребовалось буквально пара настроек.

Во-первых надо включить lispindent для соответствующего языка следующей настройкой в lispindent.sublime-settings (если используется Package Control то его можно открыть через меню Preferences->Package settings).
{
  "languages": {
    "racket": {
      "syntax": "Racket.tmLanguage"
    }
  }
}
В настройках Bracket Highlighter, которые bh_core.sublime-settings (также легко открываются через меню Preferences->Package settings) надо только найти и настроить под себя параметр high_visibility_style, мне понравился underline. Также удобно повесить переключение этого режима на хоткей, для этого в Default.sublime-keymap надо дописать
{
  "keys": ["ctrl+\\"],
  "command": "bh_toggle_high_visibility"
}
Ну и проверить что файлы .rkt открываются как Racket по умолчанию.

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

среда, 26 марта 2014 г.

IDE как зло

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

Этот пост скорее дамп мыслей чем законченная идея. Однако мысли эти посещают меня довольно давно и мне кажется неплохой идей их зафиксировать. Мыслей этих примерно 4:
  • Общая польза от IDE крайне переоценена 
  • Вред от них практически никогда осознанно не рассматривается 
  • Во многих [коммерческих] проектах есть крайне не здоровая зависимость от них 
  • Производящие их компании и сообщества уже много лет ничего реально не улучшали 
Польза переоценена очень сильно. Очень многие буквально считаю что без них нельзя работать. Другие думаю что IDE ускоряет разработку в разы. Основными функциями которые считаются незаменимыми являются поиск, навигация, рефакторинг и, иногда, дебагер. Как мне кажется потребность в этих функциях во многом создана самими IDE.

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

Рефакторинг? Да то же самое, весь мой рефакторинг в питоне укладывается в grep и Ctrl+R. Просто нет дублирования информации о модулях и сама питонья культура не приветствует создание пакетов "просто так".

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

Реальная польза от IDE - перетаскивание неудачных решений в дизайне языков и библиотек из области "фатальный бред" в область "можно терпеть". Не более. Бывает ли такое решение проблем необходимо? Конечно бывает. Но надо ли им пользоваться по умолчанию?

Печальна также и ситуация с оценкой проблем создаваемых IDE. Их наблюдается немало, но вспоминать про них - табу. Про то как джавовские null'ы несут зло и хаос написаны многие сотни страниц текстов, про то что IDEA последние 6 лет стабильно фризит на более-менее больших проектах почти никто не вспоминает.Или вернёмся опять к рефакторингу. Несмотря на то что идея изменения структуры кода без изменения его семантики в общем то здравая, тут тоже важна мера. Один из негативных эффектов наличия IDE в наборе инструментов - это откровенный спам рефакторингами. Не нравится имя? Две кнопки, вбить новое и готово! Захотелось перепилить структуру пакетов? Берём мышку, драг, дроп, кровь-кишки-мозги по стенам.

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

Самая очевидная проблема - IDE скрывают реальное положение вещей в коде. Бессистемное именование, иерархии классов в 8 уровней, пинг-понг из вызовов перегрузок и super - всё это успешно маскируется навороченным Hierachy view. Проблема в том что инструменты могут что-то сделать с механической частью проблемы - найти все перегрузки, вызовы, ветвления. Но они бессильны с интеллектуальной частью - программисту всё так же надо разбираться в таких путаных структурах.

В коммерческой разработке на Java и C# сейчас наблюдается крайне болезненный культ IDE. Примерно треть половина что я видел не собиралась иначе чем экспортом из конкретной среды, примерно треть могла нормально разрабатываться в одной единственной среде из-за code style или кодогенерации или того что единственное описание зависимости между модулями - проект в проприетарном формате созданный 5 лет назад.

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

Проблема в том что разработчики Git плагинов для IDEшек с которыми я работал либо просто не в курсе этой особенности, либо менеджеры соответствующей квалификации пояснили им что разноцветный дифф важнее для хомяков чем какая-то там расширяемость. Как следствие нельзя настраивать и даже использовать уже настроенные алиасы и нельзя удобно призывать на выполнение внешние скрипты. Зато есть кнопки Update и Commit&Push... Ну можете представить как выглядит история когда проект резко переезжает с SVN, никто не пользуется гуглом а среда представляет такой easy по самое не могу функционал.

Ну и наконец о развитии - для сред разработки оно остановилось где-то в 90. IDEA 12 отличается от от JBuilder 2003 практически только разнообразными окошками навигаторов, а он в свою очередь от Turbo Pasсal 6 в основном наличием индекса символов и файлов. И все вместе они на фоне Squeak, скажем так, не выглядят достижениями трёх пятилеток.

Не хватает реальной интеграции компонентов. Например, как дебагер задействует редактор? Красная полоска в месте останова и попап со значением переменной. И то если программер позаботился о правильном toString, а если нет - пожалуйста прокликивайте дерево объектов. Это в две тысячи четырнадцатом году предел юзабилити и визуализации типа? Я LabView году так в 04-05 поюзабельнее дебагер рисовал.

И кстати о рисовании. В 2014 опять же году, когда всё прогрессивное человечество хреначит колбэки на жаваскрипте встраивает DSL в любой инструмент сложнее cat, для расширения любой IDE мне надо создать модуль(!) плагина, скомпилировать(!) его, положить в нужную папочку а то и прокликать пару форм и перезапустить(!) софтину. Future of programming, чо. Самый доступный способ расширения что предлагается - разлапистая форма настройки брекпоинта с condition и log message (в студии то небось до сих пор и того нет?).

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

Потому что так не делали в 1995 году? Я не вижу других причин.

понедельник, 17 марта 2014 г.

Land of Lisp

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

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

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

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

Код примеров на мой вкус немного грязноват. Много где можно радикально улучшить читабельность простыми изменениями вроде добавления структур вместо списков и магических ca*r'ов, заменой анонимных функций на именованные. Стиль который она оставляет после себя как мне кажется нельзя назвать изящным, но это мнение нуба явно тяготеющего к диалектам Scheme-семейства а не Common для которого написана книга.

И да, просто копировать примеры в таком виде было не очень интересно и решение нашлось само собой - я недавно начал ковырять Racket а книжка то написана под Common LISP! Вот и совместил приятное с полезным, транслировал примеры на современный Racket. И я теперь практически лисп-переводчик с опытом работы :) Кстати благодаря этой книжке я сделал и небольшой (и кажется первый сколько-нибудь полезный) вклад в опенсурс: изрядно подвыправил Racket плагин для Sublime.

В общем несмотря на то что книжка вроде не блестящая при должном настрое и желании что-то поделать руками она приночит массу удовольствия. Рекомендую!

четверг, 30 января 2014 г.

Линкопост #2

Пачка ссылок за последние... 4 месяца. Для начала связанное с Racket.

The Racket Way - доклад на strange loop, рассказ о дизайне или даже скорее философии Racket. Несколько наглядных примеров потребности в мета-языках. Достаточно подробно показана возможность плавной эволюции по пути приложение, библиотека, internal DSL, подмножество языка и новый язык со специальным синтаксисом в конце. Полезно посмотреть и как введение в Racket и чтобы понять что можно делать с мета-языками. Мне такая схема показалось существенно более жизнеспособной чем применение MPS или создание external DSL с 0.

Fear of Macros - что-то вроде мини-книги или большого цикла статей о макросах в Racket. Вопрос раскрывается гораздо удачнее чем в основной документации. Автор начинает с простого но низкоуровнего примера и оттуда движется к высокоуровневым pattern-based macros. Оставляет целостное понимание что такое syntax object, expansion и т.д. Интересно будет тем что интересуется мета-программированием или изучает схему.

Frog - аналог Octopress на Racket, вроде попроще в инсталляции. Выглядит симпатично, использует модный Bootstrap. В качестве языка разметки в том числе можно использовать Scribble или Markdown. Код более менее читаемый, в общем неплохой проект для поиграться с языком и посмотреть как на нём пишут реальный софт.

Немного холиваров и вбросов.

We're Doing It All Wrong - доклад от бывшего участника разработки компилятора Scala. Подробно, хотя и крайне эмоционально рассматривает различные проблемы в самом языке и текущей реализации компилятора. Немного сумбурно - неявно мешаются в кучу проблемы дизайна языка,  библиотеки, кода компилятора а в конце вообще выдвигается идея некоего идеального языка не совсем очевидно связанная с озвученными проблемами. Но в любом случае стоит уделить внимание если вы планируете куда-то внедрять скалу.

The Unreasonable Effectiveness of C - наверно одна из самых интересных статей из прочитанных мной за последнее время. Анализируется почему старый, низкоуровневый язык C был и остаётся популярным и весьма успешным. Строго рекомендовано к прочтению фанбоям хаскелей, скал, джаваскриптов, коков и всего остального что конвертирует силу мысли в быстрые и безбажные программы.

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

Хорошие статьи по практике программирования.

Computational Geometry in Python: From Theory to Implementation - понятный и краткий обзор вычислительной геометрии с точки зрения программиста. Хорошо проиллюстрирован кодом на питоне. Очень приятный способ размять мозги в новой области.

How to design and code a complete program - очень хорошая серия статей о дизайне в функциональном стиле. Построена вокруг одного примера - CRUD приложения для веба. Просто и наглядно излагаются некоторые неочевидные концепции. Код на хаскеле.

Ну и немного философии. Why education is so difficult and contentious - большой обзор происхождения и актуальных проблем современного образования. Интересна тем что внятно формулирует цели образования и показывает что они не очень то совпадают с интересами современного индивида, да и во многом общества.

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

вторник, 21 января 2014 г.

"(Не)совершенная случайность"

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

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

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

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

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

Также хочется отметить перевод - действительно хороший и грамотный. Я не заметил ни одной шероховатости в терминологии и описании сложных ошибок использования тервера. Единственный момент который вызвал моё непонимание это название книги. На английском она называется "Drunkard's Walk" то есть "Походка пьяного" как я понимаю.

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

четверг, 9 января 2014 г.

Clojure vs. Racket - мои наблюдения

Недавно потянуло меня подосвежить в памяти ЛИСП, в качестве учебного пособия и источника игрушечных проектов я без колебаний выбрал LoL. А вот над тем какой диалект выбрать призадумался на пару дней. Вообще сама ситуация довольно примечательна, ЛИСП насколько я понимаю сейчас является единственным языком с несколькими совершенно живыми и здравствующими диалектами. Встраиваемые я сразу отбросил, но и вполне себе самостоятельных осталось порядочно.

В финал вышли два - Clojure и Racket. Common Lisp я отбросил так как в нём многовато на мой вкус специальных форм, макросов и прочих интересных вещей, мне он показался достаточно непоследовательным. Для двух финалистов есть известное и по сути очень хорошее сравнение. Его вывод достаточно однозначен - на практике программировать на Clojure гораздо удобнее, а для учебных целей у диалектов паритет. Однако пост от 2010 года и часть данных там устарели. Ниже я перечислю все устаревшие моменты в том посте ну и приведу пару фактов которые склонили мой выбор в пользу ракеты.

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

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

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

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

Почему я в итоге выбрал Racket? Буквально две причины. Во-первых в Clojure слишком много на мой вкус синтаксических конструкций. Да да, ЛИСП с избытком конструкций, куда мир катится? Куча каких-то скобочек, шапочек, двоеточий и стрелочек... Всякие навороты вроде ключевых слов очень активно используются стандартной библиотекой. Вторая - JVM. Сейчас я уж слишком привязан к ней, надо как-то расширять кругозор.