Extension:StackFunctions

Abstract
The StackFunctions extension implements a programming language which is basically PostScript without graphics.

Motivation
This extension can be considered as an alternative to the combination of ParserFunctions with StringFunctions (and maybe other extensions) or to Winter. Advantages are:
 * When using conditional expressions with ParserFunctions or Winter, wikitext in the false-branch is parsed before evaluating the condition. If that text contains complex templates, such superfluous parsing may take much time. With StackFunctions, wikitext is parsed only if needed for the output.
 * To execute loops, you would need either inefficient auxiliary templates with a limited number of runs or LoopFunctions which also have limits. StackFunctions is able to execute loops with any number of iterations and any depth of nesting in a relatively efficient way.
 * If you have text which on the one hand you'd like to display between ..  and on the other hand to use as an argument to ParserFunctions, you need to build more or less complex structures using ExpandAfter. StackFunctions can handle this in a much easier way.
 * StackFunctions offer a Turing-complete programming language which can be used to implement any algorithm (with more or less effort in a more or less efficient fashion) without need for additional extensions.
 * StackFunctions easily handle complex data structures like arrays and dictionaries, which may also be nested to any level.
 * My personal experience is that StackFunctions generally tend to execute faster than a combination of other existing extensions, especially when the latter solution would need a large number of auxiliary templates which are evaluated many times.

Installation

 * See Extension:StackFunctions/Install when you install StackFunctions for the first time.


 * See Extension:StackFunctions/Upgrade when you upgrade and existing StackFunctions installation.


 * See Extension:StackFunctions/Parameters for a complete list of parameters you might choose to customize in your LocalSettings.php.

Usage
Preliminary Remark: programming with a stack processor like this is a matter of taste. You might alternatively find it extremely cool or totally unusable. You have been warned.

Syntax
You can use this extension either as a parser extension or as a parser function extension.

Parser Extension
As a parser extension, the syntax is:

 your_stackfunctions_code 

This syntax is usually the preferrable one because:


 * You don't have to bother with the problems listed below for the parser function syntax.
 * From theory it is likely that this executes faster than the parser function syntax because the code is not parsed before passing it to StackFunctions. (However, I didn't yet write so much code that I can confirm this from observation.)

If you want to evaluate magic words, templates or parser functions, you can do this within the code via the statusdict and parsetemplate/showtemplate operators.

The only things that cannot be done with this syntax are:
 * Usage of template parameters , , ...  in StackFunctions code in a template.
 * Using the output of StackFunctions code as a template parameter of parser function parameter.
 * Print section headings. They will be printed, but won't be counted correctly for the TOC.

Parser Function Extension
As a parser function extension, the syntax is:

When using this syntax, you must pay attention to some issues. The basic rule is that any   structures are parsed by the MediaWiki parser before any StackFunctions code is executed. There is a number of consequences:


 * Take care not to have any   in your code. If you have consecutive braces, put a space in between.


 * You cannot use a literal | character inside   because the parser would interpret it as a separator for an additional parameter passed to #sf:. Within a string constant, you can write its octal representation \174 instead.


 * If you put a template, magic constant or parser function in a string literal, it will first be evaluated and then the result passed to the StackFunctions code. Use parsetemplate/showtemplate if you want to evaluate it only while executing the StackFunctions code. In particular, you should do so within conditional branches so that the parser spends time only on those templates which are actually needed.


 * When using html tags within string literals, take into account that the MediaWiki parser will interpret them before invoking StackFunctions which is probably not what you want. Use \074, \076</tt> instead of &lt;, &gt;</tt> to avoid this.

Important Note
Code in the two syntax forms is executed at different times. In the 1.9.2 MediaWiki parser, first all code in the xml-like syntax is executed, then all code in the function syntax. This implies that, for instance, an object put on the stack by code in function syntax will never be seen by code in xml-like syntax. As this behaviour depends on the internal realization of MediaWiki, you should not trust it remains the same in the future. Therefore I strongly discourage mixing the two syntaxes on the same page (including all templates used on it) if the pieces of code should see each other's activity (leaving objects on the stack, opening dictionaries etc.)

Writing Code
StackFunctions are basically an implementation of PostScript without graphical operators, with a few modifications and with some MediaWiki-specific extensions. I'm not going to explain PostScript here; you might refer to the following sources about PostScript:


 * The PostScript Wikipedia article for a very basic introduction.


 * The PostScript Language Tutorial and Cookbook for a good tutorial.


 * The PostScript Language Reference, third edition for a complete reference.

Extension:StackFunctions/Reference explains all differences from PostScript, including additional operators and features. Whatever is not mentioned there should work just as in PostScript.

Have a look at Extension:StackFunctions/Internals if you'd like to learn more about the way StackFunctions internally works.