SlideShare a Scribd company logo
IRODS Cheat Sheet (version 3+) 
Version 0.9 by Samuel Lampa, BILS (bils.se) 
Contact author: samuel dot lampa at bils dot se 
Numeric Literals 
1 # integer 
1.0 # double 
Strings 
'A 'string', ' ++ "another ”string”" 
# Some valid escape characters: 
“n, r, t, , ', ", $, *" 
Boolean constants 
true # True 
false # False 
Boolean comparison 
! # Not 
&& # And 
|| # Or 
%% # Or used in the "##" syntax 
Arithmetic operators 
- # Negation 
^ # Power 
* # Multiplication 
/ # Division 
% # Modulors 
- # Subtraction 
+ # Addition 
Arithmetic comparison 
> # Greater than 
< # Less than 
>= # Greater than or equal 
<= # Less than or equal 
Arithmetic functions 
exp(<num>) 
log(<num>) 
abs(<num>) 
floor(<num>) # always returns integer 
ceiling(<num>) # always returns integer 
average(<num>, <num>, ...) 
max(<num>, <num>, ...) 
min(<num>, <num> , ...) 
String functions 
writeLine("stdout", "Hi!"); 
Prints out “Hi!.” 
"This “++”is”++” a string." 
Equals to “This is a string.” 
"This is a string." like "This is*" 
Equals to true 
"This is." like regex "Th.*is[.]" 
Equals to true 
substr("This is a string.", 0, 4) 
Output: This 
strlen("This is a string.") 
Output: 17 
split("This is a string.", " ") 
Equals to: [This,is,a,string.] 
writeLine("stdout", triml("This is a 
string.", " ")); 
Equals to: is a string. 
trimr("This is a string.", " ") 
Equals to: This is a 
List functions 
list(<elem>, <elem>, ...) 
Creates a new list, Ex: 
list("This","is","a","list") 
elem(<list>, <index>) 
Retrieves elements from a list (0-indexed). Ex: 
elem(list("This","is","a","list"),0) 
# returns “This” 
setelem(<list>, <index>, <value>) 
Updates an item in a list. Ex: 
setelem(list("A","list"),0,"My") 
# Evaluates to list("My","list"). 
size(<list>) 
Gives the size of a list. Ex: 
size(list("This","is","a","list")) 
# evaluates to 4. 
hd(<list>) 
Gives the head of a list, Ex: 
hd(list("This","is","a","list")) 
# Evaluates to "This" 
tl(<list>) 
Gives the tail of a list. Ex: 
tl(list("This","is","a","list")) 
# Evaluates to list("is","a","list") 
cons(<element>, <list>) 
Add elements to a list. Ex: 
cons("My",list("list")) 
# Evaluates to list("My","list"). 
Tuples 
Tuples are created like so: 
( <component>, ..., <component> ) 
If statements 
Logical if: 
if <expr> then { <actions> } 
else { <actions> } 
Logical if example: 
if (*A==1) then { true; } else { 
false; } 
Functional if (returning value of any type): 
if <expr> then <expr> else <expr> 
Functional if example: 
if true then 1 else 0 
if *A==1 then true else false 
The following abbreviation are allowed (the red 
striked part can be abbreviated) in functional ifs: 
if (...) then { ... } else { ... } 
if (...) then { ... } else { if (...) 
then {...} else {...} } 
Multiple abbreviations can be combined for 
example: 
if (*X==1) { *A = "Mon"; } 
else if (*X==2) {*A = "Tue"; } 
else if (*X==3) {*A = "Wed"; } 
Foreach loops 
Without iterator: 
foreach(*C) { 
writeLine("stdout", *C); 
} 
With the iterator variable (*E in this case): 
foreach(*E in *C) { 
writeLine("stdout", *E); 
}
Defining functions 
Functions can be thought of as microservices written 
in the rule language and are defined like this: 
<name>(<param>, ..., <param>) = <expr> 
Example: 
square(*n) = *n * *n 
Variables in functions: The let expression 
As function definitions are based on expressions 
rather than action sequences, we cannot put an 
assignment directly inside an expression. For 
example, the following is not a valid function 
definition: 
quad(*n) = *t = *n * *n; *t * *t 
To solve this problem, the let expression provides 
scoped values in an expression. The general syntax for 
the let expression is: 
let <assignment> in <expr> 
For example: 
quad(*n) = let *t = *n * *n in *t * *t 
The variable on the left hand side of the assignment in 
the let expression is a let-bound variable. The scope of 
such a variable is within the let expression. A let 
bound variable should not be reassigned inside the let 
expression. 
Defining Rules 
Define rules with nontrivial rule conditions like this: 
<name>(<param>, ..., <param>) { 
on(<condition>) { <actions> } 
} 
The rule condition can be skipped for rules with trivial 
or non-existent conditions: 
<name>(<param>, ..., <param>) { 
<actions> 
} 
A rule can have multiple conditional expressions: 
<name>(<param>, ..., <param>) { 
on(<condition>) { <actions> } … 
on(<condition>) { <actions> } 
} 
Generating and Capturing Errors 
In a rule, we can also prevent the rule from failing 
when a microservice fails: 
errorcode(msi) 
The errormsg microservice captures the error 
message, allows further processing of the error 
message, and avoids the default logging of the error 
message, like so: 
errormsg(msi, *msg) 
In a rule, the fail() and failmsg() microservices can be 
used to generate errors. 
fail(errorcode) generates an error with an error code. 
Example: 
fail(-1) 
failmsg(<errorcode>, <errormsg>) generates an 
error with an error code and an error message. 
Example: 
failmsg(-1, "this is an error message") 
The msiExit microservice is similar to failmsg: 
msiExit("-1", "msi") 
Inductive Data Types 
The features discussed in this section are currently 
under development! 
An inductive data type is a data type for values that 
can be defined inductively, i.e. more complex values 
can be constructed from simpler values using 
constructors. General syntax: 
data <name> [ ( <type parameter 
list> ) ] = 
| : <data constructor type> 
… 
| <data constructor name> : <data 
constructor type> 
For example, a data type that represents the natural 
numbers can be defined as 
data nat = 
| zero : nat 
| succ : nat -> nat 
Here the type name defined is “nat.” The type 
parameter list is empty. If the type parameter list is 
empty, we may omit it. There are two data 
constructors. The first constructor “zero” has type 
“nat,” which means that “zero” is a nullary constructor 
of nat. We use “zero” to represent “0”. The second 
constructor “succ” has type “nat -> nat” which means 
that “succ” is unary constructor of nat. We use “succ” 
to represent the successor. With these two 
constructors we can represent all natural 
numbers: zero, succ(zero), succ(succ(zero)). 
Pattern matching 
If a data type has more than one data structure, then 
the "match" expression is useful: 
match <expr> with 
| <pattern> => <expr> 
… 
| <pattern> => <expr> 
For example, given the nat data type we defined 
earlier, we can define the following function using the 
match expression: 
add(*x, *y) = 
match *x with 
| zero => *y 
| succ(*z) => succ(add(*z, *y)) 
For another example, given the "tree" data type we 
defined earlier, we can define the following function 
size(*t) = 
match *t with 
| empty => 0 
| node(*v, *l, *r) => 1 + 
size(*l) + size(*r)

More Related Content

iRODS Rule Language Cheat Sheet

  • 1. IRODS Cheat Sheet (version 3+) Version 0.9 by Samuel Lampa, BILS (bils.se) Contact author: samuel dot lampa at bils dot se Numeric Literals 1 # integer 1.0 # double Strings 'A 'string', ' ++ "another ”string”" # Some valid escape characters: “n, r, t, , ', ", $, *" Boolean constants true # True false # False Boolean comparison ! # Not && # And || # Or %% # Or used in the "##" syntax Arithmetic operators - # Negation ^ # Power * # Multiplication / # Division % # Modulors - # Subtraction + # Addition Arithmetic comparison > # Greater than < # Less than >= # Greater than or equal <= # Less than or equal Arithmetic functions exp(<num>) log(<num>) abs(<num>) floor(<num>) # always returns integer ceiling(<num>) # always returns integer average(<num>, <num>, ...) max(<num>, <num>, ...) min(<num>, <num> , ...) String functions writeLine("stdout", "Hi!"); Prints out “Hi!.” "This “++”is”++” a string." Equals to “This is a string.” "This is a string." like "This is*" Equals to true "This is." like regex "Th.*is[.]" Equals to true substr("This is a string.", 0, 4) Output: This strlen("This is a string.") Output: 17 split("This is a string.", " ") Equals to: [This,is,a,string.] writeLine("stdout", triml("This is a string.", " ")); Equals to: is a string. trimr("This is a string.", " ") Equals to: This is a List functions list(<elem>, <elem>, ...) Creates a new list, Ex: list("This","is","a","list") elem(<list>, <index>) Retrieves elements from a list (0-indexed). Ex: elem(list("This","is","a","list"),0) # returns “This” setelem(<list>, <index>, <value>) Updates an item in a list. Ex: setelem(list("A","list"),0,"My") # Evaluates to list("My","list"). size(<list>) Gives the size of a list. Ex: size(list("This","is","a","list")) # evaluates to 4. hd(<list>) Gives the head of a list, Ex: hd(list("This","is","a","list")) # Evaluates to "This" tl(<list>) Gives the tail of a list. Ex: tl(list("This","is","a","list")) # Evaluates to list("is","a","list") cons(<element>, <list>) Add elements to a list. Ex: cons("My",list("list")) # Evaluates to list("My","list"). Tuples Tuples are created like so: ( <component>, ..., <component> ) If statements Logical if: if <expr> then { <actions> } else { <actions> } Logical if example: if (*A==1) then { true; } else { false; } Functional if (returning value of any type): if <expr> then <expr> else <expr> Functional if example: if true then 1 else 0 if *A==1 then true else false The following abbreviation are allowed (the red striked part can be abbreviated) in functional ifs: if (...) then { ... } else { ... } if (...) then { ... } else { if (...) then {...} else {...} } Multiple abbreviations can be combined for example: if (*X==1) { *A = "Mon"; } else if (*X==2) {*A = "Tue"; } else if (*X==3) {*A = "Wed"; } Foreach loops Without iterator: foreach(*C) { writeLine("stdout", *C); } With the iterator variable (*E in this case): foreach(*E in *C) { writeLine("stdout", *E); }
  • 2. Defining functions Functions can be thought of as microservices written in the rule language and are defined like this: <name>(<param>, ..., <param>) = <expr> Example: square(*n) = *n * *n Variables in functions: The let expression As function definitions are based on expressions rather than action sequences, we cannot put an assignment directly inside an expression. For example, the following is not a valid function definition: quad(*n) = *t = *n * *n; *t * *t To solve this problem, the let expression provides scoped values in an expression. The general syntax for the let expression is: let <assignment> in <expr> For example: quad(*n) = let *t = *n * *n in *t * *t The variable on the left hand side of the assignment in the let expression is a let-bound variable. The scope of such a variable is within the let expression. A let bound variable should not be reassigned inside the let expression. Defining Rules Define rules with nontrivial rule conditions like this: <name>(<param>, ..., <param>) { on(<condition>) { <actions> } } The rule condition can be skipped for rules with trivial or non-existent conditions: <name>(<param>, ..., <param>) { <actions> } A rule can have multiple conditional expressions: <name>(<param>, ..., <param>) { on(<condition>) { <actions> } … on(<condition>) { <actions> } } Generating and Capturing Errors In a rule, we can also prevent the rule from failing when a microservice fails: errorcode(msi) The errormsg microservice captures the error message, allows further processing of the error message, and avoids the default logging of the error message, like so: errormsg(msi, *msg) In a rule, the fail() and failmsg() microservices can be used to generate errors. fail(errorcode) generates an error with an error code. Example: fail(-1) failmsg(<errorcode>, <errormsg>) generates an error with an error code and an error message. Example: failmsg(-1, "this is an error message") The msiExit microservice is similar to failmsg: msiExit("-1", "msi") Inductive Data Types The features discussed in this section are currently under development! An inductive data type is a data type for values that can be defined inductively, i.e. more complex values can be constructed from simpler values using constructors. General syntax: data <name> [ ( <type parameter list> ) ] = | : <data constructor type> … | <data constructor name> : <data constructor type> For example, a data type that represents the natural numbers can be defined as data nat = | zero : nat | succ : nat -> nat Here the type name defined is “nat.” The type parameter list is empty. If the type parameter list is empty, we may omit it. There are two data constructors. The first constructor “zero” has type “nat,” which means that “zero” is a nullary constructor of nat. We use “zero” to represent “0”. The second constructor “succ” has type “nat -> nat” which means that “succ” is unary constructor of nat. We use “succ” to represent the successor. With these two constructors we can represent all natural numbers: zero, succ(zero), succ(succ(zero)). Pattern matching If a data type has more than one data structure, then the "match" expression is useful: match <expr> with | <pattern> => <expr> … | <pattern> => <expr> For example, given the nat data type we defined earlier, we can define the following function using the match expression: add(*x, *y) = match *x with | zero => *y | succ(*z) => succ(add(*z, *y)) For another example, given the "tree" data type we defined earlier, we can define the following function size(*t) = match *t with | empty => 0 | node(*v, *l, *r) => 1 + size(*l) + size(*r)