This is a list of features, organized however, and loosely maintained.

Core Language

  • The syntax is loosely based on python, though it uses "semi-colons"
  • Assignment, and basic operators are supported (+, -, *, /).
  • Functions can be called.
  • Variables can be assigned and used as you would expect in expressions.
    • If you put {varname} in the middle of a string expression it will be replaced with the variable value
  • Methods on objects can be called. If the object is a .NET object, the interpreter will attempt to do method resolution directly on the .NET methods.
    • There is a special case if a method is followed by code in between curly braced (" and "), then the code gets passed as a further argument. This allows for flow control.
    • If the method name is a .NET property name on a .NET object, and there is no method by the same name, then calling it obj.Prop() will return the value of the property, and obj.Prop("hi") will set the value of the property and return the object.
  • Basic values:
    • Integers and doubles
    • Quoted strings
    • Arrays, which are denoted by "" and "": [], 1, 1, 2, "hi" - they can have mixed types.
      • The sum function can be applied, and it will try to add all the values in an array up (as long as it is possible!).
      • you can divide an array by a single object, as long as there is a way to divide each object in the array by that object.
    • Dictionaries, which are written in brackets: {} and a comma separated list of key,value pairs.
      • The ":" and "=>" can be used interchangeably. The following are the same dictionary, that contains a single item: "{1 => 2}", "{1 : 2}", "1 => 2", "1 : 2". The last two are ways of declaring a dictionary with a single item in them.
      • If the key is a simple string that doesn't start with a number, it does not need to be quoted: {"Color" => 1} and {Color => 1} are the same dictionary.
      • The sum() method will add all the values in the dictionary together to make one value (sum a list of numbers, etc.).
      • Operators: d1+d2, d1/d2, c1*d2, where d is a dictionary and c is a constant. These aren't matricies: this is an element-by-element operation.
  • Operators:
    • +, -, *, / defined on integers and doubles
  • Flow Control
    • for (dict) { statements;}; For loop, with a list of dictionaries containing the variables to be set in the loop.
    • r = map(dict) {statements;}; Just like the for loop, only save the last result of the statements in the for loop as a list. Basically a transform.
    • r = map("v", l1, l2, l3) { statements; } - Loop over each statement, setting the variable "v" to l1, l2, and l3 in turn. The result is the result of the last set of statements. This may change to remove the quotes around the "v" in the future.
    • r = map(array,varname){statements;}; - loop over each value of the array, setting varname to that value when executing statements. The last result of statements is returned. This is basically an array transform.


These features are really only available to people using C#. They help with the core of the system.
  • Any function can be declared to the language by creating a static function, decorating the class it is declared in with the Export(IFunction) tag from MEF. Argument resolution is done using the full .NET type system.
  • If a function call can't be found, a secret argument, the Context is prepended to the argument list and the search for a matching function is repeated. This Context object gives access to inner workings and hooks.
  • Any extension method can be declared for an object in the same way as a function. The first argument, in that case, must be the object type it will be called against.
  • One can use MEF to declare new search strategies for finding methods.
  • One can add a post-method or function call hook. Each time a method of a particular name is called, a use supplied function can be called with the result of the first function call. The user function can do whatever it wants, including replacing the returning object for something completely new.
  • It is possible to be called with the result of every single expression statement. These are statements that evaluate a value, but never return that value to anything useful.
  • Operator overloading is done by defining a method called OperatorPlus, OperatorMinus, OperatorMultiply, or OperatorDivide. ab = ba and ab = ba are built into the language.


  • All plotting is run through the plot() method.
  • You can add pre-plot hooks that can process the plots that are about to be drawn.
  • Several methods, like TurnOffStatBoxes use these hooks plus the post-function hooks to add code that turns off stat boxes (for example).
    • TurnOffStatBoxes - if more than two plots are being plotted, then don't have stat boxes
    • NormalizePlots - make sure the plots will all fit and no-one will have areas off-plot because the Maximum isn't set correctly.
    • ConfigureLineWidth - set the default line width of all plots
    • title - sets the title of the plot
    • xaxis, yaxis - sets the x and y axis titles
  • Legend's can be created by calling the Legend function with a dictionary as an argument. It is possible to call it repeatedly. It must be called at least once before plot().
    • The dictionary's key is a search string that is looked for in the title of a histogram.
    • The dictionary's value can be either an integer, or a another dictionary that contains a "Color" key and perhaps a "Title" key.
  • The variable plotformats is a string array, with a list of file extensions that ROOT's graphics engine knows. For example, by default it is set to be "png". If you wanted both png and pdf outputs, you might do "png", "pdf". Set it anywhere in your script!

ROOT Objects

  • Methods in ROOT are automatically supported - ROOT's meta-data system is used (via ROOT.NET).
  • Some special operations are defined on TH1's:
    • h1 + h2, h1/h2

Accessing ROOT files

  • Local files are supported. Supply the full path. Use the function file with a single argument as the path to access.
  • You can access a root file from the most recent teamcity server build. Use the function teamcity with the URL of the file as an argument. The system will automatically fetch the most recent file from that build sequence. It will only download a file that hasn't been downloaded already. Use the built-in network credential manager if you need password access.

Shell Program

  • Monitors the input file for changes. Each time it see the files saved or written to, it will re-run the script, automatically updating the plot.
  • A defaults.plotlingo file, located in the same directory as the executable, is loaded, first, each time the program is run. Contains useful pretty-printing defaults.

Last edited Dec 4, 2014 at 12:44 PM by gwatts, version 20