Освоение MUMPS: основные операторы

Автор Райан Хейслер

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

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

Примечание о примерах кода: мы рассмотрели такие команды, как write, read, do и set , в предыдущем посте. В этом посте мы использовали полное имя каждой команды во всех примерах. Однако соглашение M, как мы узнали, заключается в использовании сокращенной формы для команд. Этот пост и все последующие посты будут использовать сокращенную форму команд в примерах кода, например. w вместо write. Мы также добавили ,! (перевод строки) в конце каждого write в примерах кода, чтобы при их запуске каждый вывод был на отдельной строке.

Что отличается, а что совпадает?

Как и следовало ожидать, + используется для сложения, - — для вычитания, * и / — для умножения и деления, а ** — для возведения в степень. >, <, >= и <= ведут себя так же, как и в других местах. & представляет логическое AND.

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

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

Точно так же в документах не упоминается ,!, который используется после команды write и ее аргумента для добавления к выходным данным символа новой строки. Например: write "Hello",! выводит строку «Hello», за которой следует новая строка. Мы стараемся иметь привычку выполнять каждую команду write с помощью ,!.

Другие операторы могут выглядеть незнакомыми в M. # — это символ «модуля», — это символ логического NOT, а ! — логическое OR. В зависимости от контекста = используется как для присваивания, так и для сравнения на равенство — в M нет ==.

Наконец, _ предназначен для конкатенации строк. M будет преобразовывать числа в строки во время конкатенации, поэтому write 1_". "_12_"eggs" выведет 1. 12 eggs.

Оператор `\`

Ранее я упростил: / для десятичного деления. При необходимости он вернет десятичные результаты, поэтому 1/4 равно 0.25. С другой стороны, \ выполняет целочисленное деление. Вы можете передать ему десятичные числа, но оно всегда будет округляться до ближайшего целого числа (ведет себя как функция пола).

`[` operator

Что-то, что мы в Menlo нашли полезным для нескольких языков, — это встроенный способ проверки, содержит ли строка подстроку. Это то, что [ делает для нас в M. Левый операнд — это строка для поиска, а правый операнд — подстрока.

Операторы `]` и `]]`

Официальная документация называет ] оператором «следует», а ]] — оператором «сортировки после», но не объясняет, что означают эти слова. Если мы попробуем их, мы увидим, что 4]3 и 4]]3 оцениваются как True, так в чем же разница?

] будет оцениваться как истина, если левый операнд следует за правым операндом в последовательности кодирования символов M. По умолчанию это последовательность ASCII, поэтому таблица ASCII может помочь вам определить, каким будет результат сравнения с ]. M также имеет встроенную функцию $ASCII, которая сообщит вам значение ASCII переданного ей символа. По сути, B]A — это сокращение от выражения $ASCII("B")>$ASCII("A"). Вот еще несколько примеров

* Menlo использует реализацию Intersystems Caché M.

]], с другой стороны, оценивает, сортируется ли левый операнд после правого операнда в «последовательности сортировки нижнего индекса» ¹. Последовательность сопоставления индексов — это то, что M использует для сортировки индексов (дочерних узлов) массива. Возможно, вы использовали функцию $ORDER (описанную в другом посте). $ORDER возвращает следующий узел массива, используя последовательность сортировки нижнего индекса. Эта последовательность немного отличается от ASCII тем, что цифры идут первыми. После этого следуют значения ASCII. Некоторые примеры:

Порядок действий

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

Операция слева направо особенно сложна с логическими операторами. В следующих примерах мы будем использовать 1 для представления «истина» и 0 для представления «ложь». Помните, что каждая строка заканчивается на ,!. Восклицательный знак в символе новой строки не имеет отношения к логическому OR.

M не использует Вычисление короткого замыкания при оценке логических операторов. В некоторых языках, если первое выражение логического AND оценивается как ложное, второе выражение не будет оцениваться, поскольку все логическое выражение должно быть ложным. В M это не так. Оцениваются обе части логического выражения.

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

Этот код выводит 2 строки: «это побочный эффект» и «это напечатает». Несмотря на то, что первое выражение, которое вычисляет &, ложно, оно все равно вызывает evalWithSideEffect. В Menlo мы стараемся не писать подобный код, потому что некоторые языки обрабатывают оценку короткого замыкания иначе, чем другие.

Операторы M могут показаться странными программистам, привыкшим к более современным языкам, но при правильном использовании они могут делать все, что нам от них нужно. Они даже включают несколько удобных инструментов, которых нет в других языках, таких как \ и [. В этом посте мы не упомянули один из операторов M: ?, оператор сопоставления с образцом. Новичкам это может быть сложно понять, но это чрезвычайно мощно. Следите за нашим следующим постом о ? и о том, почему вы не пропустите регулярные выражения при использовании M.

Сноски:

[1] — Определение последовательности сопоставления индексов и обсуждение ] и ]] см. на этой странице. Это характерно для реализации MUMPS в GT.M, но справедливо и для Caché.