Sergey Dmitriev (sergeydmitriev) wrote,
Sergey Dmitriev
sergeydmitriev

Новый подход к программированию.

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

Чуть более подробно про эти проблемы см. What is bad about OOP

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

Опишем новый подход:

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

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

Каждый узел такого графа является экземпляром некоторого типа узлов – назовем такой тип “Семантический тип” (Semantic Type).
Опишем подробнее, что из себя представляет “Семантический тип”.
В качестве примера семантических типов рассмотрим понятие “Java class” и “if statement”

Каждый семантичекий тип определяет:

1. Набор ссылок (links), которые описывают ребра этого графа. Каждая такая ссылка имеет определенную роль – это некоторая строка, определяеющая тип ссылки.
Для каждого типа ссылок задается семантический тип (Semantic Type) узла на который они могут ссылаться.
Для каждого типа ссылок задается возможное количество ссылок данного типа в одном узле (Cardinality) - ровно одна или несколько или не более одной и т.д.
Для каждого типа ссылок также необходимо задать на каком этапе они задаются (в момент кодирования, компиляции или выполнения). Если какой-то тип ссылок вычисляется во время компиляции или выполнения, то необходимо предоставить алгоритм вычисления этих ссылок.

Пример: Java class имеет 5 типов ссылок: ссылки на поля, ссылки на методы, ссылки на конструкторы, ссылка на базовый класс, ссылки на реализуемые интерфейсы.
Пример: “If statement” имеет 4 типа ссылок: на условие, на “if true expression”, на “if false expression” и на следующее выражение – на которое передается управление после окончания работы всего “if statement”а – эта ссылка устанавливается во время исполнения программы.

2. Задание следующего узла во время исполнения программы.
Аналогично, следующий узел может быть задан либо жестко в момент кодирования, либо вычисляться во время компиляции или выполнения программы.
Каждый узел может иметь собственное внутреннее состояние во время исполнения программы, которое может использоваться при таком вычислении.
Пример: Java class получает управление только в момент первого использования. В этот момент он инициализирует все свои статические поля, а также выполняет блок статической инициализации. Затем он переводит свое состояние в “initialized = true” и больше ничего не делает а просто возвращает управление тому кто ему его передал.
Пример: При передаче управления на “If statement” он создает специальный узел, который получит управление при выходе из условия, затем передает управление условию, передавая ему также и указатель а этот узел. Этот специальный узел при получении управления от условия проверяет вершину стека на “true” и в зависимости от этого передает управление на соответствующее выражение в “If statement”е. Можно обойтись и без создания специальных узлов, если ввести понятие разных точек входа в узел при передаче ему управления и возможность передавать эти точки входа вместо передачи указателя на узел.

3. Внутреннее состояние – определяет состояние узла во время исполнения программы. Задается некоторым набором полей, может изменяться во время передачи управления данному узлу.
Пример: Java class имеет состояние “initialized”

4. Действия, исполняемые при передаче управления данному узлу.
При передаче управления узел может изменить свое внутреннее состояние, а также может читать или записать что-то на стек или в память. (Описание модели стека и памяти - ниже). Также узел имеет доступ к графу программы (через свои ссылки) и может читать его содержимое, а также менять граф путем создания или удаления других узлов и изменения ссылок.

5. Дополнительные свойства (параметры) узла – определяются набором поименованных строк.
Пример: Java class может иметь свойства “abstract” со значениями “true” и “false”, свойство “visibility”, которое принимает значения public или package local и т.д.

Память и стек.
Память – это куча, с возможностью выделять и удалять ее сегменты, а также записывать данные по заданному адресу. (Возможно будет также поддержка автоматической сборки мусора)
Стек – это собственно стек. Может быть более одного стека при поддержке многонитевости.
Память и стек, изначально пустые, доступны узлам при передаче им управления во время исполнения программы.

Чем хорош и интересен такой подход?

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

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

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

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

В каком-то смысле изложенные идеи сочетают в себе идеи “Intentional Programming”-а и идеи языка Форт.

В настоящее время я имплементирую программу-прототип реализующую изложенную модель, и надеюсь вскоре выложить первый вариант.
В первую очередь я моделирую язык Java, также хотелось бы смоделировать какой-нибудь функциональный язык (типа Lisp или ML), а также логический язык (типа Prolog), ну и конечно же смоделировать языки для нескольких предметных областей (в том числе язык описания самих семантических типов – для достижения замыкания системы на себя)

В этом прототипе семантические типы описываются обыкновенными Java классами. Затем программа-граф задается как набор экземпляров этих классов.

Следующие шаги

1. Написание среды разработки.
2. Поддержка многопоточности.
3. Работа с системными ресурсами – файлы и т.д.
4. Поддержка описания интерфейса с пользователем – наиболее трудная и интересная на мой взгляд проблема.
5. Bootstrap
Tags: language_oriented_programming
  • Post a new comment

    Error

    default userpic
  • 49 comments