Hello World

In this first tutorial we will create a very simple workflow in cuneiform, consisting of one task with a bash body. In cuneiform tasks are either written in cuneiform or in a foreign scripting language, including Lisp, Matlab, Octave, Perl, Python, and R.
Let's start with the simplest query we can build:

'Hello World';

If you've done everything right, cuneiform will start the query and shortly after that respond that the query finished with the output

Hello World
That wasn't very exciting, so let's take it one step further and place the string in a variable:

output = "Hello World";
output;

The second line,

output;
will start a query with the goal to compute the value of the variable 'output'. As stated just one line before that, it has the string value "Hello World".
Instead of just assigning the value and asking for it later, which wouldn't be of much use, we can define tasks to work with different input and generate a matching output.

deftask hello( out : input ) {
    out = input;
}

hello(input: "Hello World");

The keyword

deftask
starts the definition of a new task block, followed by the name of the task, the input and output parameters and the task body. The task above is written in Cuneiform, though Cuneiform allows bodies of different languages as you will see later on.
Instead of querying the task with the given input, we could save it's output in a variable:

deftask hello( out : input ) {
    out = input;
}

output = hello(input: "Hello World");
output;

It's true that this example is not very exciting because nothing really happens - we just defined a task that gives us whatever we used as input back as output, an identity function. But be assured that we can do much more than this, it's just an early example. Now that we have done all this, it is time to define a task in a language different from Cuneiform - Bash.
Let's have a look at the code first and explain afterwards:

deftask greet( out : person ) in bash *{
	out="Hello $person";
}*

greet(person: 'Alice');

We are doing two things here: One is the definition of the task 'greet' in Bash, which uses an input parameter called 'person' and an output parameter 'out'. The body is a simple bash statement, where we bind the string "Hello $person" to the output variable. The $-character indicates, that the following word is a variable and will be replaced with the current value by Cuneiform before the task is run.
This means $person will be replaced by the string value "Alice" of the input variable when the task is applied, the output will be a string type.
Standing alone, the task isn't of much use to us, we need to bind it by applying a value to the input parameter. this is done by saying

greet(person: 'Alice');
The task will now be called with value 'World' for person, resulting in an output string "Hello Alice" for the task. Change the value of the input parameter to greet another person! As we have seen before, instead of directly binding the string value to the input "person", we could also define a variable with the value and assign that variable to the input parameter.
Of course you are not limited to a single input parameter. The following task, as simple variation of the hello task defined above, uses two inputs to compute a single output:

deftask greet( out : personA personB ) in bash *{
	out="Hello $personA and $personB";
}*

greet(personA: 'Alice' personB: 'Bob');

As last part of this tutorial, let's combine what we have learned into one workflow:

deftask hello( out : input ) {
    out = input;
}

deftask greet( out : word person ) in bash *{
	out="$word $person";
}*

hi = hello(input: "Hi there");
result = greet(person: 'Alice' word: hi);
result;