Основой для языка MSH послужил язык MUMPS. MUMPS разработан где то в 80-х годах прошлого столетия, как впрочем и многие другие современные языки. Он с самого начала разрабатывался как язык для создания больших информационных систем, работы с большими распределенными данными. В связи с чем имеет некоторую специфику. Программирование на этом языке несколько отличается от программирования на других языках. Несмотря на его малую распространенность у него существует довольно устойчивое сообщество в разных частях света программистов разрабатывающих на нем информационные системы. За время своего существования MUMPS мало изменился. Некоторые элементы языка потеряли актуальность. И язык на данный момент несколько архаичен. Хотелось бы иметь более современный язык подобный MUMPS. С этой целью и создавался язык MSH. Некоторые концепции языка MSH отличаются или отсутствуют в языке MUMPS. В основном для аудитории MUMS программистов и написан данный материал, но может и другим будет интересно.

Константы.

В MUMPS константы отсутствуют. В MSH они введены. Но из-за специфики языка существовать в виде неизменяемых переменных времени исполнения программы они не могут. Поэтому в MSH они введены как объекты времени компиляции. Что то типа define языка Си в самом упрощенном виде. В момент трансляции языка MSH в Pi код виртуальной машины все константы в исходном тексте заменяются их значениями. То есть в Pi коде их уже нет. Константы могут использоваться как значения переменных, в качестве индекса или имени переменной. Формат команды:Constant nameConst=valConst <,nameConst=valConst>;Справа от знака равенства может находиться только константа, выражение не допускается. Имя константы должно быть уникальным и с именами переменных не пересекаться.

Переменные.

В MUMPS переменные хранятся в деревянной структуре, будь то глобали или локали. Правда у глобалей в MUMPS есть небольшое отличие — сокращенный синтаксис. В MSH нет сокращенного синтаксиса. Хранение данных в виде только дерева позволяет унифицировать обращение к данным. Можно писать программы обработки любого дерева данных. Но в программах часто приходится работать с различными промежуточными значениями и хранить их в дереве не эффективно. Доступ к дереву всегда влечет дополнительные расходы, как бы мы этот доступ не оптимизировали. В MSH данные могут храниться как в деревянной структуре, так и в одномерном массиве. В одномерном массиве лучше хранить промежуточные данные, хотя можно хранить и любые данные. Доступ к массиву значительно быстрее, чем к дереву. Дерево хранить так называемые разряженные данные. То есть в дереве хранятся только существующие вершины. Например имеем дерево [1] [5] [78]. Только эти вершины и будут хранится в дереве. Массив хранит все промежуточные значения. Например мы создали 78 элемент в массиве $78. Будут созданы все элементы в этом массиве вплоть до 78. Если мы создаем дерево, то создается и пустой массив и наоборот, если создается массив, то создается и пустое дерево. Но это конечно относится к текущей реализации MSH.Видимость переменных в MUMPS имеет свои особенности. То что в MUMPS называют глобалями в других языках это обращение к базам данных. А вот локали являются аналогом переменных в других языках. Ну с глобалями все ясно. Это внешние данные и они доступны как из любого задания данного приложения, так и из других приложений. Хранятся они в виде файлов и как правило несколько глобалей в одном файле. В MSH в общем то все так же за исключением одного момента. Каждая глобаль хранится в отдельном файле. А если точнее то в нескольких файлах одного каталога. Этот момент существенен с технологической точки зрения построения информационной системы. И еще одно замечание. Глобали в MSH синхронизированы по обращению. Это значит, что к ним можно обращаться одновременно из разных заданий без дополнительной синхронизации. Теперь детальней разберемся с локалями. В общем случае локаль в MUMPS является глобальной переменной верхнего уровня в смысле языка Си. Аналога переменным из кучи в языке Си, в MUMPS нет. А вот аналог автоматическим переменным языка Си есть. Это локали перечисленные (или не перечисленные), в зависимости от формы команды, в команде New. Область видимости таких локалей от команды New до команды завершения блок Quit. Оригинальное конечно решение обусловленное природой MUMPS и отсутствием в нем деклараций переменных. По моему мнению глобальная область видимости локалей по умолчанию спорное решение, хотя и не фатальное. В MUMPS где я в основном работаю напрямую с глобалями, локальных переменных не так уж много и конфликты имен не часты, хотя и случаются. Но все же это не удобно при программировании. В MSH принят другой подход. Команды New здесь нет. А локализация переменных выполнена по префиксу. Переменные имеющие префикс % локализованы внутри задания. Переменные имеющие префикс ^tmp локализованы внутри приложения. Переменные не имеющие этих префиксов локализованы внутри блока Do. Это касается одинаково как деревьев, так и массивов.

