• Главная
  • Контакты
Подписаться:
  • Twitter
  • Facebook
  • RSS
  • VK
  • PushAll
logo

logo

  • Все
    • Положительные
    • Отрицательные
  • За сегодня
    • Положительные
    • Отрицательные
  • За вчера
    • Положительные
    • Отрицательные
  • За 3 дня
    • Положительные
    • Отрицательные
  • За неделю
    • Положительные
    • Отрицательные
  • За месяц
    • Положительные
    • Отрицательные
  • За год
    • Положительные
    • Отрицательные
  • Сортировка
    • По дате (возр)
    • По дате (убыв)
    • По рейтингу (возр)
    • По рейтингу (убыв)
    • По комментам (возр)
    • По комментам (убыв)
    • По просмотрам (возр)
    • По просмотрам (убыв)
Главная
  • Все
    • Положительные
    • Отрицательные
  • За сегодня
    • Положительные
    • Отрицательные
  • За вчера
    • Положительные
    • Отрицательные
  • За 3 дня
    • Положительные
    • Отрицательные
  • За неделю
    • Положительные
    • Отрицательные
  • За месяц
    • Положительные
    • Отрицательные
  • Главная
  • DeclarativeCOS — Декларативное программирование на Cache

DeclarativeCOS — Декларативное программирование на Cache +15

24.04.2017 08:45
jxcoder 11 1500 Источник
Проектирование и рефакторинг*, Программирование*, NoSQL*, Блог компании InterSystems
Проект DeclarativeCOS — крик души по теме программирования на COS.

Цель проекта — обратить внимание сообщества к улучшению внутреннего ядра COS.

Идея проекта — поддержка лаконичного синтаксиса при работе с циклами и коллекциями.

image

Итак, что же лаконичного я придумал? Добро пожаловать в примеры!

Примеры


Ключевой концепт проекта — декларативный подход. Нужно указать ЧТО нужно использовать и КАК.

Лично мне всегда не хватало простого оператора/команды/заклинания в терминале COS для того, чтобы вывести коллекцию на экран в том виде, в котором тебе это хочется. А теперь есть две приятные штуки: zforeach и $zjoin!

>s words = ##class(%ListOfDataTypes).%New()
>d words.Insert(“Hello”)
>d words.Insert(“World!”)

>zforeach $zbind(words, “io:println”)
Hello
World!

Здесь стоит рассказать подробнее о функции $zbind. Начать следует с того, что COS можно расширять своими командами и функциями, о чем можно подробно написано в соответствующей документации и статье на портале сообщества разработчиков.

Эта функция создает экземпляр класса Binder. Его задача — связать коллекцию и функцию, которую нужно применить к каждому элементу коллекции. В данном случае, используется стандартная функция с именем “io:println” из DeclarativeCOS, которая для заданного значения value выполняет простую команду:

>w value,!

Команда zforeach работает с экземпляром класса Binder, последовательно проходя по коллекции и применяя функцию к каждому ее элементу.

$zjoin — создает строку из коллекции, объединяя ее элементы между которыми добавляется указанный разделитель.

Пример: создать дату на основе дня, месяца и года используя разделитель “ / ”.
>s numbers = ##class(%ListOfDataTypes).%New()
>d numbers.Insert(“04”)
>d numbers.Insert(“03”)
>d numbers.Inset(“2017”)

>w $zjoin(numbers, “ / ”)
04 / 03 / 2017


$zmap — создает новую коллекцию из элементов исходной коллекции к каждому элементу которой применена указанная функция.

Пример: преобразовать каждое число в hex.
>set numbers = ##class(%ListOfDataTypes).%New()
>do numbers.Insert($random(100))
>do numbers.Insert($random(100))
>do numbers.Insert($random(100))

>write "[" _ $zjoin(numbers, ", ") _ "]"
[82, 12, 27]

>set hexNumbers = $zmap(numbers, "examples:toHex")

>write "[" _ $zjoin(hexNumbers, ", ") _ “]”
[52, C, 1B]


$zfind — находит первый элемент коллекции, на котором указанная функция возвращает $$$YES. Иначе возвращает null-строку.

Пример: найти простое число.
>set numbers = ##class(%ListOfDataTypes).%New()
>do numbers.Insert($random(100))
>do numbers.Insert($random(100))
>do numbers.Insert($random(100))

