Action code
'Action code' is the overall name given to the use of actions, e.g. in automating Tinderbox, and to syntax rules defining valid actions. In use an 'action' may comprise one or more discrete actions, each one delimited by a semi-colon.
An expression in Action code
An 'expression' used in Action code is a combination of data and operators that tells Tinderbox how to compute a value. It is a way of calculating something or deriving a value based on existing information.
Generally an expression can be evaluated to give a value.
Scope of expressions vs. actions
These examples show the relative scope of an expression vs. an action
- An expression:
5+2;
- An action:
$Width=5+2;
Note the difference. Whilst the expression generates a result, an action does something with the value. The implications of that are explored below.
Using expressions in Action code
Expressions are used within Tinderbox to define values, conditions, or other computations.
5 + 2
2 * ($MyNumber + 3)
$Height(parent) * 1.5
($Overdue |$ Essential)
$Width(/$Configuration) + 1) * $Scale
The result of an evaluation any of these, returns a value that can be used in current action code. At its simplest, even a literal string of text "Hello world"
as it evaluates as the text value 'Hello world'.
An action in Action code
An 'action' in Tinderbox is a piece of code that performs a task. Actions are commands that tell Tinderbox to do something, such as setting the value of an attribute, changing the colour of a note, or creating links between notes. Here are the expressions above as complete actions.
$MyNumber = 5 + 2;
$MyNumber = 2 * ($MyNumber + 3);
$MyNumber = $Height(parent) * 1.5;
$myDate = ($Overdue | $Essential);
$Width(/$Configuration)+1)*$Scale;
$MyString = "Hello world";
More detail is given on the nuances of action code and expression in th the section below 'Actions and Expressions in more detail'.
Choosing between eval() vs. action() operator use within actions
In general use of action code it may not be possible to explicitly state or reference all values as they may be being created by the current code. Tinderbox thus offers two operators to assist with this challenge: eval() and action().
eval(). Whilst most action operators evaluate their argument/inputs, complex expressions may need to the evaluated into a single value before they are usable via the calling operator. This is where eval() can be useful, in ensuring a value (rather than expression code) is passed to the next part of the code. Thus the point of eval() is to generate a value.
action(). In contrast, there are occasions where the need it to run an action where part of the code need to be generated on the fly. For instance, having a list of attribute names but wishing to iterate the list and generate $-references to each attribute and assign it a value. Here is where action() is useful, but note that the code used must evaluate to a complete action().
Although action() post-dates eval() as an operator by some years, and some old code examples may use eval() because that was all that was available at he time. Indeed, if trying to choose between the two, it is more likely the action() is the correct—or more easily used—choice, albeit each requiring a slightly different argument.
A key point re use of action() is the it must contain the code text of a complete action—or code text plus variables that evaluate to such.
In basic form, and assuming variable vText
holds the string 'ReferenceTitle' and the value of $ReferenceTitle is 'Now We Are Six', the following might seem be the same:
$Text = eval("$" + vText);
→ sets 'Now We Are Six'
action($Text = "$" + vText);
→ fails
when in fact the necessary syntax for the latter is
action("$Text = $" + vText);
→ sets 'Now We Are Six'
Why the difference? In the eval() case, '$'+vText' is literally '$'+'ReferenceTitle', and the eval returns the value of $ReferenceTitle. For the action() example, the evaluation occurs in two stages: first the value of vText is retrieved and then the overall string is executed as an action.
If eval() fails where it feels it ought to work (i.e. there are no input errors, just a fail in context), using action() instead will likely work. But note that when swapping between eval() and action() use the argument needs to be altered to use an expression (for eval()) vs. an an action (for action()).
Actions and expressions in more detail
Normally, actions and stamps require an action: an assignment, or an if(), each(), or var() statement.
Note than a stored action, e.g. a Stamp or Rule may comprise more than one action, is which case they are stored with a semi-colon after each action to enable the action code parser to detect each individual action in turn. The first action is completed before the next one is run, etc. These are both actions, they simply vary in the number of actions they contain:
- A single action:
$MyString = "Hello world";
- A multiple action:
$MyNumber = 4 * 2; $MyString = "Hello";
White space or line breaks between multiple actions are ignored by the parser. Thus in practice, multiple actions are often written with each action on a separate line of code for the clarity to the human reader/user of the code.
However, actions may be expression-like, in having no overt assignment which are evaluated for their side-effects. For example, "frogs".speak()
is technically an expression, not an action, but if run (evaluated) in an action, the macOS will say the word "frogs".
Most often, actions tend use simple arithmetic and logical expressions that are then passed to a left-side assignment. Operators in action code evaluate the arguments passed to them. Thus:
$Text = capitalize("hello world");
fetches the argument, here a literal string—which evaluates as itself—before capitalising it. Or, if we encode:
capitalize("hello" + " " + "world");
the capitalize() operator first assembled the expression in the argument (i.e. to make 'hello world') before returning the capitalised version of the string. If $MyString contains "hello world", then:
$Text = capitalize($MyString);
evaluates $MyString, capitalises that value and returns the result to $Text. Most action operator arguments are evaluated: cases where this is not so are generally explicitly documented.
Dot operators use the output of the operator to which they are chained. If addition evaluation is needed, i.e. a previous output needs to be crystallised into a value before further use, the preceding operators can be placed in parentheses and the next dot operator chained to the closing parenthesis.
Note the latter examples above the right-side involves more complex evaluation where extra parentheses are added to make explicit the evaluation order, as discussed further here.
Single action, e.g. a rule, can have multiple expressions:
$Color= "blue";$Badge="ok";
Multiple expressions must be delimited by semi-colons. Line breaks between expressions are optional. They may aid legibility of code but have no effect on how the code is parsed.
Because Tinderbox recognises operators such as + and -, notes whose names begin with characters other than letters and numbers may sometimes be interpreted in unexpected ways. For example, if a note is named "6*7", rules like
$Prototype=6*7;
…might be parsed as a multiplication with the result of 42.
$Prototype="6*7";
…should have the expected effect. Quoting characters will always cause Tinderbox to treat such content as literal text.
Actions and rules may use computation with data attributes, including attribute values from other notes. For example:
$DueDate=date($DueDate(parent)+"7 days");
$DueDate=date($ExpiryDate(parent)-"10 days");
Date attribute values can also be computed with literal dates and date designators:
$DueDate=date("November 15, 2004"+"7 weeks");
This older style is deprecated (but works) as it is introduces scope for ambiguity in the evaluation of the code and the user's intent:
$DueDate="November 15, 2004"+"7 weeks"
Not recommended!
In the previous examples note that the actual and partial date strings use quotes.
Expressions in attributes
To understand the role of expressions stored as attribute values, see Expression-storing attributes.
Additional information
See further discussion of expressions:
See also—notes linking to here: