DeclarativeCOS - Declarative Caché Programming
The goal of the project is to draw the attention of the community to improving the internal core of COS.
The idea of the project is to support concise syntax when working with loops and collections.

So, what did I come up with concise? Welcome to the examples!
Examples
The key concept of the project is a declarative approach. It is necessary to indicate WHAT to use and HOW.
Personally, I always lacked a simple operator / command / spell in the COS terminal in order to display the collection on the screen in the form in which you want it. And now there are two nice things: zforeach and $ zjoin !
>s words = ##class(%ListOfDataTypes).%New()
>d words.Insert(“Hello”)
>d words.Insert(“World!”)
>zforeach $zbind(words, “io:println”)
Hello
World!Here it is worth telling more about the $ zbind function . To begin with, COS can be expanded with its commands and functions, which can be described in detail in the relevant documentation and article on the developer community portal.
This function creates an instance of the Binder class . Its task is to link the collection and the function that needs to be applied to each element of the collection. In this case, a standard function called “io: println” from DeclarativeCOS is used , which for a given value value executes a simple command:
>w value,!The zforeach team works with an instance of the Binder class, sequentially going through the collection and applying a function to each of its elements.
$ zjoin - creates a string from the collection, combining its elements between which the specified separator is added.
>s numbers = ##class(%ListOfDataTypes).%New()
>d numbers.Insert(“04”)
>d numbers.Insert(“03”)
>d numbers.Inset(“2017”)
>w $zjoin(numbers, “ / ”)
04 / 03 / 2017
$ zmap - creates a new collection from the elements of the original collection to each element of which the specified function is applied.
>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 - Finds the first element of the collection on which the specified function returns $$$ YES. Otherwise returns a null string.
>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="":"", 1:primeNumber)
Prime number: 41 $ zfilter - creates a new collection based on the original collection, but taking only those elements on which the specified function returns $$$ YES. If there are no such elements, then returns an empty collection.
>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 - Verifies that the collection has at least one element on which the specified function returns $$$ 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 - count the number of elements in the collection on which the specified function returns $$$ 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: 2Installation
To install DeclarativeCOS, just download two files from the official GitHub repository of the project:
- install.base.xml are just classes. Without z-functions.
- install.advanced.xml -% ZLANG routines that add z-functions.
How to use
- Inherit a class from DeclarativeCOS.DeclarativeProvider .
- Implement a class method.
- Mark this method with @Declarative annotation.
- Use the z-functions of DeclarativeCOS.
- Feel the happiness.
detailed instructions
Class MyPackage.IO extends DeclarativeProvider
{
}Class MyPackage.IO extends DeclarativeProvider
{
ClassMethod println(value As %String)
{
w value,!
}
}Class MyPackage.IO extends DeclarativeProvider
{
/// @Declarative("myIO:myPrintln")
ClassMethod println(value As %String)
{
w value,!
}
}>s words = ##class(%Library.ListOfDataTypes).%New()
>d words.Insert("Welcome")
>d words.Insert("to")
>d words.Insert("DeclarativeCOS!")
>zforeach $zbind(words, "myIO:println")Welcome
to
DeclarativeCOS!How it works
The DeclarativeCOS project uses the ^ DeclarativeCOS global to store information about methods marked with @Declarative (declarativeName) annotation.
Each such method is saved to the global as follows:
set ^DeclarativeCOS(declarativeName) = $lb(className, classMethod)For example, for the io: println function :
set ^DeclarativeCOS(“io:println”) = $lb(“DeclarativeCOS.IO”, “println”)Each time the io: println function is used , a global search is performed, and then the $ classmethod function makes a call to the original method (DeclarativeCOS.IO # println) at the given value.
Conclusion
DeclarativeCOS is a contribution to the new Caché ObjectScript. In the very language that really helps its developers write programs quickly, concisely, simply and reliably. Welcome to the criticism, support and opinions in the commentary under this post!)
Disclaimer: this article and my comments on it are my opinion and are not related to the official position of InterSystems Corporation.