200 инженеров в Варшаве обсуждают дыры в пайплайнах. Без вас?
Support us

Программирование без текстовых файлов

6 комментариев
Программирование без текстовых файлов

Помню, как в студенческие годы я постоянно терял баллы на заданиях по программированию. Преподавателю просто не нравилось, что мой исходный код мог занимать больше 80 столбцов, а работать с ним в Emacs оказывалось неудобно. Мне также приходилось вступать в споры о том, как лучше делать отступы — при помощи пробелов или табуляции, а также о том, следует ли переносить фигурную скобку на новую строку. Как ни странно, со времени появления первых высокоуровневых языков — LISP и FORTRAN — мы до сих пор пишем исходный код в текстовых файлах с кодировкой ASCII (или UTF-8). Cо времен PDP-11 в этом отношении программирование почти не изменилось.

Что можно изменить в разработке кода?

Мне как разработчику компиляторов это кажется несколько странным. Ведь работа любого компилятора начинается с синтаксического анализа вашего исходного кода и преобразования его в так называемое «абстрактное синтаксическое дерево», сокращенно — AST. Этот этап необходим компилятору, чтобы он мог понять смысл вашей программы. Но дело не только в компиляторах. Статические анализаторы, генераторы документации или lint нужны именно по этой причине: программа не может напрямую оперировать текстовыми исходниками.

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

Если мы проектируем язык, который оперирует линейными потоками символов, нам приходится сталкиваться с глупыми проблемами, в частности:

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

Говоря о выразительности, вспомним одну из самых замечательных идей LISP: поговорим о макроcах.

В языке C тоже есть макросы, но они основаны на подстановке текста. Считается общепризнанным, что система макросов в C сделана плохо и чревата множеством ошибок, зачастую прибегать к таким макросам не рекомендуется. Напротив, в основе макросов LISP лежит идея о том, что у вас есть определенные «макрофункции», выполняемые во время компиляции. Эти функции генерируют AST (новый код), который будет вставляться в вашу программу. Система макросов в LISP обладает огромным потенциалом, так как позволяет создавать новые языковые конструкции, интеграция которых в язык протекает относительно гладко. Из таких новых конструкций можно собрать предметно-ориентированный язык (DSL), на котором вы затем сможете найти решение конкретной задачи, стоящей перед вами. Почему же у других языков программирования нет такой системы макросов, как у LISP? Загвоздка в том, что реализовывать в других языках подобную систему команд нецелесообразно — во многом потому, что эти языки являются текстовыми.

Исходный код LISP — это тоже текст, но его скобочный формат очень строг и регулярен. Фактически LISP представляет AST-дерево в форме вложенных связанных списков. Программист может создавать код и манипулировать им внутри одного и того же вложенного представления, и даже выполнять сгенерированный код «на лету», пользуясь функцией eval. Одна из основных проблем с LISP-подобными языками заключается в том, что их сложно читать. Я думаю, что удобочитаемость такого языка можно повысить, избавившись от сложного скобочного представления — при программировании должны непосредственно редактироваться базовые структуры данных. Здесь следует оговориться, что, рассуждая о нетекстовых языках программирования, я не имею в виду ни визуальные языки, которые редактируются через один большой сенсорный интерфейс (как в фильме «Особое мнение»), ни «стрелочно-рамочные» языки, в которых для реализации самой небольшой фичи требуется двадцать раз щелкнуть мышью. Я думаю, нетекстовый язык нового поколения должен напоминать усовершенствованную интегрированную среду разработки (IDE), которую можно использовать при помощи старой доброй клавиатуры. Потоки задач в такой IDE будут очень похожи на те, которые сегодня нам уже привычны.

