среда, 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.

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