Основой для языка 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 удаляет событие вместе с обработчиками.