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

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

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

О программистах.


Если начинать с самого начала, то когда-то давно я слышал перефразированное высказывание, «каждый программист должен написать свою базу данных, текстовый редактор и язык программирования». И если первые две вещи я уже давным давно написал, то с языком программирования пока не сложилось.

Ведь как обычно создаются языки программирования?

У каждого программиста всегда есть какой-то своей предыдущий опыт:

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

А перед тем, как описывать синтаксис, выбирать ключевые слова и начинать основную работу: лексер, парсер, базовые библиотеки, нужно дать ответ на основные вопросы:

  • Компилятор/интерпретатор/транспилятор(transpiler)?
  • Статическая или динамическая типизация?
  • Ручное управление памятью или автоматическое со сборщиком мусора?
  • Модель программирования: ООП, функциональное, структурное или что-то новое?
  • Разрешены ли вставки из других языков программирования и т. д.?

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

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

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

О не программистах.


Эта область — программирование для «не программистов» на «естественном» языке. Я специально взял слова «не программистов» и «естественном» в кавычки, т.к. эти термины являются очень условными.

Ведь если не программист начинает программировать, то сам того не осознавая, он автоматически становится программистом ;-). А «естественным» язык программирования быть не может по определению. Точнее для компьютеров скорее всего «естественным» будет язык Assembler или набор машинных команд.

Поэтому, цель максимум — приблизить язык программирования к естественному человеческому языку.

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

Но в подобно формулировке кроется очень большая проблема!

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

А если текст программы будет на «естественном» языке, то она станет понятной только для знающих этот язык, одновременно становясь непонятной для всех остальных.

В качестве иллюстрации: раз или два.

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

  • Так как каждый пользователь является носителем своего родного естественного языка (или даже нескольких), то жестко задавать ключевые слова невозможно, из чего следует, что основой такого языка должны стать только правила пунктуации, но никак не лексика или грамматика.
  • Компилятор/транслятор должен уметь преобразовывать исходный текст программы не только в машинный код для компьютера, но в другой вариант «естественного» языка, чтобы пользователь мог работать с исходным текстом на известном ему «естественном» языке.
  • Очень хочется видеть в новом языке толерантность терпимость к очепяткам. Подобная «фича» присутствует в письме на естественном языке, и несмотря на наличие опечаток, практически всегда сохраняется смысл. Естественно, в данном случае не стоит доходить до фанатизма. Компилятор не читает мысли и не может в действительности «понять», что имел ввиду пользователь, и все же довольно часто можно игнорировать опечатки в тексте программы исходя из контекста (пусть и с выводом предупреждающих сообщений).

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

О гипотетическом языке


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

  • Любой текст состоит из предложений и комментариев. Предложения обрабатываются, а комментарии игнорируются.
  • Предложение состоит из последовательности терминов, литералов и символов, разделенных пробелами и знаками препинания и завершается символом конца предложения.
  • Термин — слитно написанная последовательность букв, цифр и символов ":" и "_".
  • Литерал — константы, включаемые непосредственно в текст программы, тип которой определяется однозначно. Это символьные строки в кавычках, целые и вещественные числа, и некоторые специальные форматы (время, дата).
  • Символы — все остальное символы, которые не относятся к знакам препинания, пробельным символам, цифрам и буквам.
  • Знаки препинания — символы пунктуации, имеющие специальное значение при разборе текста программы:

    • «.»,«;»,«!»,«?»,«…» — конец предложения.
    • «=» — присвоение значения.
    • "" (кавычки) — определение символьной строки.
    • «()» — передача параметров/аргументов или группировка операторов для определения приоритета выполнения операций.
    • «[]» — массив или обращение к элементу массива.
    • «{}» — включение в текст исходного кода программы на обычном языке программирования.
    • «$» — системная переменная.
    • «@» — системная функция.
    • «,» (запятая) — перечисление.
    • «:» (двоеточие) — список или логическая связь.

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

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

Так же эта возможность требуется для реализации низкоуровневых функций и для взаимодействия с внешними библиотеками.

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

Для похожих целей служат и символы «$» — системная переменная и «@» — системная функция. Если такой символ поставить в начале слова, тогда он станет обозначать объект с соответствующим назначением. Например «@exit» — будет означать функцию, а «$var» — переменную с соответствующими именами, а сами объекты станут доступны как в обычном коде, так и в программных вставках внутри фигурных скобок.

Аналогичным образом организуется и доступ к отдельным полям/методам объектов:
«объект@метод» или «объект$поле».

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

Символ двоеточия «:» используется для создания списков и для обозначения логической связи между двумя частями слова/текста, в том числе для указания полного пути модуля.

Например, создание списка:

В_строку: элемент 1, элемент 2, последний элемент.
Форматированный_список:
- элемент 1;
- элемент 2;
- последний элемент.


Логическое следствие/указание связи:

module:calc //термин «calc», который находится в модуле «module»
super:module:example$var //переменная «$var» которая находится в указанной иерархии.

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

О компьютерах


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

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

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

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

перейти = @goto,
метка = @label,
продолжить = @continue,
прервать=@break и т.д.


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

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

Компьютерный: функция(параметр1, функция2(), параметр3=значение).
Естественный: функция параметр1 функция2 параметр3=значение.


Но:

Компьютерный: функция( функция2(параметр) ).
Естественный: функция функция2(параметр).
Или так: функция (функция2 параметр).


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

О возражениях


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

Поэтому напомню про его обязательное свойство — умение преобразовывать текст программы с одного языка на другой. Это позволяет писать программы как с использованием строго формального синтаксиса без использования переопеределенных терминов на естественном языке, так и преобразовывать исходный текст в «естественный» язык для «не программиста».