Expressions are used in Knackly for formulas and logic. The concept of expressions was introduced at the end of the Knackly Bootcamp guide; please refer to the guide for a basic definition and explanation of expressions. Expressions use operators in order to produce results.
Operators:
An "operator" is a symbol that has a special meaning in expressions (i.e., "+", "", "==", and "<" are all operators). Operators instruct Knackly to act upon the variables in an expression in specific ways. For instance, if you wanted to add two number variables together, or wanted to create a text string that fills with different information depending on the answer to a selection variable, you would use operators in an expression to produce the correct result.
When discussing operators and expressions, we usually refer to the variables (what the operator is acting upon) as operands, and the action the expression performs as an operation. The operation (and therefore the result) depends upon which operators you use.
Each operator and its affiliated operation produce some kind of value. When an operation is performed, we refer to that as evaluating the expression – i.e., when Knackly goes through the expression and evaluates it, it produces a value.
There are three basic kinds of operators – unary, binary, and other.
Unary operators perform an operation on one single operand. These operators include the not operator ("!") and the unary minus operator (""). These will be described in further detail below. Unary operators are all prefix operators – the operator is used in front of its operand (i.e., !TFVar determines whether TFVar evaluates negatively).
Binary operators perform operations on two operands, which are frequently referred to by their position with respect to the operator (i.e., a left operand and a right operand). For example, in the expression NumVar1 + NumVar2, NumVar1 is the left operand, + is the operator, and NumVar2 is the right operand.
Other operators do not fit within the unary/binary definitions above, but will be covered in specifics below, along with explanations and examples of the most common operators in Knackly.
Mathematical Operators:
Mathematical operators are used to perform mathematical functions on number variables, or in the case of the Addition operator, can also be used to add strings of text together.
Addition
The addition operator is the plus sign ("x"). This binary operator adds numbers together in a number formula or can combine pieces of text. The operands for this operator are the two numbers being added.
Example 1: NumVar1 + NumVar2 will result in the sum of the two number variables.
Example 2: NameVar + " is the Borrower" will result in "[NameVar] is the Borrower".
Subtraction
The subtraction operator is the minus sign ("") or ndash. This binary operator subtracts one number from another in a number formula. Be careful when using the minus sign in docx templates – often Word is set to autocorrect the ndash to an mdash ("—"), which will not be recognized by Knackly and produce an error when the template is uploaded. The operands for this operator are the left hand number and the right hand number being subtracted from it.
Example 1: NumVar1  NumVar2 will result in the difference between the two number variables.
Multiplication
The multiplication operator is the asterisk ("*"). This binary operator will multiply two number variables together. The operands for this operator are the two numbers being multiplied.
Example 1: NumVar1 * NumVar2 will result in the product of multiplying the two number variables.
Division
The division operator is the forward slash ("/"). This binary operator will divide two number variables. The operands for this operator are the left number and the right number being divided into it.
Example 1: NumVar1 / NumVar2 will result in the quotient of dividing NumVar1 by NumVar2.
Modulus
The modulus operator is the percent sign ("%"). This binary operator will give the remainder of a division operation. The operands for this operator are the left number and the right number being divided into it to create the remainder.
Example 1: NumVar1 % NumVar2 will give the remainder of NumVar1 divided by NumVar2.
Unary minus
The unary minus operator is a minus sign ("") in front of any number variable. This unary operator will toggle the mathematical sign (positive or negative) of the number variable it is applied to. Like with the subtraction operator above, be careful that your ndash isn't turned into an mdash by Word's auto formatting. The operand for this operator is the number being toggled.
Example 1: NumVar will toggle the mathematical sign (positive/negative) of the number variable.
There is a unary plus operator, but it does not have a purpose in Knackly.
Comparison Operators:
Comparison operators are used to compare variables or answers to determine whether the comparison is true or not. These operators are used most often in numeric comparisons and in evaluating the answer of a selection variable.
Equal
The equal operator is two equals signs together, without a space ("=="). This binary operator will evaluate whether the variables on either side of it are equal, or evaluate whether a selection variable has a specific answer. The operands for this operator are the numbers being evaluated, or the selection variable and the option it is being evaluated against.
Example 1: NumVar1 == NumVar 2 will evaluate whether the two number variables are the same.
Example 2: SelectVar == "Option1" will evaluate whether the selection variable has Option1 selected as its answer.
Not Equal
The not equal operator is an exclamation point in front of an equals sign ("!="). This binary operator will evaluate whether the variables on either side of it are unequal. The operands for this operator are the number variables being evaluated.
Example 1: NumVar1 != NumVar2 will evaluate whether the two number variables are unequal.
Example 2: SelectVar != "Option1" will evaluate whether the selection variable does not have Option1 selected as its answer.
Greater Than and Greater Than or Equal To
The greater than operator is the greater than sign (">"). The greater than or equal to operator is the greater than sign in front of an equals sign (">="). These binary operators evaluate whether the left side number variable is a larger number than the right side number variable (for greater than), or whether the left number variable is a number equal to or larger than the right side number variable (for greater than or equal to). The operands for this operator are the number variables being evaluated.
Example 1: NumVar1 > NumVar2 will determine whether NumVar1 is a larger number than NumVar2.
Example 2: NumVar1 >= NumVar2 will determine whether NumVar1 is a number larger than or equal to NumVar2.
Less Than and Less Than or Equal To
The less than operator is the less than sign ("<"). The less than or equal to operator is the less than sign in front of an equals sign ("<="). These binary operators evaluate whether the left side number variable is a smaller number than the right side number variable (for less than), or whether the left number variable is a number equal to or smaller than the right side number variable (for less than or equal to). The operands for this operator are number variables being evaluated.
Example 1: NumVar1 < NumVar2 will determine whether NumVar1 is a smaller number than NumVar2.
Example 2: NumVar1 <= NumVar2 will determine whether NumVar1 is a number smaller than or equal to NumVar2.
Logical Operators:
Logical operators are used to connect and evaluate strings of operators. For instance, if you need to determine whether a selection variable is a certain answer AND a true/false variable is true, you would use a logical operator.
And
The and operator is two ampersands ("&&"). This binary operator will determine whether both pieces logic on either side of it is true and will give a true value only if both pieces of logic are true. The operands for this operator are the logical expressions on either side of it.
Example 1: TFVar && SelectionVar == "Option1" will determine whether the true/false variable is true and whether the selection variable has "Option1" as its answer. This expression will only return a "true" result if both pieces of it are true.
Example 2: MarriedTF && Client.Last == Spouse.Last will determine whether the true/false variable is true, and then whether Client and Spouse have the same last name.
Or
The or operator is two pipes or vertical bars (""). This binary operator will determine whether either piece of logic on either side of it is true and will give a true value if either evaluates to true. The operands for this operator are the logical expressions on either side of it.
Example 1: NumVar1 > NumVar2  NumVar1 > 2 will determine whether NumVar1 is a larger number than NumVar2 and determine whether NumVar2 is a larger number than 2. If either piece of logic is true, the expression will return a "true" result.
Example 2: SelectionVar == "Option1"  SelectionVar == "Option2" will evaluate the answer to the selection variable and return a true result if the selection variable's answer is either Option1 or Option2 (but not any other option).
Other Operators:
Knackly uses several other important operators in expressions that do not fit into the categories above.
Ternary Operator
The ternary operator is a question mark ("?") followed by a colon (":"). This tertiary operator functions as an "else" or a conditional operator for expressions. For example, if you need to have one result in a particular circumstance, and a different result if that circumstance is not present, you would use the ternary operator. This operator requires three operands – the operand before the question mark (the one being evaluated), and the operands before and after the colon (the resulting values produced depending on the evaluation of the first operand).
Example 1: TFVar ? "Text A" : "Text B" will determine whether the true/false variable is true. If the true/false variable is true, it will result in Text A. Otherwise (else), it will return Text B.
Example 2: SelectionVar == "Option1" ? Client.FullName : Client.FirstName will determine whether the selection variable's answer is Option1. If it is Option1, the expression will result in Client.FullName. If the selection variable's answer is not Option1, then the expression will result in Client.FirstName.
Vertical Bar
The vertical bar is one pipe or vertical bar (""). This binary operator is used for formatting or filtering other variables or lists in Knackly. The operands for this operator are the variable before the bar (the variable being filtered or formatted) and the expression after the bar (the filter or format being applied).
Example 1: ListVarfilter: ListTF will bring in only the list items where the true/false variable on the list is true.
Example 2: DateVarformat: "MMMM D, YYYY" will format the date variable as Month Day, Year (i.e., January 1, 2001).
Grouping Operator
The grouping operator is a pair of parentheses ("( )"). This operator is also just referred to as parentheses or parentheticals. This operator will explicitly force Knackly to evaluate whatever is inside it before evaluating any other operators. This operator does not require a certain number of operands, but instead acts upon whatever is put between the parentheses.
Example 1: NumVar1 * (NumVar2 + NumVar3) will add NumVar2 and NumVar3 before multiplying their result by NumVar1. Without the parentheses, NumVar1 and NumVar2 would be multiplied before NumVar3 is added to their result. (i.e., 5 * (1 + 2) will result in 15, whereas 5 * 1 + 2 will result in 7).
Index Operator
The index operator is a pair of square brackets ("[ ]"). This binary operator will extract a single indexed value from a list. The index operator is always zerobased; the first item in a list is 0, the second item is 1, and so on. The operands for this operator are the list variable and the index number.
Example 1: ListVar[0] will produce the first item of the list variable.
Example 2: ListVar[2].ListTextVar will produce the text variable that is on the second item in the list.
Not
The not operator is an exclamation point ("!"). This unary operator determines whether the operand following it is true. The operand for this operator is the expression or variable immediately following the exclamation point.
Example 1: !TFVar will evaluate whether the true/false variable untrue.
Example 2: !(NumVar 1 + NumVar2 = NumVar3) will evaluate whether the expression inside the parentheses is untrue.
Period
The period operator is a period (".") This operator is used to identify or specify a particular part of a greater whole. The operands for this operator are the variable period (the greater whole you are specifying a part of) and the variable after the period (the part you want to specify).
Example 1: ObjectVar.TextVar will result in the text variable that is on the object variable.
Identifying
The identifying property is the letters i and d followed by a dollar sign ("id$"). This is not technically an operator, but is mostly used in formulas and expressions. The identifying property does not have operands.
The identifying property is a background property assigned to each variable in Knackly, no matter what model that variable is on. This property is used in comparing various items to determine whether they match or are the same.
For example, if you have a selection variable called Fiduciary, which is filled from all your partymodel based variables, you could use id$ to check whether the selected Fiduciary was also the Client partymodel variable by using the expression Fiduciary.id$ == Client.id$. This is useful if you need different language in certain places if specific parties are selected in specific roles.
Another way the identifying property is used is in the object model itself. For instance, if you have a party object model and you only want some variables asked if the object model is the Client object variable, you would use the expression id$ == Client.id$. This checks whether the object currently being used is the Client object variable (id$ identifies the current object model, while Client.id$ identifies the Client object variable based on the current object model. If they are the same, then the variable is asked).
Order of Operations:
Precedence  Operators  Examples 
1  Parentheses: "( )"  (Var1 + Var2)
If (NumVar1 + NumVar2) * NumVar3, NumVar1 and NumVar2 will be added together before their result is multiplied by NumVar3