Объекты.

В MUMPS объектов нет. Но ООП получило повсеместное распространение. Основная масса современных языков программирования так или иначе поддерживает ООП. MSH не исключение. Для того чтобы было ООП язык должен иметь для начала объекты. В общем случае описание объект состоит из декларативной части и части реализации. MSH не поддерживает декларации переменных, значит декларативной части описания объектов не будет. Существует описание объекта в MSH в виде части реализации. В MUMPS код программы представлен в виде программных модулей. Точки входа в модуле являются подпрограммами и функциями. Программный модуль в MSH и взят в качестве описания объекта (класса). Метки модуля являются точками входа этого модуля. Точки входа в этом случае являются публичными свойствами get этого класса. Публичными свойствами set этого класса будут та же точка входа как и get модифицированная определенным символом. В качестве такового в MSH выбран символ точка «.». У свойства в MSH кроме доступа get и set есть еще операция Kill -удаление свойства. В этом случае имя свойств модифицируется префиксом «..». Наследование классов в MSH является множественным и реализовано с помощью команды Extend. Классы перечисленные в этой команде в порядке следования являются предками данного класса. Во время выполнения программы при обращении к свойству объекта его описание сначала ищется в исходном модуле затем в модулях перечисленных в команде Extent в порядке их следования. Более раннее положение модуля в команде дает ему больший приоритет. Защищенные свойства реализуются с помощью системного свойства %this. Объекты в MSH могут находиться только в дереве. В массиве могут храниться только примитивные типы данных.Методы класса так же являются точками входа в модуле класса. Создаются объекты с помощью стандартного свойства %new.Например имеем класс Person со свойством Age. В модуле класса есть точки входа «Age» и «.Age».В переменной [1,2] создадим объект.Set [1,2].%new= Person;Обращение к свойству Age объекта Person по записи.Set [1,2].Age=50;Обращение к свойству Age объекта Person по чтению.Set $1=[1,2].Age;Эти команды транслятор преобразует в обращения к подрограммам. Но это не единственный способ обращения к свойствам. По записи к свойсту Age можно обратиться и через метод.Do [1,2].Age(50);В MSH модуль выполняет двоякую роль. Кроме модуля класса он может трактоваться и как модуль программ. В этом случае к точкам входа обращаются как к подпрограммам. Предположим в модуле Person есть метка ABC. Тогда к ней можно обратиться как к программе. Правда в этом случае переменная %this будет пустой.Do Person.ABC(125,D,25.6);Так можно организовать классовые методы.

События.

Еще одной эффективной парадигмой программирования являются события. Как правило языки программирования не содержат средств обработки событий. Они обычно вынесены в стандартные библиотеки. В MUMPS обработка событий в зачаточном состоянии и сводится к обработке ошибок. В MSH события включены в язык. События могут быть как системными, порожденными системой. Так и пользовательскими, порожденными пользователем с помощью команды EventTrap. Аргументы этой команды передаются обработчикам этого события.Команда EventCall назначает событию программу обработчик. В момент возникновения события текущее задание будет прервано и будет выполнена программа обработчик в новом блоке Do. Как будто в этом месте встретилась команда Do с вызовом данного обработчика. Это значит что локальные переменные выполнявшейся программы в обработчике события будут недоступны.Команда EventWait останавливает выполнение текущей программы и ожидает возникновение события. При возникновении события текущая программа продолжает работу и с этого момента в программе становятся доступными переданные аргументы. Новый блок Do не создается и поэтому все локальные переменные этого блока Do доступны после каоманды EventWait.Если событие возникло до появления команд EventCall и EventWait. То событие будет обработано первой встретившейся командой EventCall или EventWait. После обработки событие удаляется. Команда EventDelete удаляет событие вместе с обработчиками.

