Skip to main content

Miscellaneous Operators

( ) (Parentheses) Operator

Behavior: Use parentheses to control the order in which operations are performed within an expression. See Precedence of Operators to understand the order in which operations are performed when parentheses are not used. When in doubt, use parentheses to ensure operations are carried out in the desired order. Also see Uses of Parentheses for more details.

( expression )


put 2 * (height + width) into perimeter

AsList Function

Behavior: The asList function is called with an object (property list) as a parameter, it first checks whether the object has an asList property. If so, its value is returned. If not, and the object has an asListExpression property, the value of that property is evaluated as an expression (equivalent to calling the value() function) to obtain the list value. If the object has neither of these properties, an asList function message is sent exclusively to the object and its helpers, and its return value is used.

If the target is not an object (or does not have an asList or asListExpression property or an asList function handler) and it is not already a list, the target's string value is evaluated as an expression (equivalent to calling the value() function) to obtain the list value.

{the} asList of factor
asList( expr )


put file "scores" as a list into testScores


Is A, Is Not A, Isn't A, Is All, Is Not All, Isn't All Operators

Behavior: Checks whether a value is valid as a particular type, or analyzes the contents of a value. You can test whether a value is or is not a number, integer, even number, odd number, positive number, negative number, positive integer, negative integer, point, rectangle, date, time, or Boolean. A variable can be tested to see whether it is a list, a range, an iterator, a file, a folder, a tree, or an object. You can also test whether a character or all characters in a value are digits, letters, alphanumeric, uppercase, lowercase, punctuation, blank (or whitespace), blankOrReturn (or whitespaceOrReturn), or controlChars. You can tell if a value is actually a reference to another container, by testing whether or not it is a reference. In addition, the is a operator can also be used to test for custom object types if the object defines an objectType property (see the ObjectType property in Special Properties).

valueToTest is {not} a typeIdentifier
valueToTest is {not} all typeIdentifier

Examples: The following expressions all yield "true":

put pi is a number
put pi is not an integer
put -12 is an even number
put 5683 is an odd number
put 98.6 is a positive number
put 0 isn't a positive number
put -13.2 is a negative number
put 144 is a positive integer
put -1 is a negative integer
put "123, 12.5" is a point
put "123, 12.5, 245, 25" is a rectangle
put (snow is greater than rain) is a boolean
put (a,b,c) is a list
put 14..94 is a range
put (a,b,c) is an iterator
put "July 4, 1776" is a date
put "/System/Library/Fonts/Courier.dfont" is a file
put "/System" is a folder
put (partnum:"4X56N32", qty:14) is an object
put 6 is a digit
put character 2 of "4X56N32" is a letter
put "J946Ux" is an alphanumeric
put "a" is a lowercase
put "ABCdef" isn't all uppercase
put "(),.;:!?[]{}%\’/" is all punctuation
put space is a blank
put space & tab & return is all blankOrReturn
put tab is a controlChar
put @foo is a reference
put radius:23, objectType:("Shape", "Circle") is a "Circle"
put <"[", character, "]"> is a pattern

An error is raised if typeIdentifier is not one of the following valid identifiers, or an expression that evaluates to one of the built-in identifiers listed below, unless valueToTest is an object or property list.

If the valueToTest is an object, the is a operator evaluates to the value returned by sending an isObjectType function message to the object, with typeIdentifier as a parameter. The default implementation of this function checks the objectType property of the object contains the typeIdentifier. If a property list has an objectType property, it may be a single value or a list of values. If typeIdentifier is equal to any item in the objectType list, the is a operator will evaluate to true, otherwise it will be false.

IdentifierTrue When the Value to Test Is
"true" or "false", "yes" or "no", "on" or "off", or empty
a value other than a single number that can be converted to a date or time value
even numbera whole number that is evenly divisible by 2
filea file object or file name of an existing file, not a folder
a file object or file name of an existing folder, not a plain file
a "whole" number without any fractional part
iteratoran iterable value such as a list or range
lista list
negative integera whole number that is less than zero
negative numbera number that is less than zero
numbera number
an object or property list
odd numbera whole number that is not evenly divisible by 2
patterna pattern definition using SenseTalk's pattern language
pointa list of two numbers, or two numbers separated by commas
positive integera whole number that is greater than zero
positive numbera number that is greater than zero
rangea range
a list of four numbers, a list of two points, or four numbers separated by commas
referencea reference to another container
treea tree

The following identifiers can be used to test the type of characters in a text value:

IdentifierTrue When Every Character of the Value to Test Is
alphanumerica letter or a digit
a space or a tab or a return
a space or a tab
a hidden control character such as return, tab, formfeed, etc.
a digit: 0,1,2,3,4,5,6,7,8, or 9
an upper- or lower-case letter
punctuationa punctuation character such as , . ! ? ; :
lowercasea lower-case letter
uppercasean upper-case letter

There Is A, There Is Not A, There Isn't A, There Is No, Exists, Does Not Exist, Doesn't Exist Operators

Behavior: Tests for the existence of a file, folder, variable, object, or object property. In the case of variables, this operator returns true if the variable has been assigned a value.

there is [a | an] thingThatMayExist
there is not [a | an] thingThatMayExist
there isn't [a | an] thingThatMayExist
there is no thingThatMayExist
thingThatMayExist exists
thingThatMayExist does not exist
thingThatMayExist doesn't exist

Where thingThatMayExist is one of:
file fileName
folder folderName
object objectIdentifier
property propertyName of _someObject
variable localOrDeclaredVariableName
global globalVariableName
universal universalVariableName


if there is a folder "BankReport" then ...


if there is no file "secretpasswords" then ...


if there is not an object "printHelper" then ...


if there is a property cost of material then ...


if there is a variable controller then ...


if file "answers" doesn't exist then create file "answers"


if property sequence of part exists then add 1 to part's sequence

Is Within, Is Not Within, Isn't Within Operators

Behavior: Tests whether a point lies within a rectangle, whether one rectangle is completely contained by another, or whether a value falls within a given range. All forms of the is within operator test for containment inclusive of the edges or endpoints of the containing rectangle or range. So, for example 9 is within 5..9 will evaluate as true.

Points are always specified as a pair of numbers representing the x and y coordinates of the point. Usually, these two values are given as a two-item list such as [12,42], but a text string containing two numbers separated by commas can also be used, such as “12,42”.

Rectangles are specified as 4 numbers, representing the locations of the left, top, right, and bottom of the rectangle, such as [5,18,105,118] — this rectangle would actually be a square, with both width and height of 100. You can also think of the four numbers as describing two points, which are opposite corners of the rectangle. A rectangle can also be specified as a list of 2 points, such as [ [5,18], [105,118] ].

point is {not} within rectangle
rectangle1 is {not} within rectangle2
value is {not} within range


if mousePoint is within windowBorder then ...


if lastLoc + [12,8] is within [10,10,90,50] then ...


if windowRect is not within screenRect then ...


if day is within 1 .. lastValidDay then ...

&&& List Concatenation Operator

Behavior: Joins two lists or values into a single list of values. The result of this operation is always a list, even if one of the operands is empty.

operand1 &&& operand2


put [1,2,3] &&& [4,5] into oneList -- results in [1,2,3,4,5]


put oneList &&& 6 --> [1,2,3,4,5,6]


put 0 &&& oneList --> [0,1,2,3,4,5]


put 12 &&& 42 into luckyList -- results in [12,42]

Joined By, Split By Operators

Behavior: The joined by operator combines the elements of a list or property list into a text string. The split by operator does the reverse, taking a text string and producing a list or property list from it. The word combined may be used in place of joined, and either with or using may be used instead of by in either operator if you prefer.

When working with property lists, two separators should be used. The first indicates the text separator between elements, and the second specifies the text separator between each key and its corresponding value. To split or join a list, only a single separator is needed.

sourceStructure [joined | combined] [by | with | using] separator1 {and separator2}
sourceText split [by | with | using] separator1 {and separator2}


put path split by "/" into components


set newPath to components combined using "/"