2  Member: ".", "[ ]"  Client.FullName ListVar.[1]
example? If ListVar[1].NumVar1 + NumVar2, the NumVar1 from the second item of the list will be evaluated before it is added to NumVar2.

3  Not: "!"  !TFVar
If !TFVar && NumVar1 * NumVar2, !TFVar will be evaluated before NumVar1 and NumVar2 are multiplied.

4  Math tier one: "*", "/", "%"  NumVar1 * NumVar2 NumVar1 / NumVar2 NumVar1 % NumVar2
If NumVar1 + NumVar2 * NumVar3, NumVar2 and NumVar3 will be multiplied before NumVar1 is added to the result.
If NumVar1 + NumVar2 % NumVar3, the remainder of NumVar2 and NumVar3 will be evaluated before NumVar1 is added to the result.

5  Math tier two: "+", ""  NumVar1 + NumVar2 NumVar1  NumVar2
If NumVar1 + NumVar2 > NumVar3, NumVar1 and NumVar2 will be added together before the result is compared to NumVar3.

6  Equivalents: "<", "<=", ">", ">="  NumVar1 < NumVar2 NumVar1 <= NumVar2 NumVar1 > NumVar2 NumVar1 >= NumVar2
If NumVar1 < NumVar2 == NumVar3, NumVar1 and NumVar2 will be compared before determining whether the result is equal to NumVar3.

