Libretto Language: Symbol Reference

anglequote

description:
The angle quotes « and » (the ASCII versions are ^" and "^) are used to define angle strings. An angle string does NOT have its own escaping sequences. Its interpretation depends on further processing (e.g. as a normal string, an XML code etc.) Since opening and closing quotes are different, angle strings can be nested in each other (like parentheses). The combination of angle strings and ! (eval) provides the presentation of nested expressions in parametrized strings.
symbol:
« (^")
» ("^)
crib:
«abc»   # = abc
^"abc"^   # = abc

«{«{1+2}»}»  # = {«{1+2}»}
«{«{1+2}»}»!   # = {1+2}
«{«{1+2}»}»!!    # = 3

«"normal string1" 'normal string2'» 

"\x3F"     # = ?

«\x3F»;    # = \x3F

«<address type="email">a@ontobox.org</address>»/x:readXml()/x:ee("address")/x:a("type")   # = "email"
linked:
string
parametrized string

arithop

description:
The next symbols is used as arithmetic operators:
"+" means addition;
"-" means subtraction;
"*" or "·" means multiplication;
"div" means exact division for whole numbers and division with remainder for decimal numbers (fractions);
"mod" means division with remainder for any kind of numbers. This operator may be used only for whole numbers
"==" means equality of two entities;
"≠" or "!=" means non-equality of two entities;
"<" ("≤") means that one number is less (less or equal) than another one;
">" ( "≥") means that one number is greater (greater or equal) than another one.
symbol:
+
-
· (*)
==
≠ (!=)
<

>

mod
div
crib:
1 + 2; # 3
6 - 21; # -15
5 * 6 · 2; # 60

7 div 4; # 1
7.0 div 4; # 1.75
9 div 4.5; # 2.0
10 mod 3; # 1
10.0 mod 3; # error

1 >= 1; # true
1 > 6; # () - empty set means false
5.0 == 5; # true
3 != 23 ; # true
1 &lt; 1; # ()

linked:
expression

as

description:
“as” is used as an operator which allows user to assign variables. This may be useful in order to save data which appear along the query path.
symbol:
as
crib:
(1,2,3) as x/(1,2,3) as y/ (x * y); # (1,2,3,2,4,6,3,6,9)

class Person {name v:string; lastname v:string};
class Father extends Person {child Person};

Father &amp;john {name = 'John'; lastname = 'Smith};
Person &amp;ray {name = 'Ray'; lastname = 'Charles'};
&amp;john {child = &amp;ray};

Father as f/ child [lastname ≠ f/lastname] /
'{name} has changed his last name'! #Ray has changed his last name

linked:
variable
sequence
iteration

assign

description:
These operators are used in the operations of assignment:
“=” means destructive assignment variables (data are replaced by new values);
“.=” means adding data to the beginning of a value sequence;
“+=” means adding to the end of a value sequence.
In case of using the destructive assignment ("="), creating of a new object with empty properties is impossible. But new object still can be created if ".=" or "+=" is used to assignment new values, even though one of the property values is empty.
symbol:
=
.=
+=
crib:
class Message {text v:string[1,1]} #the property must have only one value
class Thread {messages Message[0, ]}#the property can have any amount of values

Message &amp;m1, &amp;m2, &amp;m3, &amp;m4;
Thread &amp;t {messages = &amp;m1}/messages; # (&amp;m1)
&amp;t {messages .= &amp;m2}/messages; # (&amp;m2, &amp;m1)
&amp;t {messages += (&amp;m3, &amp;m4)}/messages; # (&amp;m2, &amp;m1, &amp;m3, &amp;m4)
&amp;t {messages = &amp;m3}/messages; # &amp;m3

Thread &amp;_{messages = Message[text/v:contains('ontology')]} # the object has not been
created, because there are no messages containing word 'ontology'
# But we may use either += or .= to ?surely? create the object
Thread &amp;_{messages += ()]} # &amp;_4c5aec32-c07c-49fc-86fa-0ddbf6e78bc1

linked:
property
variable

atsym

description:
“@” is used as a key to a schemeless declaration of objects and their values at the same time. Also symbol “@” can be used as an annotation to classes, properties or ontologies.
symbol:
@
crib:
creating an object and properties on the fly 
&amp;_ {@fileName = 'test.jsp'; @fileSize = '234'};

class Titled {title v:string};
%Titled {@comment = 'Class with t-property title'} # class Title now has an annotation
%title {@comment = 'title value'}/@comment # title value
linked:
key

bracket

description:
The brackets “[]” are used to distinguish a predicate from the rest of an expression.
Another application of brackets is when in the brackets “[]” indices of a sequence are enclosed. Through using the brackets “[]” an access to elements of a sequence may be done.
Also the brackets "[]" allow user to limit number of property values on the model level.
symbol:
[
]
crib:
#brackets for condition
class Employee {salary v:int};
Employee &amp;_ {salary = 200};
Employee &amp;_ {salary = 300};
Employee [salary > 200 ] # get all employees with salary higher than 200

#brackets for accessing an element of the sequence
(1,2,3) [2] # 3

#brackets for declaring limits on the amount of values
class Mother {
    name v:string[1, 1]; #one and only one name
    children Person[1, ]; #not less than one child
    passport v:int[, 1]; #not more than one passport
}
linked:
predicate
sequence (index)

break

description:
Breaks the innermost iteration. For deep breaks/returns use funcitons label/3 and rollback/1. Breaks can influence through the functions but not generators.
symbol:
break
crib:
(1,2,3,0,4,5,6)/(if (. = 0) break else .); # = (1,2,3)

def g() {case . = 0 => break; case => .};
(1,2,3,0,4,5,6)/g();    # = (1,2,3)

gen gg() {if (. = 0) break else  .};
(1,2,3,0,4,5,6)/g(); # Error: Misplaced break...
linked:
sequence
iteration

class

symbol:
class
linked:
class

colon

symbol:
:
linked:
name
namespace
ontology

comment

symbol:
#
linked:
program

curly

symbol:
{
}
linked:
modifier
function
anonymuous function
block

def

description:
A keyword for defining a named function with the element-wise behavior.
symbol:
def
crib:
def fact($x) {
    case $x = 0 => 1; 
    case => $x * fact($x - 1)};

fact(7);     # = 5040
(1,2,3,4,5) / fact(.);     # = (1,2,6,24,120)

def untilZero() {
    case . = 0 => break;
    case => .
};

(1,2,3,0,4,5,6) / untilZero();      # = (1,2,3)
linked:
function

dollar

description:
Determines a variable, e,g, $x, $counter. Operation := is used to destructively assign values to variables. Libretto has global and local variables (in function and generator definitions). Variable names are unqualified (can not have prefixes). Global variables are not accessible within function bodies. Variables and their values are not saved in ontologies and valid only within the Libretto code that contains them. The combination of variables with operation as is convenient for organizing iterations over sequences in paths.
symbol:
$
crib:
#$x is global
$x := 115;

# $y is local
def f($y) {$y + 1};

# locals are valid only within function bodies
$x;   # = 115
$y;    # Error: Global variable $y is not instantiated
f(5)    # = 6

# no access to globals within the function bodies
def ff() {$x};
ff();     # Error: Local variable $x is not instantiated

# variables as fields in paths
$numbers := (1,2);
("a", "b") as $s / $numbers as $n / ($s + $n);       # = ("a1", "a2", "b1", "b2")


linked:
variable

dot

description:
The dot . is an analogue of 'this' and 'self' in object-oriented languages. It equals the current context. If the context is element-wise (e.g. in the call of a function) then . iteratively takes the value of each element of the context sequence. In the collection-wise context (e.g. in a call of a generator) . equals the whole sequence.
symbol:
.
crib:
# in the element-wise context the dot . iteratively takes the value of each element of the context sequence
(1,2,3,4,5) / (. + 3)  # = (4,5,6,7,8)

# in the collection-wise context of the built-in generator intersection/2 the dot . takes as the value the whole sequence at once
(1,2,3) / v:intersection(. , (2,3,4)); # = (2,3)

# functions are evaluated in the element-wise style, so the dot iteratively enumerates each value of the context sequence
# break is used to stop the iteration over the context sequence
def f() {case . = 0 => break; case => .}; 
(1,2,3,0,4,5,6)/f();    # = (1,2,3)
# . = 0 is checked here number by number: 1 = 0, 2 = 0, 3 = 0, 0 = 0


# generators are evaluated in the collection-wise style, so in them the dot takes the whole sequence as value
# break could be senseless here, because there is no iteration to stop: the sequence is taken as a whole
gen g() {case . = 0 => return; case => yield .};
(1,2,3,0,4,5,6)/g();    # = ()
# . = 0 is checked for the whole sequence at once: (1,2,3,0,4,5,6) = 0, and since it is true, the computation immediately returns

# the first dot takes the whole sequence, the second dot iteratively takes the value of each number:
gen sum() {$s := 0; .  / {$s := .  + $s}; yield $s};
(1,2,3,4,5)/sum();    # = 15

linked:
sequence
iteration

exclaim

description:
The exclamation mark ! evaluates the expression. There are three types of such expressions: parametrized strings, blocks and functions (anonymuous functions or function entities):
  • A string (e.g. «1+2 = {1+2}») is interpreted as a parametrized string, in which expressions in curly brackets are evaluated. The optional second argument of ! determines the escaping function transforming the results of evalutation. It is recommended to use angle quotes to provide nested evaluations.
  • A block (e.g. _{1+$x}): the expression(s) of the block is evaluated. In case of blocks ! does not have the second argument.
  • An anonymuous function or a function entity (e.g. _($x) {$x + 1} and %v:intersection^2: the function is evaluated; the mandatory second argument contains the arguments of the evaluated function.
Actually ! is the syntactic sugar for built-in functions v:eval/1 and v:eval/2.
symbol:
!
crib:
# in case of parametrized strings ! evaluates expressions in curly brackets:
«1 + 2 = {1 + 2}»!  # =  1 + 2 = 3

# use angle quotes « and » to organize nested evaluations:
«{«{1+2}»}»  # = {«{1+2}»}
«{«{1+2}»}»!   # = {1+2}
«{«{1+2}»}»!!    # = 3

# the first argument of ! can be an arbitrary expression:
$x1 := "{1";
$x2 := "2}";
($x1 + "+" + $x2)!;    # = 3

# the evaluated expression can depend on the context values:
(2,3) / «{.} + 2 = {. + 2}»!  # =  ("2 + 2 = 4", "3 + 2 = 5") 

# the optional 2nd argument of ! determines the escaping function, which acts on the evaluated expressions:
«&lt;a>{«&lt;b>ccc&lt;/b>»}&lt;/a>»!  # = &lt;a>&lt;b>ccc&lt;/b>&lt;/a>
«&lt;a>{«&lt;b>ccc&lt;/b>»}&lt;/a>»!x:esc  # = &lt;a>&amp;lt;b>ccc&amp;lt;/b>&lt;/a>

# any unary function can be used as the escaper:
def f($x) {$x + " is escaped"};
«the expression {«exp1»} and {«exp2»}»!f    # = the expression exp1 is escaped and exp2 is escaped

# ! can also evaluate blocks:
_{1+2}!;    # = 3

# a block saves the values of variables, which they have at the moment of block's creation (so-called closure semantics):
$x := 5;
$block := _{$x + .};
$x := 1000;
(2,5)/$block!;    # = (7,10)

# in case of functions the 2nd argument of ! is mandatory (it transfers parameters to functions):
%v:intersection^2 ! ((1,2,3),(2,3,4))    # = (2,3)

$z := 5;
$fun := _($x, $y) {($x + $y) * $z};
$z := 0;
$fun ! (2,3);    # = 25
# note that the body of an anonymuous function can contaion global variables, which also follow the closure semantics

# actually ! is a syntactic sugar for built-in functions v:eval/1 and v:eval/2
"{1+2}" !;   # = 3
v:eval/1("{1+2}");   # = 3
 
2 / _($x) {. * $x} ! (3);  # = 6
2 / v:eval(_($x) {. * $x}, _{(3)});  # = 6



linked:
block
anonymuous function
function
parametrized string

gen

symbol:
gen
linked:
generator

if

symbol:
if
else
linked:
expression

inverse

symbol:
~
linked:
property

logicop

symbol:
∧ (and)
∨ (or)
¬ (not)
linked:
expression
predicate

ontology

symbol:
ontology
linked:
program

parentheses

symbol:
(
)
linked:
sequence
function
anonymuous function

persent

symbol:
%
linked:
entity

prefix

symbol:
prefix
linked:
ontology
namespace
name

question

description:
Variables $_0..$_9 are used in combination with the question mark: ith occurrence of the question mark corresponds to the value of the ith variable. This construct is used in a number of web-programming techniques.
symbol:
?
crib:
$_0 := 10;
$_1 := 20;
$_2 := 30;

? + ? + ?;     # = 60

linked:
variable
query

quote

symbol:
"
'
linked:
string
parametrized string

remove

symbol:
--
linked:
property
object

require

symbol:
require
linked:
repository
ontology
community

return

description:
Returns from functions and generators
symbol:
return
linked:
function
generator

semicolon

symbol:
;
linked:
program
query
modifier
predicate

slash

description:
Connects the steps of a path.
symbol:
/
linked:
path
path step

sorter

description:
Sorts the context collection using a comparator (any expression which produces linearly ordered values).
symbol:
<<
>>
crib:
# example 1
(3,2,1,6,4,5)&lt;&lt;.>>    # = (1,2,3,4,5,6)


# example 2
def titleNumber() {
    v:match("(\\d*).*", "")/$_m1/v:to-int()
};

"10 Asterisks"/titleNumber();    # = 10

$titles := ("9 Data Types", "8 Modifiers, Predicates and Sequences", "10 Asterisks");

$titles&lt;&lt;.>>;
    # = ("10 Asterisks", "8 Modifiers, Predicates and Sequences", "9 Data Types")

$titles&lt;&lt;title-number()>>
    # = ("8 Modifiers, Predicates and Sequences", "9 Data Types", "10 Asterisks")
linked:
path
path step

xmlsym

description:

XML and XHTML elements are the normal expressions of Libretto. Actually they are translated into expressions, which combine builtin functions x:add/1, x:elem/1, x:attr/2. The evaluation of this expression produces a number of objects, which together represent the XML document. To work with XML documents it is necessary to load the XML ontology from the repository:

require x "http://xml.ontobox.org/";
symbol:
<>
crib:
#  An XML element is translated into the set of objects; the root object of the XML-expression is returned:
$xml := &lt;address type=&quot;postal&quot;&gt;&lt;street&gt;Main&lt;/street&gt;&lt;building&gt;15&lt;/building&gt;&lt;/address&gt;
        # = &amp;_bb9fb4ad-8077-40ad-bf5b-2a94368f454e

#  The structure of XML objects is determined in the ontology http://xml.ontobox.org/, 
#  including such classes as x:Element, x:Text, etc. and properties x:name, x:attributes, x:text ets.
$xml/x:name;    # = "address"
$xml/x:attributes[x:name = "type"]/x:value;    # = "postal"

#  Built-ins x:e/1, x:ee/1, x:a/1, x:t/0, x:tt/0 are convenient for handling data in the XML document
$xml/x:e("street")/x:t();    # = "Main"
$xml/x:a("type");     # = "postal"  
$xml/x:tt()/v:join(", ");     # = "Main, 15"    
$xml/x:ee()/x:name;     # = ("address", "street", "building")

#  The functions x:write-xml/0 and x:write-xml/2 reconstruct the XML document from the XML objects.
$xml / x:write-xml();
        # = «&lt;address type=&quot;postal&quot;&gt;&lt;street&gt;Main&lt;/street&gt;&lt;building&gt;15&lt;/building&gt;&lt;/address&gt;»

#  The functions x:read-xml/0 and x:read-xml/1, x:read-html/1 and x:read-html/3 load XML documents
$ontobox := x:read-html("http://ontobox.org/", "utf-8");
        # = &amp;_78c5f90c-2e81-43eb-88cd-e6a1a022173f
$ontobox/x:ee()/x:name/v:distinct(); 
        # = ("html", "head", "meta", "link", "title", "body", ...)
($ontobox/x:ee("h2")/x:t())[0];        # = "Overview"
$ontobox/x:ee("div")/x:a("class");        # = ("mm_left", "mm_right", ... )

#  XML expressions can contain parameters in curly brackets {..}
$street := &lt;street>Main&lt;/street>;
$num := 15;
$tp := "postal";
&lt;address type={$tp}&gt;{x:elem(&quot;street&quot;)/x:add(x:text(&quot;Main&quot;))}{&quot;&lt;building&gt;{$num}&lt;/building&gt;&quot;! / x:read-xml()}&lt;/address&gt; / x:write-xml()
        # = "&lt;address&gt;&lt;street&gt;Main&lt;/street&gt;&lt;building&gt;15&lt;/building&gt;&lt;/address&gt;"

#  Actually XML expressions are translated into combinations of built-in functions, which are further evaluated:
$xmlblock := _{&lt;address type=&quot;postal&quot;&gt;&lt;street&gt;Main&lt;/street&gt;&lt;building&gt;15&lt;/building&gt;&lt;/address&gt;}; 
        # = {x:elem("address") / x:add(x:attr("type", "postal")) / 
        #     x:add(x:elem("street") / x:add(x:text("Main"))) / x:add(x:elem("building") / 
        #          x:add(x:text("15")))}
$xmlblock! / x:name;        # = "address"

#  XML objects are always created in a special 'heap' ontology, which is determined by its prefix xheap:
xheap:*/x:name/v:distinct()&lt;&lt;.>>;        # = ("address", "building", "street", "type")

linked:
XML
expression

yield

description:
Places its argument into the output sequence of the generator in which it occurs. yield is a keyword of Libretto. It works only in generators, not in functions.
symbol:
yield
crib:
# The class of a tree with named nodes is defined by two constructors:
class Tree(name v:string, subnodes Tree);
class Tree(name v:string);

# collect/1 collects nodes with a certain name:
gen collect($name v:string) {
    yield .[name = $name];
    yield subnodes/collect($name)
};


# example: create the tree with 3 nodes two of which named 'b'
$tree := Tree(":n1", "a",
             (Tree(":n2", "b", ()), 
              Tree(":n3", "b", ())));   # = &amp;n1

$tree / collect("b");    # = &amp;n2, &amp;n3
linked:
generator