Perfect Developer basic tutorial 1 This page last modified 2011-10-29 (JAC)

Symbols used in Perfect

// Introduces a comment that terminates at the end of the line. This is the only form of comment available in Perfect.
; is used as a separator between declarations and/or statements. A semicolon after the final declaration or statement is not needed but is permitted. When statements are separated by semicolon, they are executed sequentially.
, is used as a separator between expressions, between postconditions and between statements. When statements are separated by comma, they are executed concurrently. Likewise, postconditions separated by comma are satisfied concurrently.
^= is pronounced is defined as and means exactly that. For example, const myFavoriteNumber ^= 3 defines the constant myFavoriteNumber as being the value 3.
: is pronounced of type. It is followed by a type expression and declares the preceding entity to be of that type. For example, function square(x: int): int declares a function called square that takes a parameter x of type int and returns another int.
:: is pronounced belonging to (or just in). It is followed by an expression of a collection type and declares the entity to range over the values in that collection. Only declarations of bound variables may have this form.

For example, x::s means that x ranges over the elements of collection s.
:- always appears between a bound variable declaration and a predicate. In a forall expression it is pronounced it is the case that; in an exists, any, that or those expression it is pronounced such that.

For example, forall x::myScores :- x > 50 means forall x in myScores, it is the case that x is greater than 50.
! Exclamation mark, or bang, ! means that a change of value occurs in the entity (variable, parameter or self) that precedes it (or occasionally follows it).

For example, myAccount!withdraw(someMoney, success!) invokes the method withdraw on the variable myAccount, with parameters someMoney and success, changing the values of variables myAccount and success in the process.
' Prime ' means take the final value of the expression that precedes it instead of the initial value.

For example, the expression x' = x + 1 says that the final value of x is one greater than its initial value.

Similarly, the expression myAccount'.balance < myAccount.balance says that calling the function balance on the final value of myAccount yields a lower value than calling the same function on the initial value (this might be an unfortunate consequence of calling the withdraw method!).
@ Asperand @ is used between a name and a class name to indicate that the meaning of the name is to be found in the specified class.

So, the term overdrawn@AccountStatus refers to a constant or a function called overdrawn declared in class AccountStatus. The equivalent in Java would be AccountStatus.overdrawn, or in C++ AccountStatus::overdrawn.
& Ampersand & means logical and.
| means logical or.
~ Tilde ~ means logical not. It can also be used as a prefix to a comparison operator, or to the in operator, reversing the meaning.

For example, ~< means not less than, ~= means not equal, and ~in means not in.
~~ does not mean double negation (which would be pointless), it is the compare operator. Use it to compare two values, yielding one of below@rank, same@rank, above@rank.
= = means equality, not assignment.

So a = b is a Boolean expression comparing the values of a and b, not a statement  assigning the value of b to a.
|| || is used between two type expressions to unite those types (i.e. create a type that accepts all the values of either component type).

For example, a variable of type int || bool accepts values true and false as well as 1, 2, 3 ... .
# Octothorpe, or hash, # is used for various operators that count a number of elements in the built-in collection types

For example, in evaluating the length of a sequence.
++ ++ is a binary operator, typically used to combine two collections (e.g. set union, sequence concatenation).
-- -- is a binary operator, typically used to remove the elements in one collection from another.
** ** is a binary operator, typically used to find the common elements in two collections.
> > as a binary operator means greater than, and as a unary operator means successor (equivalent to "+1" when applied to an integer operand).
< < as a binary operator means less than, and as a unary operator means predecessor (equivalent to "-1" when applied to an integer operand).
.. .. is a binary operator taking two operands of integer, character or an enumerated type. It is typically defined as yielding a sequence of all those values of the type from the first up to the second, in ascending order.
? ? is used in Perfect to mean "we haven't decided what belongs here yet". You can use this in many places in Perfect to make your source file syntactically correct even though you haven't finished it yet, allowing you to run the source file through the compiler to check what you have written so far.

As well as the above symbols, Perfect uses the symbols * / % ## %% and ^ as binary operators, and + and - as unary or binary operators.

A Perfect language processor will always construct the longest symbol it can from the source text before starting a new one. For example, x--y is recognised as the operator -- between identifiers x and y even if no such operator is defined between the corresponding types. If you meant to negate y and subtract the result from x, you had better include a space between the two - symbols, or (preferably) use x-(-y) instead.

Brackets

Round brackets are used to parenthesize expressions, as in 3 * (4 + 5), and to surround the parameters in a method call, such as members!add("David Crocker", "Escher Technologies Limited"). They are also used to parenthesize types and parts of postconditions.

Square brackets are used to invoke the indexing operator (like indexing into an array in most programming languages) or to enclose conditions (also called guards) in conditional constructs. You can always tell which of these meanings a pair of square brackets has, because square brackets that are part of a conditional construct are not directly preceded by an expression. So both sets of square brackets in ([x > y]: x, []: y) are there to enclose conditions (the second condition is empty).

Curly brackets are used only to enclose the parameter list in a constructor call. So if you see the expression account{"Joe Bloggs", 0.0} then you can be sure that this is a constructor call and account must be a type name.

The various kinds of literals (numbers, strings etc.) are discussed when we talk about the classes to which they relate.

In the next section of this tutorial, we will go on to the built-in data classes bool, char, and int. We'll show you how to construct your own enumeration classes, and we'll cover the most commonly used expressions.

Next:  Types and Expressions

 

Save My Place Glossary Language Reference Manual
Tutorials Overview Main site   
Copyright © 1997-2012 Escher Technologies Limited. All rights reserved. Information is subject to change without notice.