1. Mikołaj Baranowski
  2. cookery




Cookery is a framework for designing Domain Specific Languages for scientific applications. It is developed in Ruby programming language (requires Ruby 2.0).

How does it work

Cookery is inspired by cooking recipes and it allows to develop scientific applications with plain English. In order to develop an application, first an environment has to be established. It consist three kinds components:

  1. Action
  2. Condition
  3. Subject


Action is a pair: name and procedure. Name_ is a reference to created action and can be used in a place of action (see syntax). Procedure is a block of code that takes one argument - subject. During the execution, action receives a reference to a subject specified be a user.

Communication between actions is done using channels. They can be accessed using function channel_put(<channel_name>, <value>) and channel_get(<channel_name>) (available in action's blocks).


Condition is very similar to action. It has a name and procedure. They should have longer, descriptive names and be designed in a way that can cooperate with many actions.


Subject is built from four elements: name, regular expression, type and procedure.

  • name is a reference to a subject
  • regular expression is used to parse subject's arguments, all elements captured by a regular expression are available as arguments in a block
  • type (or protocol) points to an implementation of subject's backend, backend provides methods that can be used in a procedure to specify protocol's parameters (e.g. path)
  • procedure - block of Ruby code where all the parameters specific to a protocol can be specified using functions provided by a protocol implementation


These components define named entities - keywords that can be used in a following syntax:

Action subject (context) - condition condition ... condition.

Then, during the execution, framework passes subject with arguments specified by a user ((context)) and references to conditions.


In a following example we show an application that counts words in a compressed text file. (file file-operations.rb in a repository).

Setting up environment

First, all the required components have to be defined, a subject:

subject(:file, /(.+)/, :file) do |f|
  path f

Action that puts content of a file to a channel (specified by a subject)

action(:read) do |subject|
  puts "in action"

  channel_put(:foo, subject)

Condition that decompresses a string

condition("with zip compression") do |data|
  puts "in condition"
  gz = Zlib::GzipReader.new(StringIO.new(data))
  result = gz.read

Example, empty condition:

condition("with nothing") do |data|

Action print_result prints result to standard output

action(:print_result) do
  puts "RESULT: #{channel_get(:bar)}"

Action count_words counts word in string.

action(:count_words) do |subject, conditions|
  channel_put(:bar, channel_get(:foo).split.length)


In a following code we use available components from a previous paragraph to construct a full application.

Read file /tmp/test_data.gzip - with zip compression, with nothing.
Count words.
Print result.