put {a:1, b:2} joined with ";" and "=" --> "a=1;b=2"


split inputString by <character in ".,:;">

As Operator

Behavior: The as operator can be used to tell SenseTalk to treat a value as a particular type, or force conversion to a different representation at a particular point in a script. For example, the as text operator can be used to force textual comparisons of values that might otherwise be compared as numbers.

sourceValue as [text | {a} string | number | date | time | color | data | {a} {property} list | {an} object | {a} tree | boolean | integer | base64]


if today is "April 15" as date then payTaxes


performTextOperation (hours * rate) as text


put "007" is equal to "7.0" --> True  (numeric comparison)


put "007" is equal to "7.0" as text --> False


put file "cust2497" as a property list into customer
Tech Talk

Internally, the as operator calls the asText, asNumber, asDate, asTime, asColor, asData, asList, asObject, and asTree functions.

The existence of the as operator does not imply that SenseTalk is a "typed" language. In fact, it is an "untyped" language, with values converted automatically to whatever internal representation is needed at any time. In practice, there are only a few relatively rare situations in which you will need to use this operator to explicitly force the internal representation of a value.

For example, SenseTalk won't automatically perform a date/time comparison just because two values could be treated as date/time values. To compare two values as date/times, both values must be in that representation, otherwise they will be compared as text, giving very different results (April comes before January alphabetically, for instance). One way to ensure this is by specifying as date or as time after both values as needed, as shown in the first example above.

Similarly, as data can be used to perform direct comparisons of raw binary data values rather than their text representations. It is most often used when reading or writing binary data files to keep the data in binary format. The byte chunk type can then be used to access individual bytes or byte ranges within the data.

The as list and as property list (or as object) operators are somewhat different. They don't merely indicate how a value should be treated, but for any value that isn't already in the requested representation they will evaluate that value's text as an expression (in the same manner as the value() function) to produce the requested structure. The as tree operator will similarly evaluate text as XML (equivalent to calling the treeFromXML() function).

When the value to be converted is an object, it may control its representation in each format if it implements an asText, asNumber, etc. handler, or has special properties that apply for the requested type. See the relevant as… function documentation for full details.

See Conversion of Values for more information on automatic conversion of values, and when you might use the as operator.

AsObject Function

Behavior: When the asObject function is called with a tree as a parameter, it converts the tree to a property list representation, according to the setting of the treeFormat's useStandardFormat property, otherwise the parameter's string value is evaluated as an expression (equivalent to calling the value() function) to obtain the property list value.

{the} asObject of factor
asObject( expr )


set ComputerSpecs to an empty tree
set ComputerSpecs's _tag to "Gaming"
set ComputerSpecs 's RAM to 16 GB
set ComputerSpecs 's Storage to 2 TB
put ComputerSpecs -- Displays the text representation of the tree '<Gaming RAM="16 gigabytes" Storage="2 terabytes"></Gaming>'
put ComputerSpecs as an object -- Displays the property list representation '{_tag:"Gaming", RAM:"16 gigabytes", Storage:"2 terabytes"}'


(If ... Then ... Else ...) Operator

Behavior: Evaluates to one of two values depending on some condition. The (if ... then ... else ...) operator, also known as a Selector Expression, can be used to select one of two values or an optional value within an expression, or to select one of two containers.

The selector expression, although it looks very similar, is not the same as the if ... then ... else ... control structure which controls whether statements are executed or not. Note that parentheses are always required around a selector expression, and it must always include a then expression. If the else expression is omitted, empty is assumed (that is, it's the same as saying else empty). The else expression is required when specifying a container.

( if condition then expression1 {else expression2} )


put "Delivered " & count & " widget" & (if count > 1 then "s")


put (if a>b then a else b) into bigger

This is equivalent to:

if a>b then put a into bigger else put b into bigger


The selector expression can also be used anywhere a container is expected, provided that both the then and else expressions specify containers:

add 100 to (if a<b then a else b)-- add to whichever is smaller

This is equivalent to:

if a<b then add 100 to a else add 100 to b -- add to whichever is smaller