>set primeNumber = $zfind(numbers, "examples:isPrime")

>write "[" _ $zjoin(numbers, ", ") _ "]"
[69, 41, 68]

>write "Prime number: " _ $select(primeNumber="":"<not found>", 1:primeNumber)
Prime number: 41


$zfilter — создает новую коллекцию на основе исходной коллекции, но взяв только те элементы, на которых указанная функция возвращает $$$YES. Если таких элементов нет, то возвращает пустую коллекцию.

Пример: выбрать нечетные числа.
>set numbers = ##class(%ListOfDataTypes).%New()
>do numbers.Insert($random(100))
>do numbers.Insert($random(100))
>do numbers.Insert($random(100))

>set filteredNumbers = $zfilter(numbers, "examples:isOdd")

>write "[" _ $zjoin(numbers, ", ") _ "]"
[22, 71, 31]

>write "[" _ $zjoin(filteredNumbers, ", ") _ "]"
[71, 31]


$zexists — проверяет, что в коллекции есть хотя бы один элемент, на котором указанная функция возвращает $$$YES.

Пример: проверить, что в коллекции имеются четные числа.
>set numbers = ##class(%ListOfDataTypes).%New()
>do numbers.Insert($random(100))
>do numbers.Insert($random(100))
>do numbers.Insert($random(100))

>set hasEvenNumbers = $zexists(numbers, "examples:isEven")

>write "[" _ $zjoin(numbers, ", ") _ "]"
[51, 56, 53]

>write "Collection has" _ $case(hasEvenNumbers, 1:" ", 0:" no ") _ "even numbers"
Collection has even numbers


$zcount — подсчитать количество элементов в коллекции, на которых указанная функция возвращает $$$YES.

Пример: подсчитать количество палиндромов.
>set numbers = ##class(%ListOfDataTypes).%New()
>do numbers.Insert($random(1000))
>do numbers.Insert($random(1000))
>do numbers.Insert($random(1000))

>set palindromicNumbersCount = $zcount(numbers, "examples:isPalindromic")

>write "[" _ $zjoin(numbers, ", ") _ "]"
[715, 202, 898]

>write "Count of palindromic numbers: " _ palindromicNumbersCount
Count of palindromic numbers: 2


Установка


Для установки DeclarativeCOS достаточно скачать с официального GitHub репозитория проекта два файла:

  1. install.base.xml — просто классы. Без z-функций.
  2. install.advanced.xml — %ZLANG рутины, которые добавляют z-функции.

Как пользоваться


  1. Унаследовать класс от DeclarativeCOS.DeclarativeProvider.
  2. Реализовать метод класса.
  3. Пометить этот метод аннотацией @Declarative.
  4. Использовать z-функции DeclarativeCOS.
  5. Почувствовать счастье.

Подробная инструкция


Шаг 1. Унаследовать класс от DeclarativeCOS.DeclarativeProvider.
Class MyPackage.IO extends DeclarativeProvider
{
}

Шаг 2. Реализовать метод класса.
Class MyPackage.IO extends DeclarativeProvider
{

ClassMethod println(value As %String)
{
    w value,!
}

}

Шаг 3. Пометить этот метод аннотацией @Declarative.
Class MyPackage.IO extends DeclarativeProvider
{

/// @Declarative("myIO:myPrintln")
ClassMethod println(value As %String)
{
    w value,!
}

}

Шаг 4. Использовать z-функции DeclarativeCOS.
>s words = ##class(%Library.ListOfDataTypes).%New()
>d words.Insert("Welcome")
>d words.Insert("to")
>d words.Insert("DeclarativeCOS!")

>zforeach $zbind(words, "myIO:println")

Шаг 5. Почувствовать счастье!
Welcome
to
DeclarativeCOS!


Как это работает


Проект DeclarativeCOS использует глобал ^DeclarativeCOS для того чтобы сохранить информацию о методах, помеченных аннотацией @Declarative(declarativeName).

Каждая такой метод сохраняется в глобал в следующем виде:

set ^DeclarativeCOS(declarativeName) = $lb(className, classMethod)

Например, для функции io:println:

