Показаны сообщения с ярлыком languages. Показать все сообщения
Показаны сообщения с ярлыком languages. Показать все сообщения

четверг, 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. Если Вы ещё не изучили все его материалы стоит немедленно начать.

среда, 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 году? Я не вижу других причин.

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

Чем хорош текст

Недавно отсмотрел серию презентаций небезызвестного Брета Виктора. Кстати всем их рекомендую. Последнюю из них, "The Future Of Programming", я бы назвал вторым лучшим техническим докладом что я видел (Угадайте какой первый?).

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

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

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

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

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

У этого достоинства есть пара очень важных подпунктов. Первый - это валидация. Для текстов есть развитая теория грамматик и не менее развитая практика написания парсеров. Есть ли они для графов/картинок?

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

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