7  Equalities: "==", "!="  NumVar1 == NumVar2 SelectionVar == "Option1" NumVar1 != NumVar2 SelectionVar != "Option1"
If NumVar1 == NumVar2  TFVar, whether NumVar1 is equal to NumVar2 will be evaluated before TFVar.
If SelectionVar != "Option1"  TFVar, whether SelectionVar's answer is not Option1 will be evaluated before TFVar.

8  And: "&&"  TFVar1 && TFVar2 TFVar1 && SelectionVar == "Option1"
If TFVar1 && TFVar1  TFVar3, whether TFVar1 and TFVar2 are true will be evaluated before TFVar3.
If TFVar1 && SelectionVar == "Option1"  TFVar3, whether both TFVar1 is true and SelectionVar is answered with Option1 is true will be evaluated before TFVar3.

9  Or: ""  TFVar1  TFVar2 TFVar1  SelectionVar == "Option1"
If TFVar1  TFVar2, TFVar1 will be evaluated before TFVar2.
If TFVar1  SelectionVar == "Option1", TFVar1 will be evaluated before determining whether SelectionVar has Option1 as its answer.

10  Ternary: "? :"  TFVar1 ? TextVar1 : TextVar2
If TFVar1 ? NumVar1 + NumVar2 : NumVar3, then NumVar1 and NumVar2 will be added together before TFVar1 is evaluated.