set ^DeclarativeCOS(“io:println”) = $lb(“DeclarativeCOS.IO”, “println”)

Каждый раз, когда используется функция io:println происходит поиск по глобалу, а потом функция $classmethod сделает вызов исходного метода (DeclarativeCOS.IO # println) на заданном значении.

Заключение


DeclarativeCOS это вклад в новый Cache ObjectScript. В тот самый язык, который действительно помогает своим разработчикам писать программы быстро, лаконично, просто и надежно. Добро пожаловать в критику, поддержку и мнения в комментарии под этим постом!)

Disclaimer: данная статья и мои комментарии к ней является моим мнением и не имеют отношения к официальной позиции корпорации InterSystems.
Поделиться с друзьями
-->

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


  1. m03r
    24.04.2017 12:32
    #10188350

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

    P. S. А где монады?


    1. alexkunin
      24.04.2017 13:00
      #10188418

      Brainfuck же.

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


      1. m03r
        24.04.2017 13:14
        #10188452

        Ну, всё же они (кроме Brainfuck) были созданы именно для помощи программистам — насколько это было возможно при имеющихся ресурсах.


        1. alexkunin
          24.04.2017 13:40
          #10188492

          Ну, да, вы правы — если «быстро, лаконично, просто и надежно» относительно машкодов.

          были созданы именно для помощи программистам — насколько это было возможно при имеющихся ресурсах
          Тоже верно, но с какого-то момента программистов стало много, все разного уровня, и поэтому Бейсик с С++ сравнивать нельзя, т.к. у целевых аудиторий очень разные понятия о «просто», «лаконично» и т.д.

          В общем я с вами даже не спорю, просто поправил бы ваше «про какой язык нельзя сказать» на «про какой профессиональный язык нельзя сказать». Просто прицепился к максимализму во фразе, не обращайте внимания.


    1. jxcoder
      24.04.2017 13:13
      #10188444

      Монад пока нет, при желании можно добавить.


  1. TheShock
    24.04.2017 13:00
    #10188416

    Простите, а можете объяснить, пожалуйста, в чем декларативность? Мне код кажется очень императивным? «Сделай а, потом б, потом в».

    То, что используются процедуры, а не классы еще ведь не делает код декларативным


    1. jxcoder
      24.04.2017 13:11
      #10188440

      Тонкое замечание) спасибо за вопрос!)

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


      1. vics001
        24.04.2017 15:24
        #10188716
        +1

        Декларативный стиль предполагает «выполни задачу А, но я не знаю как», императивный — «сделай шаг А1, затем шаг А2». Грубо говоря императивный стиль описывает «алгоритм», а декларативный описывает «постановку задачи на формальном языке». If/else/for/while — все это признаки императивного стиля.


        1. jxcoder
          24.04.2017 16:46
          #10188874
          +2

          Согласен. Но давайте взглянем на этот проект свежим взглядом.

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

          Как это сделать в императивном стиле? В императивном стиле мы должны пройти по всей коллекции и вручную соединять ее элементы с разделителем попутно формируя итоговую строку.

          Как это будет выглядеть в декларативном стиле? Я себе это понимаю так, что мы говорим языку программирования «Эй, дружище, а сделай мне пожалуйста строку из вон той коллекции! И, да, кстати, вставь пожалуйста между элементами этой коллекции разделитель. Какой? Вот этот.».

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

          Вначале создадим коллекцию из букв.

          >s symbols = ##class(%ListOfDataTypes).%New()
          >d symbols.Insert(“H”)
          >d symbols.Insert(“e”)
          >d symbols.Insert(“l”)
          >d symbols.Insert(“l”)
          >d symbols.Insert(“o”)


          А теперь решим поставленную задачу.
          >w $zjoin(numbers, “ ”)
          H e l l o


          Всего одна функция. Никакой императивности. Мы говорим что хотим и получаем это.


          1. TheShock
            24.04.2017 17:10
            #10188922

            Разве воспользоваться библиотечной процедурой — уже декларативность? Си — декларативен?
            А ваше создание коллекции из букв разве не императивность?
            По-моему, вы написали обычную процедурную либу.

            Сейчас почему-то модно называть стиль php 4-й версии декларативным и функциональным)


            1. jxcoder
              24.04.2017 17:26
              #10188940
              +1

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

              «Библиотечная процедура» — звучит очень здорово!) я понимаю к чему Вы ведете.

              Я понимаю так, что «декларативность» — способ решения задачи. Если мы решаем какую-то задачу и при этом не заморачиваемся над тем, чтобы описать ее реализацию, то пожалуй это всегда здорово независимо от того как мы это будем называть) Ведь так?)

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

МЕТКИ

  • Хабы
  • Теги

Проектирование и рефакторинг

Программирование

NoSQL

Блог компании InterSystems

intersystems cache

COS

cache objectscript

declarative

programming

creative

programming art

open source

СЕРВИСЫ
  • logo

    CloudLogs.ru - Облачное логирование

    • Храните логи вашего сервиса или приложения в облаке. Удобно просматривайте и анализируйте их.
Все публикации автора
  • DeclarativeCOS — Декларативное программирование на Cache +15

    • 24.04.2017 08:45

    MonCache — реализация MongoDB API на основе InterSystems Cache +13

    • 08.02.2016 09:30

    NSNJSON. ? (Заключительная статья) +10

    • 06.11.2015 05:00

    Не COSим от разработки на Cache +4

    • 04.11.2015 21:46

    JSON для любителей скобочек -3

    • 02.11.2015 18:09

    Усложнённый упрощённый JSON -6

    • 25.10.2015 18:05

Подписка


ЛУЧШЕЕ

  • Сегодня
  • Вчера
  • Позавчера
10:53

Как троттлинг процессора ломает видеокарту через PCIe: хроники абсурда в сервисном центре DNS +49

09:01

Вот бы вернуть те старые неказистые форумы +25

13:01

ЭВМ в народном хозяйстве: лампы, кибернетика, «Урал-1» +23

06:40

Старый трансивер эфир не испортит. Часть 3. Умощняемся +23

13:30

Тегеран, 1978: Диско бессмертно +21

05:52

Книга среднего уровня — 1 +16

11:09

Галлюцинации: почему LLM «тупеют» от «умных» промптов +14

13:10

Съездили к ByteDance и Z.ai: роботы по паспорту, серверные карты на рынке и восемь дней внутри китайского AI +10

08:31

Чума оказалась очень древней. Что произошло в Сибири 5 500 лет назад +9

08:47

Действительно богатые сообщения в Telegram-ботах: разбираем Rich Messages +8

12:38

350 тысяч за вакансию: сколько на самом деле стоит нанять человека в 2026 году +7

12:05

Гибель богов. Fable и ещё 10 LLM реорганизуют код. Сравнение +7

08:16

Библиография тоже умеет галлюцинировать: что изменилось после защиты диплома +7

16:07

Age of Mythology в 2026 году: от мифов Древней Греции до ацтеков — почему стратегия все еще жива +6

11:30

Очередной выпуск гонзо-научпопа из сердца Анд. Поговорим о сукцессии +6

09:00

ИИ добрался до раритетов: цены на память DDR2 взлетели на 60% за три месяца +6

17:03

Ghidra — фреймворк АНБ для реверс-инжиниринга ПО +5

15:01

Где лучше создавать изображения по фото — выбираем из ТОП-6 ИИ с примерами и промптами +5

13:00

Unreal Engine 6 на Verse — это что-то крышесносное +5

08:22

Как я разработал простой PHP-фреймворк, двигающий разработку вперёд +5

08:00

«Иностранные холодные кошельки» — или нами когда-нибудь перестанут управлять идиоты? +91

23:14

Taskbar с живыми превью работающих приложений (олдскул на NET11) +37

08:15

Сэнди Петерсен и Джон Кармак: как Quake сломал id Software +33

13:19

Носители данных — «игра на выбывание» (2026.07) +30

17:37

Используем старый Mikrotik как сигнализацию +29

13:02

Самодельная электрогитара: тонируем деку и подгоняем к ней гриф +26

08:30

5 новых одноплатников лета 2026 года: x86, Snapdragon и сменные процессоры +25

09:05

Пока все ждут GTA. Вспоминаем, что ещё делала Rockstar и удивляемся некоторым наименованиям +24

09:01

«Из ниоткуда в Грецию» и похищенный врач: что стояло за волной сообщений о странных дирижаблях в США 1890-х годов? +23