Чего мы этим добьемся, кроме того, что сделаем язык в духе LISP? Во-первых, если в таком языке будут макросы, то их интеграция в основной код будет протекать еще более безболезненно, чем в LISP. Такие конструкции могут иметь собственные настраиваемые визуальные представления. Более того, они могли бы содержать дополнительную семантическую информацию, обеспечивающую более качественную интеграцию с вашей IDE и компилятором. Представьте себе: вы могли бы спроектировать специальный предметно-ориентированный язык для работы с дифференциальным исчислением, который допускал бы визуальное представление с использованием подходящей для этого математической нотации. В вашей IDE с ним были бы ассоциированы соответствующие функции обнаружения ошибок и автозавершения, упрощающие быстрое редактирование. Код автоматически оптимизировался бы на основе правил, которые вы заранее сообщаете компилятору. Вы могли бы не только запросить AST-дерево для функции, но также преобразовывать и инструментировать ее «на лету». Присовокупите к этому возможность визуального форматирования исходного кода любым угодным вам способом, даже не задумываясь о табуляции, пробелах, фигурных скобках, комментировании стилей и тем более о ширине пользовательского экрана.

Я усматриваю очевидную выгоду в том, что мы могли бы редактировать и хранить исходный код в таком формате данных, который более четко передает его семантику. Но одна из важнейших проблем, осложняющих такую практику, — это сложность разработки подходящего редактора. Программисты привыкли писать исходный код в виде текста — по сравнению с такой работой редактирование AST кажется более сложной и кропотливой работой. Редактирование можно было бы упростить и ускорить, если бы такая программа выдавала точные варианты автозавершения. Поскольку редактор имеет непосредственный доступ к AST, варианты автозавершения можно было бы оптимизировать, заложив в редактор подробную семантику языка. Еще одна потенциальная возможность ускорения редактирования — создание собственных комбинаций горячих клавиш, выстраиваемых по известному вам принципу. Например, вы могли бы подготовить собственную коллекцию макросов (функций для генерации кода или шаблонов для деревьев исходников с оставленными в них пробелами). Такие конструкции могли бы легко расширяться, а ваша работа сводилась бы к нажатию всего нескольких клавиш.  

Наконец, об инструментальной поддержке. В настоящее время инструментальная поддержка большинства языков программирования оставляет желать лучшего — это касается даже наиболее популярных из них. Отчасти эта проблема объясняется тем, что инструменты должны разбирать и генерировать исходный код. Например, если вам нравятся языки вроде C и C++, то будет непросто отыскать такой синтаксический анализатор, который в полной мере поддерживает грамматику этих языков. Если вы хотите написать инструмент для преобразования кода, то придется решить и такие проблемы, как сохранение комментариев — а это бывает непросто, особенно если выбранный вами синтаксический анализатор для этого не приспособлен. Если бы исходный код представлял собой более однородную структуру данных, то упростилось бы и создание инструментов, которые бы разбирали, анализировали и генерировали код. Было бы проще добавлять метаданные к уже существующему исходному коду. Я считаю, что достоинства такой модели программирования значительно перевешивали бы ее недостатки.

Максим Шевалье-Бойсверт

Источник

Читайте также
Python больше не самый популярный на GitHub. Его сменил очень молодой язык
Python больше не самый популярный на GitHub. Его сменил очень молодой язык
Python больше не самый популярный на GitHub. Его сменил очень молодой язык
4 комментария
В России русифицировали JavaScript
В России русифицировали JavaScript
В России русифицировали JavaScript
6 комментариев
JetBrains: каждому шестому разработчику ИИ экономит минимум день в неделю
JetBrains: каждому шестому разработчику ИИ экономит минимум день в неделю
JetBrains: каждому шестому разработчику ИИ экономит минимум день в неделю
1 комментарий
IEEE: из-за ИИ стало невозможно отслеживать популярность языков, их будущее под вопросом
IEEE: из-за ИИ стало невозможно отслеживать популярность языков, их будущее под вопросом
IEEE: из-за ИИ стало невозможно отслеживать популярность языков, их будущее под вопросом

Хотите сообщить важную новость? Пишите в Telegram-бот

Главные события и полезные ссылки в нашем Telegram-канале

Обсуждение
Комментируйте без ограничений

Релоцировались? Теперь вы можете комментировать без верификации аккаунта.

Комментариев пока нет.