Projectional editing

Nikita Vaniasin | Mar 16, 2017 min read
Всем привет.

Это пост для тех, кто каждый день пишет код.

Как вы вероятно знаете, я таки аспирант. Аспиранты в аспирантуре делают полезные дела и придумывают всякие безумные штуки, чтобы защитить кандидатскую диссертацию (зачем они это делают — тема для отдельного поста).

Короче.

Обычно люди не охотно делают то, что никому не нужно. А я не знаю, нужен ли мой проект кому-то. Поэтому пишу этот пост в первую очередь, чтобы собрать фидбек. Если прочитали статью, пожалуйста отпишитесь в комментах хоть что-нибудь, типа “чувак, ты втираешь какую-то дичь” или “норм”, или “о да! это то, о чем я думал каждую ночь”.

Поехали.


Как вы пишите код? Вероятнее всего вы используете модную IDE, типа JetBrains IDEA или PHPStorm. Или Visual Studio. Или покрытый плагинами Vim. Что вы делаете? Вы пишите текст. Много текста. Ваш инструмент помогает вам это делать, выплевывает подсказки, подсвечивает, если что не так и так далее.

Вы написали код. Кто-то его поправил. Потом его ещё кто-то поправил. Вы можете даже посмотреть, кто его поправил, когда и зачем. Как вы это делаете? Вероятнее всего через Git/SVN: вы используете специальные команды, чтобы посмотреть прошлые версии кода. В вашей модной IDE вы даже можете очень удобно показать рядом два куска текста (старую и новую версии) и увидеть, что именно поменялось. Здорово.

В процессе написания кода в модной IDE вы почти наверняка используете автоматические рефакторинги: вынесение переменной, метода, полей, констант, вот это всё. Как вы это делаете? Вы даёте команду IDE, и она меняет текст.

Ещё более часто вы делаете рефакторинг руками. Приходится делать это, когда IDE не умеет или не справляется с такими задачами. Как вы это делаете руками? Вы меняете текст.

Обратимся к определению рефакторинга. Например вот это с Вики:

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

Короче говоря, это небольшое изменение, которое не меняет семантику (поведение), по факту мы меняем текст.

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

Видим проблему #1: Вы не можете просто и легко определить, поменялась ли семантика программы, просто взглянув на разные версии кода. Потому что вы работаете с текстом.

Посмотрим в другую сторону: что представляет собой ваше ПО? Скорее всего это куча текстовых файлов, кое-как упорядоченных по папкам файловой системы. 99% времени работы над проектом вы не заходите в эти папки в вашем FAR, Explorer или Total Commander, потому что IDE предоставляют абстракцию над этим делом и показывают вам структуру проекта в TreeView. Раньше не было IDE, и всю эту портянку файлов можно было объяснить: пользователь должен был иметь возможность как-то редактировать файлы.

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

Проблема #2: Вам приходится управлять файлами.

Можно и дальше описывать существующие проблемы, но пока остановимся на этих.

Идея, как от них избавиться витает в головах компьютерных гиков давным-давно. Называется — projectional editing. Суть: вы редактируете не текстовые файлы, а семантику вашего проекта — по факту вы редактируете абстрактное синтаксическое дерево. Как оно хранится — заботится редактор.

Ничего особо нового в этом подходе нет. Самое первое, что приходит в голову из примеров — язык для обучения программированию code.org :

code.org

Вы накидываете блоки кода (по сути узлы дерева)из доступных элементов, и запускаете. Ошибиться синтаксически не возможно. Это не файл на диске (внутренняя реализация скрыта) и вы можете посмотреть историю изменения семантики программы. Пожалуй единственный минус — работа мышкой. А профессионалы ведь не пользуются мышкой, верно?

Второй пример — редактор кода в JetBrains MPS. Вообще-то это платформа для создания предметно-ориентированных языков и собственно разработки под такие языки. Ребята могли и не вкручивать туда projectional editor, но они это сделали и получилось довольно удобно. К сожалению, сохраняется всё в те же самые файлы, редактор используется только частично. Историю изменения семантики тоже не посмотришь.

JetBrains MPS

Вообще, с популярными примерами на этом можно покончить. Projectional Editor’ы не прижились (во всяком случае в сфере разработки ПО). Фаулер выделяет их основной недостаток в том, что код можно будет смотреть и редактировать только в специальном инструменте, что для таких штук нельзя использовать VCS.

Я, честно не вижу в этом особых проблем. 99% времени редактирования кода я провожу в одной и той же IDE. Мне не нужны другие инструменты. (Оставшийся 1% — читерство на сервере, либо эксперименты с окружением в терминале). Почему бы не сделать специальную VCS для таких проектов — тоже не ясно. А что вы думаете?


Далее пишу, как я вижу основной кейс использования сей разработки:

  1. Разработчик скачивает себе пакет-инсталятор, запускает.
  2. В результате установки у него на машине появляется:
  • IDE с projectional editor для работы с платформой разработки
  • Встроенную в неё Distributed-VCS, которая помнит все изменения семантики кода (все изменения дерева). Присутствуют все базовые операции (pull, commit, push, new branch, merge)
  • Компилятор, дебагер
  • В IDE при открытии проекта показываются не файлы и каталоги, а дерево — семантическая структура модулей. Как по факту это будет храниться на диске — не доступно разработчику. Пускай это будет всего-навсего один файл — почему бы и нет? Если какой-то хитрец всё таки залезет и попытается его поредактировать — сбилдить или закоммитить эти изменения уже не будет позволено.
  • Визуально код в редакторе будет отображаться скорее всего ближе к урезанному C#, либо другому язык со строгой статической типизацией (возможно и утиная подойдет, тут можно много подумать). Интересная возможность проекционных редакторов — скрывать ненужные подробности (например типы, или реализацию каких-то методов). Например в одном окне вы видите Hi-Level архитектуру, а в другом (смотря на ту же область дерева) — более подробную low-level реализацию.

Основная проблема, которая тут возникает — юзабилити этого редактора. Так как мы запрещаем пользователю вводить невалидный синтаксис, набор возможных действий (по сравнению с обычным редактированием текста) резко сокращается. Эту проблему немного раскрывает чувак с Unison и собственно разработчики JetBrains MPS (там не супер круто, но всё равно довольно удобно). Проблемы с юзабилити возможно опишу в отдельном посте, но было бы интереснее провести реальный эксперимент.

Вы бы воспользовались такой платформой для ежедневной разработки?

Жду ваши фидбэки отовсюду: прямо здесь, в ВК, или по почте. Или WhatsAPP, SMS, ICQ. Или за стаканом пиваса. Или сидя на катамаране в традиционном майском сплаве.