/ in Russian, на русском

Поток сознания: интерактивное программирование

На самом деле я написал этот пост больше для себя, чем для читателей. Хочу зафиксировать впечатление и идеи.

Есть один очень интересный человек, которого зовут Bret Victor. Он дизайнер, когда-то раньше работал в Apple. Есть хорошая статья про него.

Я посмотрел несколько его выступлений, и получил сильнейшее впечатление. Bret говорит что программирование слишком сложно для понимания, и что оно недостаточно наглядно и интерактивно.

Рабочий процесс вида «написать-скомпилировать-запустить» слишком медленный, и разработка получает совершенно новое качество, если результат изменений кода виден в реальном времени.

Bret Victor - Inventing on Principle from CUSEC on Vimeo.

Действительно, насколько удобнее было бы разрабатывать таким образом игры! Но ведь подобный процесс можно применить ко всему, например к разработке серверного софта.

Я просмотрел ещё несколько выступлений и мне окончательно сорвало башню:

Bret Victor - The Future of Programming from Bret Victor on Vimeo.

Seeing Spaces from Bret Victor on Vimeo.

The Humane Representation of Thought from Bret Victor on Vimeo.

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

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

Итак, коротко:

  1. Программы можно изменять в реальном времени.
  2. Результат изменения программ можно увидеть в реальном времени.
  3. Сложные связи можно отображать более понятным визуальным (или звуковым, тактильным, к примеру) способом.
  4. Показывать состояние системы различными способами, записывать его. Легко передвигаться по этому записанному состоянию, изучать поведение системы.

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

Второй, третий и четвёртый — похоже что нет. И дело тут не в том, что есть какие-то технические ограничения, просто никто не думал что это нужно.

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

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

Поток сознания

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

Я знаком с многими языками, но хотелось бы выделить один, с которого мне бы хотелось взять пример: Erlang. Очень простой и ортогональный. Кроме того, стоит обратить внимание на Smalltalk, ибо эта среда будет похожа на смоллтоковский образ.

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

Мне нравится идея организации всего как набор функций группированных по модулям. Кроме того, мне нравится прозрачная работа с данными, всё как в Erlang.

Визуализация

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

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

Само собой, что эти компоненты должны создаваться в этой же среде.

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

Типизация

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

Теперь мы не работаем с числом 47 типа int (к примеру). Мы работаем с участком памяти, размером в 4 байта, который имеет тег signed-int. Мы можем выкинуть этот тег и заменить его другим, но при этом размер этого значения останется старым.

Это вынудит делать все числовые приведения типов явными. Мы можем их делать автоматически, но как-то показывать что они происходят.

Так можно будет легче заметить какие-то проблемы с числами, какие-то закономерности.

Кроме того, вместо того чтобы возвращать кортеж {ok, value}, {error, reason} в стиле Erlang, можно просто возвращать значение с тегами ok либо error.

Модули-функции

В редакторах Atom и LightTable все доступные действия записаны в следующей нотации: “Editor: Move to beginning of line” или “Bracket matcher: go to enclosing bracket match”. Достаточно понятно и выразительно.

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

Так ведь гораздо удобнее: “MPEG-TS Packets: CC discontinuity?(packets)”.
Когда я пишу код на Erlang, то часто выходит так, что для одной экспортируемой функции я пишу много вспомогательных. Мне нравится идея сделать такие функции единицами трансляции. Т.е. модуль состоит из одной экспортируемой функции, и кучи вспомогательных.

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

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

Поток выполнения

Мне нравится декларативный стиль, использование сопоставления с образцом для организации потока выполнения.

Любую case-of-конструкцию легко визуализировать в виде графа. Кроме того, показывая case-of как граф можно указать какие-то детали, который в тексте делать неудобно. Например выполнение одного и того же clause для двух разных образцов (можно, если в образцах привязывается одинаковый набор переменных).

Документация и подсказки

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

Мы можем подробно описать каждую деталь любой части кода. Вроде того, что есть в современных IDE. Но теперь эти фичи будет сделать значительно проще (и более хитрыми), так как нам не придётся анализировать текст кода — мы работаем с кодом как с полями в базе данных, всё очень просто.

Представление

При всех этих фичах, нужно всё равно уметь переводить код в текстовый вид. Так легче выполнять какую-либо автоматизацию, а также вести контроль версий. Кроме того, надо сохранять текст в виде удобном для VCS, чтобы одно изменение в коде изменяло одну строчку в выходном тексте — легче смотреть diff-ы.

Прототип

Проще всего делать эту среду в браузере, как SPA. Для работы с внешним миром (I/O) нужно будет сделать постоянное соединение с сервером (Websockets?), что-то вроде FFI из клиентского js в реальный мир.