Комментарии (10)


  1. vintage
    05.04.2016 09:06
    +4

    Покажите мне код!


    1. misha_shar53
      05.04.2016 09:24
      -2

      Код чего?
      В предыдущей публикации //habrahabr.ru/post/241369/ есть описание языка MSH.


  1. 4dmonster
    05.04.2016 09:28
    +3

    MUMPS разработан где то в 80-х годах прошлого столетия,

    "MUMPS (англ. Massachusetts General Hospital Utility Multi-Programming System — Массачусетская основная мульти-программная система для госпиталей; иногда M, или М-система) — язык программирования, созданный в 1966—1967 годах для использования в лечебной индустрии."
    Некоторые элементы языка потеряли актуальность.

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

    Про Caсhe писали, что локальные деревья показывают очень неплохую скорость. И поэтому стоит подробнее описать архитектуру вашего решения по массивам, чтобы было понятно, за счёт чего оно работает быстрее.
    В MSH принят другой подход. Команды New здесь нет. А локализация переменных выполнена по префиксу. Переменные имеющие префикс % локализованы внутри задания. Переменные имеющие префикс ^tmp локализованы внутри приложения.

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

    А почему бы не поступить наоборот: Нужна декларативная часть для описания объектов, поэтому в MSH добавлена декларация переменных.
    В MUMPS обработка событий в зачаточном состоянии и сводится к обработке ошибок.

    MUMPS во главу угла ставит данные, соответственно в нём вместо событий — триггеры.
    P.S.: А как вам такой (не осуществлённый к сожалению) вариант для развития MUMPS — MOLE?


    1. misha_shar53
      05.04.2016 15:00

      |Скорее не появилось изменений, соответствующих современному представлению большинства об удобном языке.
      Почему не появилось? MSH как раз и есть новое представление об удобном языке. Ну а большенство надо убеждать, что это оно и есть.

      |Про Caсhe писали, что локальные деревья показывают очень неплохую скорость. И поэтому стоит подробнее описать архитектуру
      | вашего решения по массивам, чтобы было понятно, за счёт чего оно работает быстрее.

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

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

      Ну какая магия. Как раз это традиционное решение. Локализация переменных одно из немногих идей которые я взял из традиционных языков. Единственно мне пришлось опереться на префиксы, так как предварительного описания переменных у меня нет. Меня честно достало глобальность локальных переменных по умолчанию. А в каждой программе писать New и следить чтобы содержание этой команды соответствовало локальным для данной программы переменным дополнительная ненужная работа.

      |А почему бы не поступить наоборот: Нужна декларативная часть для описания объектов, поэтому в MSH добавлена декларация переменных.

      Объекты декларировать, а переменные нет? Но чем модуль не есть декларация класса? Методы там есть. Ну нет перечня защищенных переменных. Да и не надо. Переменные не имеют типа, что у них описывать, имя? Можно обойтись без этого.

      |MUMPS во главу угла ставит данные, соответственно в нём вместо событий — триггеры.

      Ничего о триггерах не слышал.

      |А как вам такой (не осуществлённый к сожалению) вариант для развития MUMPS — MOLE?

      Интересная попытка. Я категорически против декларативной части класса. И мне не нравится описание класса взятое в лоб из декларативных языков. Да и дополнительные описатели по моему только запутывают. С итератором по одному уровню я согласен, а где итератор по Query?
      Оператор while интересное решение. Перечень методов обработки строк хорош, но по моему недостаточно полон.


    1. misha_shar53
      05.04.2016 15:13

      |«MUMPS (англ. Massachusetts General Hospital Utility Multi-Programming System — Массачусетская основная мульти-программная система для |госпиталей; иногда M, или М-система) — язык программирования, созданный в 1966—1967 годах для использования в лечебной индустрии.»

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

      |Про Caсhe писали, что локальные деревья показывают очень неплохую скорость. И поэтому стоит подробнее описать архитектуру
      | вашего решения по массивам, чтобы было понятно, за счёт чего оно работает быстрее.

      Быстрее по сравнению с чем? Другими реализациями? Я не могу быть точно уверенным, но по моему, чтобы обратиться к дереву надо прочитать каталог, найти на головной странице нужный ключ и найти на странице данных нужное значение. Как то это все можно оптимизировать, но по сравнению с прямым обращением в память это разные порядки. Обращение к элементу массива в MSH выполняется как к массиву в языке Си. Берется начало массива и по индексу находится значение за одно обращение к памяти. Оно в принципе быстрее обращения к любому дереву.


      1. 4dmonster
        05.04.2016 15:59

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

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


        1. misha_shar53
          05.04.2016 16:07

          |Насколько мне известно(я конечно могу ошибаться) деревья в MUMPS физически не хранятся как деревья. И для обращения к локали — |идёт только поиск по хэш таблице. Что конечно дольше, чем обращение по смещению, если массив не сильно разреженный, и индексы |не велики.
          — Этого не может быть. Хеш таблицы не упорядочены, дерево на них не построить.


  1. hellpirat
    05.04.2016 13:48
    +1

    Сейчас бы оформить все красиво.


    1. misha_shar53
      05.04.2016 15:29

      Согласен. Это мое слабое место.


  1. bobic
    05.04.2016 21:34

    В MUMPS переменные хранятся в деревянной структуре

    Откуда такой термин? Может все же «Древовидной»?