# Expressions

Expressions combine values using various operators to yield new values. For example, the very simple expression 1+2 uses the "+" operator to produce the value 3. SenseTalk provides a wide range of operators which serve many different needs.

The values used as components in expressions can be of many different types. They may be simple values, such as numbers or text strings (as described in Values), or they may be values that are the contents of containers (Containers). Still another type of value is one provided by a `function`

. A function is a source of value that retrieves information that may vary. SenseTalk provides many functions for a wide variety of purposes. For information on working with functions, see Functions.

SenseTalk is a "typeless" language, so containers can store any type of value: numbers, text, dates, lists, etc. Values are automatically converted as needed, so, for example, if you perform a mathematical operation on a text value, SenseTalk converts that value to a number internally. For converting internal values back into a text format, SenseTalk provides mechanisms that allow you to control the format used.

## Precedence of Operators

Operators in complex expressions are evaluated in a specific order based on their precedence. The precedence of operators, from highest (those that are evaluated first) to lowest (those evaluated last) is as follows:

1st | `( )` (expressions enclosed in parentheses are evaluated first) |

2nd | (implicit concatenation—see below)`not` (logical not)`-` , `negative` (unary minus, or negation)`+` , `positive` (unary plus)`bitNot` (bitwise not) |

3rd | `^` , `to the power of` (exponentiation)`squared` `cubed` `%` , `percent` `ago` `hence` , `from now` `repeated` , `repeated up to a length of` `as` `with format` , `using format` |

4th | `*` , `times` , `multiplied by` `/` , `divided by` `div` `rem` `modulo` , `mod` `joined by` `split by` `rounded to` `rounded to nearest` `sorted` |

5th | `+` , `plus` `-` , `minus` `adding` , `adding the properties of` `replacing` , `replacing the properties of` `removing` , `removing the properties of` , `minus property` `retaining` , `retaining the properties of` `renaming` , `renaming the properties using` |

6th | `bitShift` |

7th | `&` (concatenate strings)`&&` (concatenate strings with space)`is a multiple of` `is evenly divisible by` `but at least` , `but no less than` `but at most` , `but no more than` |

8th | `&&&` (concatenate list) |

9th | `<` , `is less than` , `comes before` `>` , `is greater than` , `comes after` `<=` , `is less than or equal to` , `is at most` `>=` , `is greater than or equal to` , `is at least` `between` `contains` `is in` `is among` `is a` `is within` |

10th | `bitAnd` (bitwise and) |

11th | `bitXOr` (bitwise exclusive or`) |

12th | `bitOr` (bitwise or) |

13th | `=` , `is equal to` , `is` `<>` , `is not equal to` , `isn't` `begins with` `ends with` `matches` |

14th | `and` `and if` (short-circuit and) |

15th | `or` `or if` (short-circuit or) |

When operators at the same level of precedence are used together in an expression, they are evaluated from left to right. In any case, parentheses can be used around a sub-expression to force that group to be evaluated before other parts of the expression (see Uses of Parentheses, below).

## Implicit Concatenation

Implicit concatenation occurs when string literals, constants and certain predefined variables appear sequentially in an expression with no intervening operator. For example, this expression:

`"Line 1" return "This is " "Line 2"`

produces the same result as:

`"Line 1" & return & "This is " & "Line 2"`

In addition to the constants (return, true, false, empty, end) the predefined variables available for implicit concatenation are: space, tab, quote, comma, slash, backslash, newline, linefeed, lf, carriagereturn, creturn, cr, crlf.

## Uses of Parentheses

Parentheses are used for several different purposes in SenseTalk expressions.

### Grouping Operations

Parentheses can be used to force operations to be performed in a particular order, or to resolve any ambiguity that might otherwise exist. For example, consider this ambiguous expression:

`the square root of nine plus sixteen`

If a friend asked you "What is the square root of *nine-plus-sixteen*?" you would promptly add nine and sixteen to get twenty-five and then take the square root and give the desired answer: "five" (you do that sort of thing all the time, right?). Or, they might ask the question with slightly different emphasis and a brief pause after the word "nine", as "What is the *square-root-of-nine*, plus sixteen?". In this case you would first take the square root of nine and then add that result to sixteen to get the desired answer: "nineteen".

In the case of a script, there are no vocal clues to tell a reader which of the two possible interpretations to give to this expression. The meaning appears to be ambiguous—it could be interpreted either way. In fact, SenseTalk's rules of precedence come into play, and it evaluates the second way, giving a result of 19. If that isn't what you intended, use parentheses around the part of the expression that you want to be evaluated first:

`the square root of (nine plus sixteen)`

Readability is important in a script so that a reader of the script (including yourself at a later date) will be able to understand exactly what the script is doing. So even if the built-in rules give the answer you want, it may be a good idea to include parentheses to make it clear what was intended:

`(the square root of nine) plus sixteen`

### Forcing Evaluation as an Expression

In certain contexts, a word is treated as a literal value (the same as though it were in quotes). Enclosing such a word in parentheses forces it to be evaluated as an expression instead (specifically, as a variable name if it is a single word). This is most commonly used in the case of property names.

`put account.balance`

This expression accesses the "balance" property of the account object. But suppose in your script you sometimes want to access the balance and at other times the availableBalance. Earlier in the script a decision is made about which type of balance to use:

`set balanceToUse to "balance" -- use full actual balance unless withdrawing`

if action is "withdrawal" then set balanceToUse to "availableBalance"

To access the balance you might try this:

`put account.balanceToUse`

Unfortunately, this expression tries to access the property named "balanceToUse" of the account, which is the wrong name. To use the property name that is stored in the balanceToUse variable, use parentheses around the variable name to force it to be evaluated as an expression:

`put account.(balanceToUse)`

### Required Parentheses

Some expressions require the use of parentheses. For example, a list can be made by listing its items in parentheses, separated by commas. Other examples include property lists, function calls with multiple parameters, and the (if ... then ... else ...) selector expression.

## Vector Arithmetic with Lists

Vector arithmetic is supported. You can add or subtract two lists of numbers, provided they both have the same number of items. This will add or subtract the corresponding items of the two lists. Vector operations work with nested lists as well, provided that all corresponding sublists are of equal length.

`put [1,2,3] + [100,200,300] --> [101,202,303]`

Multiplication and division of lists also works for lists of equal length.

`put [100,200,300] / [2,10,100] --> [50,20,3]`

In addition, you can multiply or divide a list by a single value (sometimes called a ‘scalar’ because it scales all the values in the list).

`put [1,2,3] * 6 --> [6,12,18]`

## Case Sensitivity

Text comparison operators are usually not case-sensitive, as in this example:

`put "FLoWeR" is "flower" -- True`

You can control the case-sensitivity of operations in two ways. Set `the caseSensitive`

property to true or false to define whether by default uppercase and lowercase letters are treated differently or not. This property, which is local to each handler, is set to false at the beginning of each handler, so ordinarily case is ignored.

For more information about `the caseSensitive`

property, see Global and Local Properties for Working with Values.

Case-sensitivity can also be customized for each comparison, overriding the setting of `the caseSensitive`

property. To do this, specify `considering case`

, `with case`

, or `case sensitive`

(to force case to be considered), or `ignoring case`

, `without case`

, or `case insensitive`

(to force case to be ignored) for each operator:

`put "FLoWeR" is "flower" considering case -- False`

## Operators and Functions

To understand how to use specific operators and functions in the expressions you plan to create, see the following topics: