Karajan:Channels - Portable functional abstractions

From Java CoG Kit

Jump to: navigation, search

Channels allow processing of individual aspects of the results of the execution of an element. Let's assume the following scenario:

A test case generates three possible results: 0 (Success), 1 (Failure), 2 (Timeout). An element/function exists which translates the numeric result into a string:

  • 0 → "Success"
  • 1 → "Failure"
  • 2 → "Timeout"

The element is called name. It would be used like this:

name(test())

Now assume that the test is augmented with the ability to also return a time that measures how much time the test took (or any other metric about the test). It is now necessary to modify every occurence of the above piece of code into:

set([code, time], test())
name(code), time

In simple cases this is not a problem, but in more complex cases it can become quite cumbersome to separate data, apply specific transformations on it, and combine it again. In Karajan data can be returned on different channels. For example, in the above case, the time could be returned on a time channel (by test). Since elements that do not explicitly process data on a channel are transparent to it, the usage would be:

name(test())

In other words, there is no need to explicitly isolate the code value from the time value, apply the name transformation to the code value and return the result and the time value. Name would process what it knows how to process, and will transparently return the time along with the status string.

This is also the basic mechanism through which printing on the console works in Karajan. Instead of print employing a side-effect to produce output on the console, it merely returns its arguments on the stdout channel (eventually appending a new line character).

print("Hello world!", nl = false)

does exactly the same thing as

to(stdout, "Hello world!")

The element sitting at the root of the element tree asynchronously receives all data on the stdout channel and prints it on the console. It thus becomes easy to, for example, intercept or suppress the output of certain parts of a program:

element(noOutput, [channel(stdout)] //receive data on the stdout channel
  //and do nothing with it
)

noOutput(print("Hello world!"))

In a similar way, the HTML Library uses the html channel to send all HTML data. This allows HTML elements to be transparently mixed with code that does other processing:

write(file = "hello.html"
  html(
    head(title("Hello world!"))
    body(
      print("Here it goes...")
      to(html, "<h1>Hello world</h1>")
    )
  )
)
Personal tools
Collaboration and Jobs