11  Pipe: ""  ListVarfilter: TFListVar1
If TFVar1 ? ListVarfilter: TFListVar1 : TextVar2, TFVar1 will be evaluated before ListVar will be filtered for TFListVar1.

Formula Examples and Explanations:
Note: If you're in a formula, you can break your expressions across multiple lines for readability.
Situation: Create a formula to automatically produce the correct salutation for letters to estate planning clients – who may be a married couple or may be a single client. If the client is a married couple with the same last name, the salutation should be "Mr. and Mrs. LastName", whereas if clients have different last names, it should be "Mr. LastName and Mrs. LastNameHyphenName".
The formula for this situation would be a text formula and would look like this:
Married
? Spouse.Last == Client.Last
? Client.Prefix + " and " + Spouse.Prefix + " "+ Client.Last
: Client.Prefix + " " + Client.Last + " and " + Spouse.Prefix + " " + Spouse.Last
: Client.Prefix + " " + Client.Last
First the formula determines if the parties are married. If so, it determines whether the parties have the same last name, and produces the correct result depending on those factors.
Situation: Create an expression to be used in the label for a selection variable on an object model. This object model is a "fiduciary" model that is used for Executors, Trustees, and Agents in an estate planning system; instead of having the label be "Select the Fiduciary", we would like the label to say "Select the Executor", "Select the Trustee", or "Select the Agent" based on the object variable the catalog is calling for.
The formula for this label would be a text formula and would look like this:
(Executors  map: id$  contains: id$)
? "Executor"
: (Guardians  map: id$  contains: id$
? "Guardian"
: "Trustee"
This formula first determines if the object model is an executor, and brings in "Executor" if it is; if it is not an executor, it determines if the object model is a guardian, and brings in "Guardian" if it is; if not, the only option left is for the object model to be a trustee, so it brings in "Trustee".
To use this formula in the label, you would simply have the formula be called "FiduciaryTitle" and in the label you would have "Select the {[FiduciaryTitle]}".
Situation: Create a formula to bring in the appropriate text for referring to the clients in an estate planning system, depending on whether the client name(s) have been filled in and whether the client is single or are a married couple. Essentially, for a label for the ClientWill object, you might want it to say "John Doe's Will" if John Doe's name is entered, and if John Doe's name is not entered, you might want it to say "First Spouse" if John Doe is married and "Client" if John Doe is not married.
The formula would be a text formula like this:
Client.FullName  (Married ? "First Spouse" : "Client")
In this formula, Knackly first determines whether the Client.FullName is answered and uses Client.FullName if it is answered. If Client.FullName hasn't been answered, then it determines whether the situation is for a married couple and brings in either "First Spouse" or "Client" accordingly.