10:03

Телефон из 1999 года: Alcatel One Touch Pocket. Что внутри? +22

13:05

Подземный гигант: зачем Швейцария строит самую мощную батарею в мире +19

18:05

Игра проигравшего +18

12:55

Различие между научной гипотезой, теорией и законом +15

11:50

USB-ключ для ввода TOTP-кодов и сохранённого пароля +15

14:07

«Уэбб» обнаружил новый сюрприз в ранней Вселенной: зрелое скопление галактик +12

09:16

Нужен ли здесь `useEffect`? 12 сценариев из React-код-ревью — от производного состояния до React 19.2 +12

08:27

От игры за $999 до симулятора автобуса: самые странные проекты в истории Steam +12

18:53

Как я обучил русский RAG‑сплиттер, который режет документы по индексам, а не по тексту +11

17:04

Иллюзия безопасности или как ваши сотрудники прямо сейчас обучают конкурентов +11

16:52

Переоценённый король +11

04:00

B4 — сетевой мультитул по обходу блокировок +116

14:40

АВК-6: Персональный Аналоговый Компьютер +93

14:33

Как ИИ и очереди на заправках повлияли на появление нового социального феномена +65

07:25

PowerHTML +61

07:01

Несложные ходовые вакуумметры. Часть 1. Манометры сопротивления (Пирани) +47

15:00

Симулятор восприятия: три секунды побыть тем, кто не видит вашу кнопку +42

07:30

Почему интервью для разрабов — такое непроходимое говно, и что с этим делать? +40

13:02

Паттерны доступа к данным, которые выбесят ваш процессор +39

11:55

Как я запустил перцептрон на обычном непрограммируемом калькуляторе Casio +38

22:52

ставим 6 прoкси в 2 клика за 5 минут на 1 VPS +36

09:01

Практическое руководство по аудиту беспроводных сетей (Wi-Fi) на промышленных объектах и складах +33

07:05

От пламени прошлого — до сверхсовременных дальнобойных фонарей: история света, часть-2 +31

09:27

Agent Driven SDLC: как меняется разработка в эпоху ИИ +29

09:27

Agent Driven SDLC: как меняется разработка в эпоху ИИ +29

09:00

T-Shaped специалист: эволюция или ловушка современного IT? +24

08:00

Почему мощных видеокарт недостаточно для ИИ +24

10:14

Запускаем LLM локально на майнинг ферме из 4 GPU +23

15:00

Новинка: «Инженерия данных. Паттерны проектирования» +22

11:35

Все внедрили AI. Почти никто им не пользуется. Разбор самого массового вранья года +20

23:43

Картофельный парадокс Нечерноземья: почему урожайность растёт, а полки завалены импортом +15

ОБСУЖДАЕМОЕ

  • Как ИИ и очереди на заправках повлияли на появление нового социального феномена +65

    • 273   48000

    «Иностранные холодные кошельки» — или нами когда-нибудь перестанут управлять идиоты? +91

    • 121   22000

    Как троттлинг процессора ломает видеокарту через PCIe: хроники абсурда в сервисном центре DNS +49

    • 87   12000

    АВК-6: Персональный Аналоговый Компьютер +93

    • 56   16000

    B4 — сетевой мультитул по обходу блокировок +116

    • 56   46000

    Подземный гигант: зачем Швейцария строит самую мощную батарею в мире +19

    • 45   12000

    Хватит винить HR: почему «плохие рекрутёры» — самый удобный, но неверный ответ на кризис найма +2

    • 42   5600

    Taskbar с живыми превью работающих приложений (олдскул на NET11) +37

    • 41   15000

    JetBrains IDE: будущее не за горами +8

    • 39   15000

    ставим 6 прoкси в 2 клика за 5 минут на 1 VPS +36

    • 38   21000

    Игра проигравшего +18

    • 37   11000

    PowerHTML +61

    • 35   10000

    Тегеран, 1978: Диско бессмертно +21

    • 31   7200

    Запускаем LLM локально на майнинг ферме из 4 GPU +23

    • 30   11000

    HTTP получил метод QUERY: зачем понадобился безопасный запрос с телом +15

    • 28   12000
  • Главная
  • Контакты
© 2026. Все публикации принадлежат авторам.