Elan Library Reference

## Table of contents

### Main topics | Detailed topics

# Value data types

## Integer

An integer is a whole number, i.e. one that has no fractional part. It may be represented in decimal, hexadecimal or binary:

`100100100100100` (decimal), `0x640x640x64&H640x64` (hexadecimal) and `0b11001000b11001000b1100100&B11001000b1100100` (binary) all have the same value.

Its type is `IntintintIntegerint`.

name of Type | examples of defining a literal value
--- | ---
`IntintintIntegerint` | `+constant maxNumbername? set to 10literal value or data structure?0+maxNumbername? = 10literal value or data structure? # constant1+const Int maxNumbername? = 10literal value or data structure?;2+Const maxNumbername? = 10literal value or data structure?3+static final Int maxNumbername? = 10literal value or data structure?; // constant4`
`IntintintIntegerint` | `variable flagsname? set to 0b1100100value or expression?5flagsname? = 0b1100100value or expression? # variable definition6var flagsname? = 0b1100100value or expression?;7Dim flagsname? = &B1100100value or expression? ' variable definition8var flagsname? = 0b1100100value or expression?;9`

### Function dot methods on an `IntintintIntegerint`

function dot method | argument types | return type | returns
--- | --- | --- | ---
asBinary | (none) | `StringstrstringStringString` | string of binary digits representing the argument's integer value
equals | `IntintintIntegerint` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if integer and argument values are equal – `falseFalsefalseFalsefalse` otherwise
notEqualTo | `IntintintIntegerint` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if integer and argument values are unequal – `falseFalsefalseFalsefalse` otherwise
toString | (none) | `StringstrstringStringString` | a string of decimal digits representing the argument's integer value

#### Notes

- A literal integer or a named value of type `IntintintIntegerint` may always be passed into a function or procedure that is expecting a `FloatfloatdoubleDoubledouble`.
- The `IntintintIntegerint` type is intended to represent whole numbers in the range:
- - Maximum: 253 − 1 (which is 9,007,199,254,740,991)
  - Minimum value: −(253 − 1)
- If you go greater than the limit given above, the number will be accurate to approximately 17 decimal digits. Larger numbers will be rounded with zeros at the end, unless they are larger than around 270, when they will automatically be shown in exponential (scientific) format, as shown in the example.

#### Example of base conversion

● Functions to return an integer value as a hexadecimal string:

+function hex name?(n as Int parameter definitions?) returns String Type? 195 variable h name? set to ""value or expression?196 +if (n < 1)condition? then 197 assign h variableName? to "0"value or expression?198 else 199 variable m name? set to n value or expression?200 +while m > 0 condition? 201 assign h variableName? to hexDigit(m mod 16) + h value or expression?202 assign m variableName? to divAsInt(m, 16)value or expression?203 end while end if return h value or expression?204 end function
+def hex name?(n: int parameter definitions?) -> str Type?: # function 205 h name? = ""value or expression? # variable definition 206 +if (n < 1)condition?: 207 h variableName? = "0"value or expression? # assignment 208 else:209 m name? = n value or expression? # variable definition 210 +while m > 0 condition?: 211 h variableName? = hexDigit(m % 16) + h value or expression? # assignment 212 m variableName? = divAsInt(m, 16)value or expression? # assignment 213 # end while # end if return h value or expression?214 # end function
+static string Type? hex name?(int n parameter definitions?) { // function 215 var h name? = ""value or expression?;216 +if ((n < 1)condition?) { 217 h variableName? = "0"value or expression?; // assignment 218 } else {219 var m name? = n value or expression?;220 +while (m > 0 condition?) { 221 h variableName? = hexDigit(m % 16) + h value or expression?; // assignment 222 m variableName? = divAsInt(m, 16)value or expression?; // assignment 223 } // end while } // end if return h value or expression?;224 } // end function
+Function hex name?(n As Integer parameter definitions?) As String Type? 225 Dim h name? = ""value or expression? ' variable definition 226 +If (n < 1)condition? Then 227 h variableName? = "0"value or expression? ' assignment 228 Else 229 Dim m name? = n value or expression? ' variable definition 230 +While m > 0 condition? 231 h variableName? = hexDigit(m Mod 16) + h value or expression? ' assignment 232 m variableName? = divAsInt(m, 16)value or expression? ' assignment 233 End While End If Return h value or expression?234 End Function
+static String Type? hex name?(int n parameter definitions?) { // function 235 var h name? = ""value or expression?;236 +if ((n < 1)condition?) { 237 h variableName? = "0"value or expression?; // assignment 238 } else {239 var m name? = n value or expression?;240 +while (m > 0 condition?) { 241 h variableName? = hexDigit(m % 16) + h value or expression?; // assignment 242 m variableName? = divAsInt(m, 16)value or expression?; // assignment 243 } // end while } // end if return h value or expression?;244 } // end function

#### Example of large numbers

● This code calculates 2 raised to the power of 50 through 72, and its output is shown below:

+main 245 +for n item? in range(50, 73)source? 246 variable np name? set to pow(2, n).floor()value or expression?247 call printTab procedureName?(n.toString().length(), $"{n}"arguments?)248 call printTab procedureName?(30 - np.toString().length(), $"{np}\n"arguments?)249 end for end main
+def main() -> None: 250 +for n item? in range(50, 73)source?: 251 np name? = pow(2, n).floor()value or expression? # variable definition 252 printTab procedureName?(n.toString().length(), f"{n}"arguments?) # procedure call 253 printTab procedureName?(30 - np.toString().length(), f"{np}\n"arguments?) # procedure call 254 # end for # end main
+static void main() { 255 +foreach (var n item? in range(50, 73)source?) { 256 var np name? = pow(2, n).floor()value or expression?;257 printTab procedureName?(n.toString().length(), $"{n}"arguments?); // procedure call 258 printTab procedureName?(30 - np.toString().length(), $"{np}\n"arguments?); // procedure call 259 } // end foreach } // end main
+Sub main() 260 +For Each n item? In range(50, 73)source? 261 Dim np name? = pow(2, n).floor()value or expression? ' variable definition 262 printTab procedureName?(n.toString().length(), $"{n}"arguments?) ' procedure call 263 printTab procedureName?(30 - np.toString().length(), $"{np}\n"arguments?) ' procedure call 264 Next n End Sub
+static void main() { 265 +foreach (var n item? in range(50, 73)source?) { 266 var np name? = pow(2, n).floor()value or expression?;267 printTab procedureName?(n.toString().length(), String.format("%", n)arguments?); // procedure call 268 printTab procedureName?(30 - np.toString().length(), String.format("%\n", np)arguments?); // procedure call 269 } // end foreach } // end main

## Floating point

A floating point number is a decimal number (also known as a Real number) that may have both integer and fractional parts.

Its type is `FloatfloatdoubleDoubledouble`.

It may be written using exponential (scientific) notation, e.g. `120.0120.0120.0120.0120.0` can be written as `1.20e21.20e21.20e21.20e21.20e2`, and `0.0120.0120.0120.0120.012` as `1.20e-21.20e-21.20e-21.20e-21.20e-2`

name of type | examples of defining a literal value
--- | ---
`FloatfloatdoubleDoubledouble` | `+constant phiname? set to 1.618033988749895literal value or data structure?10+phiname? = 1.618033988749895literal value or data structure? # constant11+const Float phiname? = 1.618033988749895literal value or data structure?;12+Const phiname? = 1.618033988749895literal value or data structure?13+static final Float phiname? = 1.618033988749895literal value or data structure?; // constant14`
`FloatfloatdoubleDoubledouble` | `variable readingname? set to 1.1e-10value or expression?15readingname? = 1.1e-10value or expression? # variable definition16var readingname? = 1.1e-10value or expression?;17Dim readingname? = 1.1e-10value or expression? ' variable definition18var readingname? = 1.1e-10value or expression?;19`

### Function dot methods on a `FloatfloatdoubleDoubledouble`

function dot method | argument types | return type | returns
--- | --- | --- | ---
ceiling | (none) | `IntintintIntegerint` | the first integral value larger than or equal to the argument's floating point value
equals | `FloatfloatdoubleDoubledouble` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if floating point number and argument values are equal – `falseFalsefalseFalsefalse` otherwise
floor | (none) | `IntintintIntegerint` | the first integral value smaller than or equal to the argument's floating point value
isInfinite | (none) | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if value would be infinite, e.g. after division by zero – `falseFalsefalseFalsefalse` otherwise
isNaN | (none) | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if value is 'NaN', i.e. Not a Number, e.g. 0/0 – `falseFalsefalseFalsefalse` otherwise
notEqualTo | `FloatfloatdoubleDoubledouble` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if floating point number and argument values are unequal – `falseFalsefalseFalsefalse` otherwise
round | `IntintintIntegerint` | `FloatfloatdoubleDoubledouble` | the value rounded (up or down as appropriate) to the number of decimal places specified in the argument
toString | (none) | `StringstrstringStringString` | a string of decimal digits and decimal point representing the argument's floating point value

#### Notes

- The limits on floating point numbers are:
  - Maximum value: just over 1.0 × 10308
  - Minimum value: approximately 5.0 × 10-324
- A variable that has been defined as being of type `FloatfloatdoubleDoubledouble` may not be passed as an argument into a method that requires an `IntintintIntegerint`, nor as an index into a `ListlistListListList` even if the variable contains no fractional part. It may, however, be converted into an `IntintintIntegerint` before passing, using the function floor or ceiling.
- If you wish to define a variable to be of type `FloatfloatdoubleDoubledouble`, but initialise it with an integer value, then add .0 on the end of the whole number, as in:
  variable hoursWorked name? set to 3.0 value or expression?270
  hoursWorked name? = 3.0 value or expression? # variable definition 271
  var hoursWorked name? = 3.0 value or expression?;272
  Dim hoursWorked name? = 3.0 value or expression? ' variable definition 273
  var hoursWorked name? = 3.0 value or expression?;274
- Any variable or expression that evaluates to an `IntintintIntegerint` may always be used where a `FloatfloatdoubleDoubledouble` is expected.

## Boolean

A Boolean value is either `trueTruetrueTruetrue` or `falseFalsefalseFalsefalse`.

Its type is `BooleanboolboolBooleanboolean`.

The words `trueTruetrueTruetrue` and `falseFalsefalseFalsefalse` must be written in lower case.

name of type | examples of defining a literal value
--- | ---
`BooleanboolboolBooleanboolean` | `variable donename? set to truevalue or expression?20donename? = Truevalue or expression? # variable definition21var donename? = truevalue or expression?;22Dim donename? = Truevalue or expression? ' variable definition23var donename? = truevalue or expression?;24`

### Function dot methods on a `BooleanboolboolBooleanboolean`

function dot methods | argument types | return type | returns
--- | --- | --- | ---
equals | `BooleanboolboolBooleanboolean` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the truth value and argument are equal – `falseFalsefalseFalsefalse` otherwise
notEqualTo | `BooleanboolboolBooleanboolean` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the truth value and argument are unequal – `falseFalsefalseFalsefalse` otherwise
toString | (none) | `StringstrstringStringString` | String "true" if `trueTruetrueTruetrue`, "false" if `falseFalsefalseFalsefalse`

# Reference data types

## String

The data type `StringstrstringStringString` represents text, i.e. a sequence of zero or more characters.

name of type | examples of defining a literal value | details
--- | --- | ---
`StringstrstringStringString` | `+constant titlename? set to "Ulysses"literal value or data structure?25+titlename? = "Ulysses"literal value or data structure? # constant26+const String titlename? = "Ulysses"literal value or data structure?;27+Const titlename? = "Ulysses"literal value or data structure?28+static final String titlename? = "Ulysses"literal value or data structure?; // constant29` | delimited by double quotes
`StringstrstringStringString` | `variable quotename? set to "'Hello', she said"value or expression?30quotename? = "'Hello', she said"value or expression? # variable definition31var quotename? = "'Hello', she said"value or expression?;32Dim quotename? = "'Hello', she said"value or expression? ' variable definition33var quotename? = "'Hello', she said"value or expression?;34` | ' may be used in a string delimited by "
`StringstrstringStringString` | `variable emptyStringname? set to ""value or expression?35emptyStringname? = ""value or expression? # variable definition36var emptyStringname? = ""value or expression?;37Dim emptyStringname? = ""value or expression? ' variable definition38var emptyStringname? = ""value or expression?;39` | a zero-length, or 'empty', string

### Character sets

When typing from the keyboard into a literal string all the basic ASCII characters (0x20 to 0x7e) and '£' can be input.

You cannot use Alt+numeric-keypad to enter accented letters or other special characters in the extended ASCII range (0x80 to 0xff).

You can, however, copy any text from outside Elan and paste it into a string, whether ASCII, extended ASCII or UTF-8 encoded.

To insert a character from the full range, you use its Unicode (codepoint) value, in decimal or hexadecimal, by means of function unicode :

`print($"Spanish introduces a question with {unicode(191)}"arguments?)40print(f"Spanish introduces a question with {unicode(191)}"arguments?)41Console.WriteLine($"Spanish introduces a question with {unicode(191)}"arguments?); // print statement42Console.WriteLine($"Spanish introduces a question with {unicode(191)}"arguments?) ' print statement43System.out.println(String.format("Spanish introduces a question with %", unicode(191))arguments?); // print statement44` | ⟶ | Spanish introduces a question with ¿
`print($"This is an up arrow: {unicode(0x2191)}"arguments?)45print(f"This is an up arrow: {unicode(0x2191)}"arguments?)46Console.WriteLine($"This is an up arrow: {unicode(0x2191)}"arguments?); // print statement47Console.WriteLine($"This is an up arrow: {unicode(&H2191)}"arguments?) ' print statement48System.out.println(String.format("This is an up arrow: %", unicode(0x2191))arguments?); // print statement49` | ⟶ | This is an up arrow: ↑

These examples 'interpolate' the output of function unicode by using a $ before the string and curly braces within it. Ssee Interpolated fields ).

### Manipulating strings

Strings can be built from other strings by concatenation using the plus operator, for example:

`print("Hello " + "world"arguments?)50print("Hello " + "world"arguments?)51Console.WriteLine("Hello " + "world"arguments?); // print statement52Console.WriteLine("Hello " + "world"arguments?) ' print statement53System.out.println("Hello " + "world"arguments?); // print statement54` | ⟶ | Hello world

A newline may be inserted within a string with \n:

`print("Hello\nworld"arguments?)55print("Hello\nworld"arguments?)56Console.WriteLine("Hello\nworld"arguments?); // print statement57Console.WriteLine("Hello\nworld"arguments?) ' print statement58System.out.println("Hello\nworld"arguments?); // print statement59` | ⟶ | Hello world

When editing and you leave the field, the newline will be implicitly applied in your code.

As in most languages, strings are immutable. When you apply any operation or function with the intent of modifying an existing `StringstrstringStringString`, the existing `StringstrstringStringString` is never changed. Instead, the operation or function will return a new `StringstrstringStringString` that is based on the original, but with the specified differences.

You can loop through a `StringstrstringStringString` picking each of its characters sequentially using the for loop .

### Function dot methods on a String

function dot method | argument types | return type | returns
--- | --- | --- | ---
asRegExp | (none) | `RegExpRegExpRegExpRegExpRegExp` | a new string that is a a converted to a regular expression: no check is made of whether the result is a valid regular expression
asUnicode | (none) | `IntintintIntegerint` | the Unicode value of the first character of the string (To convert a Unicode value into a string, use function unicode )
contains | (none) | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the string contains the substring specified as the argument – `falseFalsefalseFalsefalse` otherwise
equals | `StringstrstringStringString` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the string and argument are equal – `falseFalsefalseFalsefalse` otherwise
notEqualTo | `StringstrstringStringString` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the string and argument are unequal – `falseFalsefalseFalsefalse` otherwise
indexOf | `StringstrstringStringString` | `IntintintIntegerint` | index of the first instance of the argument (substring) within the string If it is not present, -1 is returned
isAfter | `StringstrstringStringString` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if alphabetic comparison finds the string comes strictly 'after' the argument string – `falseFalsefalseFalsefalse` otherwise
isAfterOrSameAs | `StringstrstringStringString` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if alphabetic comparison finds the string comes 'after' or equals the argument string – `falseFalsefalseFalsefalse` otherwise
isBefore | `StringstrstringStringString` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if alphabetic comparison finds the string comes strictly 'before' the argument string – `falseFalsefalseFalsefalse` otherwise
isBeforeOrSameAs | `StringstrstringStringString` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if alphabetic comparison finds the string comes 'before' or equals the argument string – `falseFalsefalseFalsefalse` otherwise
length | (none) | `IntintintIntegerint` | the number of characters in the string
lowerCase | (none) | `StringstrstringStringString` | a new string with the original rendered in lower case
matchesRegExp | `RegExpRegExpRegExpRegExpRegExp` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the string matches the regular expression – `falseFalsefalseFalsefalse` otherwise
replace | `StringstrstringStringString`, `StringstrstringStringString` | `StringstrstringStringString` | a new string with all occurrences of the first argument string replaced by the second argument string
split | `StringstrstringStringString` | `List<of String>list[str]List<string>List(Of String)List<String>` | a `ListlistListListList` of the substrings found between occurrences of the argument string if the argument is the empty string then the list is of all the individual characters
subString | `IntintintIntegerint`, `IntintintIntegerint` | `StringstrstringStringString` | a new string that is the substring specified by the two positive integers (m,n) where m indexes the first character of the substring required (counting from 0) and n indexes the character after the last character required (exclusive index) if m ≥ n the result is the empty string
toString | (none) | `StringstrstringStringString` | the string itself
trim | (none) | `StringstrstringStringString` | a new string with leading and trailing spaces removed
upperCase | (none) | `StringstrstringStringString` | a new string with the original rendered in upper case

### Interpolated fields in strings

Strings support interpolation, that is you can insert the values of variables or simple expressions within the string by enclosing them in curly braces and prefixing the string with a $:

If `aaaaa` and `bbbbb` have values 3 and 17:

`print($"{a} times {b} equals {a*b}"arguments?)60print(f"{a} times {b} equals {a*b}"arguments?)61Console.WriteLine($"{a} times {b} equals {a*b}"arguments?); // print statement62Console.WriteLine($"{a} times {b} equals {a*b}"arguments?) ' print statement63System.out.println(String.format("% times % equals %", a, b, a*b)arguments?); // print statement64` | ⟶ | 3 times 17 equals 51

If `velocityvelocityvelocityvelocityvelocity` and `fuelfuelfuelfuelfuel` have values 3.0 and 50.4:

`assign messagevariableName? to $"LANDED SAFELY AT SPEED {(velocity*100).floor()} FUEL {fuel.floor()}"value or expression?65messagevariableName? = f"LANDED SAFELY AT SPEED {(velocity*100).floor()} FUEL {fuel.floor()}"value or expression? # assignment66messagevariableName? = $"LANDED SAFELY AT SPEED {(velocity*100).floor()} FUEL {fuel.floor()}"value or expression?; // assignment67messagevariableName? = $"LANDED SAFELY AT SPEED {(velocity*100).floor()} FUEL {fuel.floor()}"value or expression? ' assignment68messagevariableName? = String.format("LANDED SAFELY AT SPEED % FUEL %", (velocity*100).floor(), fuel.floor())value or expression?; // assignment69` `print(messagearguments?)70print(messagearguments?)71Console.WriteLine(messagearguments?); // print statement72Console.WriteLine(messagearguments?) ' print statement73System.out.println(messagearguments?); // print statement74` | ⟶ | LANDED SAFELY AT SPEED 300 FUEL 50

And for the area of a circle:

+main 275 variable r name? set to 2.0 value or expression?276 print($"area = {(pi*r*r).round(2)}"arguments?)277 end main +def main() -> None: 278 r name? = 2.0 value or expression? # variable definition 279 print(f"area = {(pi*r*r).round(2)}"arguments?)280 # end main +static void main() { 281 var r name? = 2.0 value or expression?;282 Console.WriteLine($"area = {(pi*r*r).round(2)}"arguments?); // print statement 283 } // end main +Sub main() 284 Dim r name? = 2.0 value or expression? ' variable definition 285 Console.WriteLine($"area = {(pi*r*r).round(2)}"arguments?) ' print statement 286 End Sub +static void main() { 287 var r name? = 2.0 value or expression?;288 System.out.println(String.format("area = %", (pi*r*r).round(2))arguments?); // print statement 289 } // end main | ⟶ | area = 12.57

## Standard data structures

Elan has two mutable data structure types `ListlistListListList` and `DictionaryDictionaryDictionaryDictionaryDictionary`, and three immutable data structure types `HashSetHashSetHashSetHashSetHashSet`, `StackStackStackStackStack` and `QueueQueueQueueQueueQueue`.

The contents of these structures are referred to as items (or sometimes elements).

The values of items in a mutable structure may be changed directly by calling the various procedure dot methods defined for each structure type.

The values of items in an immutable structure cannot be changed directly, and so have no procedure dot methods defined for them: rather, the methods called on them create new copies of the structures containing specified changes.

Since procedure methods may be called only from within the main routine or a procedure, it is also possible to make changes via function dot methods, which return a copy of the data structure with specified changes: that is why all such methods have names starting 'with'.

Immutable data structures are intended specifically to facilitate the Functional Programming paradigm, but some are also useful within other programming paradigms.

All six contain values (and keys in the case of a `DictionaryDictionaryDictionaryDictionaryDictionary`) of only a single type, that type being specified either explicitly (as in <of `IntintintIntegerint`>), or implicitly if the structure is created using a literal definition.

This table summarises the creation and reference to these structures. Details of their methods follow.

| List | Dictionary | HashSet | Stack | Queue
--- | --- | --- | --- | --- | ---
mutability | Mutable | Mutable | Immutable | Immutable | Immutable
type form | `List<of Type>list[Type]List<Type>List(Of Type)List<Type>` The type of item can be any, including `ListlistListListList` for 'jagged' data | `Dictionary<of KeyType, ValueType>Dictionary[KeyType, ValueType]Dictionary<KeyType, ValueType>Dictionary(Of KeyType, ValueType)Dictionary<KeyType, ValueType>` `keyTypekeyTypekeyTypekeyTypekeyType` is `IntintintIntegerint`, `FloatfloatdoubleDoubledouble`, `StringstrstringStringString` or `BooleanboolboolBooleanboolean` `valueTypevalueTypevalueTypevalueTypevalueType` may be any type | `HashSet<of Type>HashSet[Type]HashSet<Type>HashSet(Of Type)HashSet<Type>` The type of the item must be immutable | `Stack<of Type>Stack[Type]Stack<Type>Stack(Of Type)Stack<Type>` The type of the item must be immutable | `Queue<of Type>Queue[Type]Queue<Type>Queue(Of Type)Queue<Type>` The type of the item must be immutable
size | Dynamic | Dynamic | Dynamic | Dynamic | Dynamic
literal definition | `[2, 3, 5, 7, 11][2, 3, 5, 7, 11]new [] {2, 3, 5, 7, 11}{2, 3, 5, 7, 11}list(2, 3, 5, 7, 11)` | Not available | Only as converted from a literal `ListlistListListList` e.g. `["a", "b", "c"].asSet()["a", "b", "c"].asSet()new [] {"a", "b", "c"}.asSet(){"a", "b", "c"}.asSet()list("a", "b", "c").asSet()` | Not available | Not available
create empty | `new List<of Type>()list[Type]()new List<Type>()New List(Of Type)()new List<Type>()` | `new Dictionary<of KeyType, ValueType>()Dictionary[KeyType, ValueType]()new Dictionary<KeyType, ValueType>()New Dictionary(Of KeyType, ValueType)()new Dictionary<KeyType, ValueType>()` | `new HashSet<of Type>()HashSet[Type]()new HashSet<Type>()New HashSet(Of Type)()new HashSet<Type>()` | `new Stack<of Type>()Stack[Type]()new Stack<Type>()New Stack(Of Type)()new Stack<Type>()` | `new Queue<of Type>()Queue[Type]()new Queue<Type>()New Queue(Of Type)()new Queue<Type>()`
create initialised | `createPopulatedList(number, value)createPopulatedList(number, value)createPopulatedList(number, value)createPopulatedList(number, value)createPopulatedList(number, value)` `createPopulatedListofLists(cols, rows, value)createPopulatedListofLists(cols, rows, value)createPopulatedListofLists(cols, rows, value)createPopulatedListofLists(cols, rows, value)createPopulatedListofLists(cols, rows, value)` | `createDictionarycreateDictionarycreateDictionarycreateDictionarycreateDictionary` | Not available | Not available | Not available
read by index | `li[2]li[2]li[2]li[2]li[2]` | `d["b"]d["b"]d["b"]d["b"]d["b"]` | not available | not available | not available
read by index range | `li.subList(3, 5)li.subList(3, 5)li.subList(3, 5)li.subList(3, 5)li.subList(3, 5)` lower bound is inclusive from 0 upper bound is exclusive | not available | not available | not available | not available
procedure methods to mutate contents | see Procedure methods on a List  | see Procedure methods on a Dictionary  | not available | not available | not available
function dot methods | see Function dot methods on a List  | see Function dot methods on a Dictionary  | see Function dot methods on a Set  | see Function dot methods on a Stack  | see Function dot methods on a Queue 

## List

The `ListlistListListList` type defines a data structure containing n items of any single type, including basic value types, structure types such as `ListlistListListList`, and user-defined types such as a Class.

Items in a List of n items are indexed from 0 to n-1.

To create a List, use either of:

- Method createPopulatedList  to define its length and the initial value (and implicitly the type) of its items:
  `variable aListname? set to createPopulatedList(10, "no one")value or expression?75aListname? = createPopulatedList(10, "no one")value or expression? # variable definition76var aListname? = createPopulatedList(10, "no one")value or expression?;77Dim aListname? = createPopulatedList(10, "no one")value or expression? ' variable definition78var aListname? = createPopulatedList(10, "no one")value or expression?;79`
- Define an empty List of the required type, and use the procedure methods listed below to populate it:
  `variable aListname? set to new List<of String>()value or expression?80aListname? = list[str]()value or expression? # variable definition81var aListname? = new List<string>()value or expression?;82Dim aListname? = New List(Of String)()value or expression? ' variable definition83var aListname? = new List<String>()value or expression?;84`
  `call aList.initialiseprocedureName?(10, "no one"arguments?)85aList.initialiseprocedureName?(10, "no one"arguments?) # procedure call86aList.initialiseprocedureName?(10, "no one"arguments?); // procedure call87aList.initialiseprocedureName?(10, "no one"arguments?) ' procedure call88aList.initialiseprocedureName?(10, "no one"arguments?); // procedure call89`
  `call aList.appendprocedureName?("4"arguments?)90aList.appendprocedureName?("4"arguments?) # procedure call91aList.appendprocedureName?("4"arguments?); // procedure call92aList.appendprocedureName?("4"arguments?) ' procedure call93aList.appendprocedureName?("4"arguments?); // procedure call94`

The item at index `ixixixixix` in List `aListaListaListaListaList` can then be changed using a reassign variable instruction and a valid index value in square brackets:

- `assign aList[ix]variableName? to "Smith"value or expression?95aList[ix]variableName? = "Smith"value or expression? # assignment96aList[ix]variableName? = "Smith"value or expression?; // assignment97aList(ix)variableName? = "Smith"value or expression? ' assignment98aList[ix]variableName? = "Smith"value or expression?; // assignment99`

A List's size can be dynamically changed using the procedure methods listed below.

### Deconstructing a List

A `ListlistListListList` may be split (deconstructed) into new named values using indexes and the methods head, tail  and subList :

- To extract the first item in a List:
  `variable headItemname? set to myList[0]value or expression?100headItemname? = myList[0]value or expression? # variable definition101var headItemname? = myList[0]value or expression?;102Dim headItemname? = myList(0)value or expression? ' variable definition103var headItemname? = myList[0]value or expression?;104`
  or
  `assign heatItemvariableName? to myList.head()value or expression?105heatItemvariableName? = myList.head()value or expression? # assignment106heatItemvariableName? = myList.head()value or expression?; // assignment107heatItemvariableName? = myList.head()value or expression? ' assignment108heatItemvariableName? = myList.head()value or expression?; // assignment109`
- To form a new List of all but the first item in a List:
  `variable tailListname? set to myList.tail()value or expression?110tailListname? = myList.tail()value or expression? # variable definition111var tailListname? = myList.tail()value or expression?;112Dim tailListname? = myList.tail()value or expression? ' variable definition113var tailListname? = myList.tail()value or expression?;114`
  If the original list contains only one item, the new List will be the empty List.
- To get some other portion of a List, use the method subList:
  `assign shortListvariableName? to myList.subList(1, 5)value or expression?115shortListvariableName? = myList.subList(1, 5)value or expression? # assignment116shortListvariableName? = myList.subList(1, 5)value or expression?; // assignment117shortListvariableName? = myList.subList(1, 5)value or expression? ' assignment118shortListvariableName? = myList.subList(1, 5)value or expression?; // assignment119`

In all these cases the items indexed must exist, else a runtime error will stop the program.

### Lists of lists

#### Two dimensional arrays

Understood as a grid, a 2D array is a List of 'columns' each of which is a List of 'row' items, i.e. it is a List of Lists in which the column number is the x coordinate, and the row number is the y coordinate.

To create a 2D array that holds a value of a single type in every cell, you define such a List of Lists thus:

- Use method createPopulatedListofLists  to set the size of, and initial value in, every x,y position:
  `variable array2Dname? set to createPopulatedListofLists(cols, rows, value)value or expression?120array2Dname? = createPopulatedListofLists(cols, rows, value)value or expression? # variable definition121var array2Dname? = createPopulatedListofLists(cols, rows, value)value or expression?;122Dim array2Dname? = createPopulatedListofLists(cols, rows, value)value or expression? ' variable definition123var array2Dname? = createPopulatedListofLists(cols, rows, value)value or expression?;124`
- For the special case of Block graphics , use 40 columns and 30 rows or (more simply):
  `variable gridname? set to createBlockGraphics(value)value or expression?125gridname? = createBlockGraphics(value)value or expression? # variable definition126var gridname? = createBlockGraphics(value)value or expression?;127Dim gridname? = createBlockGraphics(value)value or expression? ' variable definition128var gridname? = createBlockGraphics(value)value or expression?;129`

The item at index `ixixixixix`,`iyiyiyiyiy` in a 2D array can be accessed and changed using its two coordinates in square brackets:

- `variable valuename? set to array2D[ix][iy]value or expression?130valuename? = array2D[ix][iy]value or expression? # variable definition131var valuename? = array2D[ix][iy]value or expression?;132Dim valuename? = array2D(ix)(iy)value or expression? ' variable definition133var valuename? = array2D[ix][iy]value or expression?;134`
- `assign array2D[ix][iy]variableName? to 7value or expression?135array2D[ix][iy]variableName? = 7value or expression? # assignment136array2D[ix][iy]variableName? = 7value or expression?; // assignment137array2D(ix)(iy)variableName? = 7value or expression? ' assignment138array2D[ix][iy]variableName? = 7value or expression?; // assignment139`

#### Higher dimensional arrays

For a 3D array, you can, for example, define:

- `variable array3Dname? set to new List<of List<of List<of Float>>>()value or expression?140array3Dname? = list[list[list[float]]]()value or expression? # variable definition141var array3Dname? = new List<List<List<double>>>()value or expression?;142Dim array3Dname? = New List(Of List(Of List(Of Double)))()value or expression? ' variable definition143var array3Dname? = new List<List<List<double>>>()value or expression?;144`

and refer to a cell using three indexes in square brackets.

### Procedure methods on a `ListlistListListList`

Where an argument provides a new value for an item in a List, that value must be of the same type as defined for the List's items.

procedure method | arguments | action
--- | --- | ---
append | value of `ListlistListListList` item's type | the item is added to the end of the List
appendList | `ListlistListListList` | the argument List is added to the end of the List
initialise | `IntintintIntegerint`, value of `ListlistListListList` item's type | specify the number (> 0) of items in the List, and an initial value for every item. May be called at any time to redefine the List's size and initial values.
insert | `IntintintIntegerint`, value of `ListlistListListList` item's type | the item is inserted at the index given. If the index is negative it is counted from the end If the index is greater than the list's length, the item is inserted at the end
prepend | value of `ListlistListListList` item's type | the item is is added to the start of the List
prependList | `ListlistListListList` | the argument List is added to the start of the List
removeAll | value of `ListlistListListList` item's type | delete all items equal to the given item
removeAt | `IntintintIntegerint` | delete the item at the argument index
removeFirst | value of `ListlistListListList` item's type | delete the first item equal to the given value

### Function dot methods on a `ListlistListListList`

function dot method | arguments | return type | returns
--- | --- | --- | ---
asSet | (none) | `HashSetHashSetHashSetHashSetHashSet` | a new Set containing all the unique items in the List
contains | value | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the List contains the specified item – `falseFalsefalseFalsefalse` otherwise
equals | `ListlistListListList` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if list and argument are identical – `falseFalsefalseFalsefalse` otherwise
filter | `lambdalambdalambdalambdalambda` | `ListlistListListList` | a new List obtained from applying a lambda to the input List see filter  in HoFs 
head | (none) | `ListlistListListList` item's type | the first item of the List (i.e. index = 0, which must exist)
indexOf | value of `ListlistListListList` item's type | `IntintintIntegerint` | the index of the first occurrence of the argument value in the List, or -1 if no match is found
join | `List<of String>list[str]List<string>List(Of String)List<String>` | `StringstrstringStringString` | a single String that joins all the items in the list, with the specified String (which can be empty) inserted between the items
length | (none) | `IntintintIntegerint` | the number of items in the List
map | `lambdalambdalambdalambdalambda` | `ListlistListListList` | a new List obtained from applying a lambda to the input List see map  in HoFs 
maxBy | `lambdalambdalambdalambdalambda` | `ListlistListListList` item's type | the list item corresponding to the maximum of the values returned by a lambda see maxBy  in HoFs 
minBy | `lambdalambdalambdalambdalambda` | `ListlistListListList` item's type | the list item corresponding to the minimum of the values returned by a lambda see minBy  in HoFs 
notEqualTo | `ListlistListListList` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if list and argument differ l – `falseFalsefalseFalsefalse` otherwise
orderBy | `lambdalambdalambdalambdalambda` | `ListlistListListList` | a new list with the items ordered according to the value returned by a lambda
reduce | item of `ListlistListListList` item's type, `lambdalambdalambdalambdalambda` | return type of lambda | the final value obtained by applying a lambda cumulatively to each item in the input List taking account of the first argument as an initial (and default return) value see reduce  in HoFs 
subList | `IntintintIntegerint`, `IntintintIntegerint` | `ListlistListListList` | a new list that contains the items specified by the two positive integers (m,n) where m indexes the first item of the list required (counting from 0) and n indexes the item after the last item required (exclusive index) if m ≥ n the result is the empty list
tail | (none) | `ListlistListListList` item's type | all items except the first item in the List (i.e. index = 1..n, which must exist)
toString | (none) | `StringstrstringStringString` | a String that is a comma+space-separated list of the List's items, enclosed in square brackets
withAppend | item of `ListlistListListList` item's type | `ListlistListListList` | a new List lengthened with the item added after the end
withAppendList | `ListlistListListList` of same type | `ListlistListListList` | a new List lengthened by appending the given List
withInsert | `IntintintIntegerint`, value of `ListlistListListList` item's type | `ListlistListListList` | a new List with the item inserted after the item at the given index position
withPrepend | value of `ListlistListListList` item's type | `ListlistListListList` | a new List lengthened with the item added before the beginning
withPrependList | `ListlistListListList` of same type | `ListlistListListList` | a new List lengthened by prepending the given List
withRemoveAll | value of `ListlistListListList` item's type | `ListlistListListList` | a new List with items equal to the given item removed
withRemoveAt | `IntintintIntegerint` | `ListlistListListList` | a new List with the item at the given index removed
withRemoveFirst | value of `ListlistListListList` item's type | `ListlistListListList` | a new List with the first item equal to the given item removed
withSet | `IntintintIntegerint`, value of `ListlistListListList` item's type | `ListlistListListList` | a new List with the item replacing that at the given index

## Dictionary

A `DictionaryDictionaryDictionaryDictionaryDictionary` is like a List whose items are pairs but, instead of having a numeric index, each item has a key plus an associated value, i.e. a Dictionary is a set of key:value pairs.

The key's type must be one of `IntintintIntegerint`, `FloatfloatdoubleDoubledouble`, `StringstrstringStringString` or `BooleanboolboolBooleanboolean`. The values may be of any type. The types of both keys and values are fixed when the Dictionary is created.

You refer to a dictionary item using one of its (unique) keys, e.g. in a `Dictionary<of String, Int>Dictionary[str, int]Dictionary<string, int>Dictionary(Of String, Integer)Dictionary<String, int>` named `birthdaysbirthdaysbirthdaysbirthdaysbirthdays` whose keys are names and whose values are birth year, you might refer to `birthdays["Shakespeare"]birthdays["Shakespeare"]birthdays["Shakespeare"]birthdays["Shakespeare"]birthdays["Shakespeare"]` and retrieve the value 1564.

#### Example using `DictionaryDictionaryDictionaryDictionaryDictionary`

● Define a constant Dictionary for reference throughout the program:

Procedure greekLetters sets up the key:value pairs, procedure printD shows how a procedure can use the Dictionary, and function getDItem retrieves a value given a key.

+main 290 variable dL name? set to new Dictionary<of String, Int>()value or expression?291 variable dLRef name? set to new AsRef<of Dictionary<of String, Int>>(dL)value or expression?292 call greekLetters procedureName?(dLRef arguments?)293 assign dL variableName? to dLRef.value()value or expression?294 print(dL arguments?)295 call printD procedureName?(dL arguments?)296 print(getDItem(dL, "alpha")arguments?)297 end main
+def main() -> None: 298 dL name? = Dictionary[str, int]()value or expression? # variable definition 299 dLRef name? = AsRef[Dictionary[str, int]](dL)value or expression? # variable definition 300 greekLetters procedureName?(dLRef arguments?) # procedure call 301 dL variableName? = dLRef.value()value or expression? # assignment 302 print(dL arguments?)303 printD procedureName?(dL arguments?) # procedure call 304 print(getDItem(dL, "alpha")arguments?)305 # end main
+static void main() { 306 var dL name? = new Dictionary<string, int>()value or expression?;307 var dLRef name? = new AsRef<Dictionary<string, int>>(dL)value or expression?;308 greekLetters procedureName?(dLRef arguments?); // procedure call 309 dL variableName? = dLRef.value()value or expression?; // assignment 310 Console.WriteLine(dL arguments?); // print statement 311 printD procedureName?(dL arguments?); // procedure call 312 Console.WriteLine(getDItem(dL, "alpha")arguments?); // print statement 313 } // end main
+Sub main() 314 Dim dL name? = New Dictionary(Of String, Integer)()value or expression? ' variable definition 315 Dim dLRef name? = New AsRef(Of Dictionary(Of String, Integer))(dL)value or expression? ' variable definition 316 greekLetters procedureName?(dLRef arguments?) ' procedure call 317 dL variableName? = dLRef.value()value or expression? ' assignment 318 Console.WriteLine(dL arguments?) ' print statement 319 printD procedureName?(dL arguments?) ' procedure call 320 Console.WriteLine(getDItem(dL, "alpha")arguments?) ' print statement 321 End Sub
+static void main() { 322 var dL name? = new Dictionary<String, int>()value or expression?;323 var dLRef name? = new AsRef<Dictionary<String, int>>(dL)value or expression?;324 greekLetters procedureName?(dLRef arguments?); // procedure call 325 dL variableName? = dLRef.value()value or expression?; // assignment 326 System.out.println(dL arguments?); // print statement 327 printD procedureName?(dL arguments?); // procedure call 328 System.out.println(getDItem(dL, "alpha")arguments?); // print statement 329 } // end main

● Define a constant Dictionary for reference throughout the program in a way suitable for Functional programming, by using the HoF `reducereducereducereducereduce` in a function that creates the Dictionary from a List of key:value pairs as Tuples:

+main 330 variable di name? set to createDictionary([("alpha", 1), ("beta", 2), ("gamma", 3)])value or expression?331 print(di["beta"]arguments?)332 end main
+def main() -> None: 333 di name? = createDictionary([("alpha", 1), ("beta", 2), ("gamma", 3)])value or expression? # variable definition 334 print(di["beta"]arguments?)335 # end main
+static void main() { 336 var di name? = createDictionary(new [] {("alpha", 1), ("beta", 2), ("gamma", 3)})value or expression?;337 Console.WriteLine(di["beta"]arguments?); // print statement 338 } // end main
+Sub main() 339 Dim di name? = createDictionary({("alpha", 1), ("beta", 2), ("gamma", 3)})value or expression? ' variable definition 340 Console.WriteLine(di("beta")arguments?) ' print statement 341 End Sub
+static void main() { 342 var di name? = createDictionary(list(("alpha", 1), ("beta", 2), ("gamma", 3)))value or expression?;343 System.out.println(di["beta"]arguments?); // print statement 344 } // end main

### Procedure method on a `DictionaryDictionaryDictionaryDictionaryDictionary`

procedure method | argument types | action
--- | --- | ---
removeAt | key's type | delete the key:pair at the given key (if it exists)

### Function dot methods on a `DictionaryDictionaryDictionaryDictionaryDictionary`

function dot method | argument types | return type | returns
--- | --- | --- | ---
equals | `DictionaryDictionaryDictionaryDictionaryDictionary` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if dictionary and argument are identical – `falseFalsefalseFalsefalse` otherwise
hasKey | item of Dictionary key's type | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the Dictionary contains the given key – `falseFalsefalseFalsefalse` otherwise
keys | (none) | `ListlistListListList` | a List containing the keys
notEqualTo | `DictionaryDictionaryDictionaryDictionaryDictionary` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if dictionary and argument differ – `falseFalsefalseFalsefalse` otherwise
toString | (none) | `StringstrstringStringString` | a string that is a comma+space-separated list of the Dictionary's key:value pairs, enclosed in square brackets
values | (none) | `ListlistListListList` | a List containing the values
withSet | item of Dictionary key's type, item of Dictionary value's type | `DictionaryDictionaryDictionaryDictionaryDictionary` | a new Dictionary with the value replacing what was at the specified key
withRemoveAt | item of Dictionary key's type | `DictionaryDictionaryDictionaryDictionaryDictionary` | a new Dictionary with the key:value pair removed from the specified key

## HashSet

A `HashSetHashSetHashSetHashSetHashSet` (also referred to merely as a Set) is a standard data structure containing Set members, that works somewhat like a `ListlistListListList` with two important differences:

- The value of a `HashSetHashSetHashSetHashSetHashSet` member may appear only once: if a member being added to a Set has the same value as an existing member in the Set then the Set remains the same as before.
- The values in a `HashSetHashSetHashSetHashSetHashSet` are not indexed: two Sets with the same contents but defined in a different sequence, can still be compared correctly with methods equals and notEqualTo.
- There are no methods that modify an existing Set, but several (e.g. add and remove) return a new `HashSetHashSetHashSetHashSetHashSet` that is based on the original Set or Sets with specified differences.

This enables a Set to work like a mathematical set so that it is possible to perform standard set operations such as union and intersection.

When creating a `HashSetHashSetHashSetHashSetHashSet`, the type of its members must be specified in the form `HashSet<of String>HashSet[str]HashSet<string>HashSet(Of String)HashSet<String>`

You can add members: either individually with add, or many with addFromList. And you can create a new `HashSetHashSetHashSetHashSetHashSet` from an existing `ListlistListListList` by calling asSet on it.

Example of creating a Set from a literal List and changing its content:

variable st name? set to new HashSet<of Int>()value or expression?345 st name? = HashSet[int]()value or expression? # variable definition 346 var st name? = new HashSet<int>()value or expression?;347 Dim st name? = New HashSet(Of Integer)()value or expression? ' variable definition 348 var st name? = new HashSet<int>()value or expression?;349 | ⟶ ⟶ ⟶ ⟶ | 3 2 2 [5, 7]

### Function dot methods on a `HashSetHashSetHashSetHashSetHashSet`

function dot method | argument types | return type | returns
--- | --- | --- | ---
add | value (of `HashSetHashSetHashSetHashSetHashSet` members' type) | `HashSetHashSetHashSetHashSetHashSet` | a new Set extended with the item, provided it differs from all of the Set's current members
addFromList | `ListlistListListList` | `HashSetHashSetHashSetHashSetHashSet` | a new Set extended with those items from the List that are not already in the Set
asList | (none) | `ListlistListListList` | a List containing the Set's members as List items
contains | value (of `HashSetHashSetHashSetHashSetHashSet` members' type) | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the Set contains the item – `falseFalsefalseFalsefalse` otherwise
difference | `HashSetHashSetHashSetHashSetHashSet` | `HashSetHashSetHashSetHashSetHashSet` | a Set containing those members of the Set that do not occur in the argument Set
equals | `HashSetHashSetHashSetHashSetHashSet` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if Set and argument Set contain identical values – `falseFalsefalseFalsefalse` otherwise
notEqualTo | `HashSetHashSetHashSetHashSetHashSet` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if Set and argument Set differ in their values – `falseFalsefalseFalsefalse` otherwise
intersection | `HashSetHashSetHashSetHashSetHashSet` | `HashSetHashSetHashSetHashSetHashSet` | a HashSet containing those members common to both the Set and the argument Set
isDisjointFrom | `HashSetHashSetHashSetHashSetHashSet` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the Set has no items in common with the argument Set – `falseFalsefalseFalsefalse` otherwise
isSubsetOf | `HashSetHashSetHashSetHashSetHashSet` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if all the Set's items are also in the argument Set – `falseFalsefalseFalsefalse` otherwise
isSupersetOf | `HashSetHashSetHashSetHashSetHashSet` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the Set contains all the items that are in the argument Set – `falseFalsefalseFalsefalse` otherwise
length | (none) | `IntintintIntegerint` | the number of members of the Set
remove | value (of `HashSetHashSetHashSetHashSetHashSet` members' type) | `HashSetHashSetHashSetHashSetHashSet` | a new Set with the argument item removed (if present)
toString | (none) | `StringstrstringStringString` | a string that is a comma+space-separated list of the Set's members, enclosed in brackets
union | `HashSetHashSetHashSetHashSetHashSet` | `HashSetHashSetHashSetHashSetHashSet` | a Set containing all the unique members of the Set and the argument Set (i.e. no duplicates)

## Stack and Queue

- `StackStackStackStackStack` and `QueueQueueQueueQueueQueue` are similar data structures except that `StackStackStackStackStack` is 'LIFO' (last in, first out), while `QueueQueueQueueQueueQueue` is FIFO (first in, first out). The names of the methods for adding and removing items are different, but there are also common methods.
- Both a `StackStackStackStackStack` and a `QueueQueueQueueQueueQueue` are defined with the type of the items that they can contain, similarly to how `ListlistListListList` has a specified item type, though with different syntax. The type is specified in the form shown below e.g. `Stack<of String>Stack[str]Stack<string>Stack(Of String)Stack<String>`, `Queue<of Int>Queue[int]Queue<int>Queue(Of Integer)Queue<int>`.
- Both `StackStackStackStackStack`and`QueueQueueQueueQueueQueue` are dynamically extensible, like a `ListlistListListList`. There is no need (or means) to specify a size limit as they can continue to expand (eventually until the computer's memory limit is reached).
- The same syntax is used to specify the type if you want to pass a `StackStackStackStackStack` or `QueueQueueQueueQueueQueue` into a function, or specify it as the return type.
- `StackStackStackStackStack` and `QueueQueueQueueQueueQueue` have two methods in common: length and peek. peek returns the next item to be removed, without actually removing it.
- The methods for adding and removing an item are different for `StackStackStackStackStack` and `QueueQueueQueueQueueQueue`, as shown here:

### Function dot methods on a `StackStackStackStackStack`

function dot method | argument types | return types | returns
--- | --- | --- | ---
equals | `StackStackStackStackStack` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if stack and argument are identical – `falseFalsefalseFalsefalse` otherwise
notEqualTo | `StackStackStackStackStack` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if stack and argument differ – `falseFalsefalseFalsefalse` otherwise
push | value (of `StackStackStackStackStack` item's type) | `StackStackStackStackStack` | the Stack with the value added to its top
pop | (none) | `StackStackStackStackStack` item, `StackStackStackStackStack` | the topmost item of the Stack, and the Stack with the item removed
peek | (none) | `StackStackStackStackStack` item | the topmost item on the Stack (without altering the Stack)
length | (none) | `IntintintIntegerint` | the number of items in the Stack
toString | (none) | `StringstrstringStringString` | a String that is a comma+space-separated list of the Stack's items, enclosed in square brackets, the last item pushed being the first in the String

### Function dot methods on a `QueueQueueQueueQueueQueue`

function dot method | argument types | return types | returns
--- | --- | --- | ---
equals | `QueueQueueQueueQueueQueue` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if queue and argument are identical – `falseFalsefalseFalsefalse` otherwise
notEqualTo | `QueueQueueQueueQueueQueue` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if queue and argument differ – `falseFalsefalseFalsefalse` otherwise
enqueue | value (of `QueueQueueQueueQueueQueue` item's type) | `QueueQueueQueueQueueQueue` | the Queue with the item added to the end of the Queue
dequeue | (none) | `QueueQueueQueueQueueQueue` item, `QueueQueueQueueQueueQueue` | the next item in the Queue, and the Queue with the item removed
peek | (none) | `QueueQueueQueueQueueQueue` item | the next item in the Queue (without altering the Queue)
length | (none) | `IntintintIntegerint` | the number of items in the Queue
toString | (none) | `StringstrstringStringString` | a String that is a comma+space-separated list of the Queue's items, enclosed in square brackets, the first item enqueued being the first in the String

#### Examples using `StackStackStackStackStack` and `QueueQueueQueueQueueQueue`

● Results of push and pop on strings in a `StackStackStackStackStack`:

+main 350 variable sk name? set to new Stack<of String>()value or expression?351 print(sk.length()arguments?)352 assign sk variableName? to sk.push("apple")value or expression?353 assign sk variableName? to sk.push("banana")value or expression?354 assign sk variableName? to sk.push("cherry")value or expression?355 print(sk.length()arguments?)356 print(sk arguments?)357 print(sk.peek()arguments?)358 print(sk.pop()arguments?)359 print(sk arguments?)360 print(sk.pop().item_0 arguments?)361 print(sk arguments?)362 assign sk variableName? to sk.pop().item_1 value or expression?363 print(sk arguments?)364 end main +def main() -> None: 365 sk name? = Stack[str]()value or expression? # variable definition 366 print(sk.length()arguments?)367 sk variableName? = sk.push("apple")value or expression? # assignment 368 sk variableName? = sk.push("banana")value or expression? # assignment 369 sk variableName? = sk.push("cherry")value or expression? # assignment 370 print(sk.length()arguments?)371 print(sk arguments?)372 print(sk.peek()arguments?)373 print(sk.pop()arguments?)374 print(sk arguments?)375 print(sk.pop().item_0 arguments?)376 print(sk arguments?)377 sk variableName? = sk.pop().item_1 value or expression? # assignment 378 print(sk arguments?)379 # end main +static void main() { 380 var sk name? = new Stack<string>()value or expression?;381 Console.WriteLine(sk.length()arguments?); // print statement 382 sk variableName? = sk.push("apple")value or expression?; // assignment 383 sk variableName? = sk.push("banana")value or expression?; // assignment 384 sk variableName? = sk.push("cherry")value or expression?; // assignment 385 Console.WriteLine(sk.length()arguments?); // print statement 386 Console.WriteLine(sk arguments?); // print statement 387 Console.WriteLine(sk.peek()arguments?); // print statement 388 Console.WriteLine(sk.pop()arguments?); // print statement 389 Console.WriteLine(sk arguments?); // print statement 390 Console.WriteLine(sk.pop().item_0 arguments?); // print statement 391 Console.WriteLine(sk arguments?); // print statement 392 sk variableName? = sk.pop().item_1 value or expression?; // assignment 393 Console.WriteLine(sk arguments?); // print statement 394 } // end main +Sub main() 395 Dim sk name? = New Stack(Of String)()value or expression? ' variable definition 396 Console.WriteLine(sk.length()arguments?) ' print statement 397 sk variableName? = sk.push("apple")value or expression? ' assignment 398 sk variableName? = sk.push("banana")value or expression? ' assignment 399 sk variableName? = sk.push("cherry")value or expression? ' assignment 400 Console.WriteLine(sk.length()arguments?) ' print statement 401 Console.WriteLine(sk arguments?) ' print statement 402 Console.WriteLine(sk.peek()arguments?) ' print statement 403 Console.WriteLine(sk.pop()arguments?) ' print statement 404 Console.WriteLine(sk arguments?) ' print statement 405 Console.WriteLine(sk.pop().item_0 arguments?) ' print statement 406 Console.WriteLine(sk arguments?) ' print statement 407 sk variableName? = sk.pop().item_1 value or expression? ' assignment 408 Console.WriteLine(sk arguments?) ' print statement 409 End Sub +static void main() { 410 var sk name? = new Stack<String>()value or expression?;411 System.out.println(sk.length()arguments?); // print statement 412 sk variableName? = sk.push("apple")value or expression?; // assignment 413 sk variableName? = sk.push("banana")value or expression?; // assignment 414 sk variableName? = sk.push("cherry")value or expression?; // assignment 415 System.out.println(sk.length()arguments?); // print statement 416 System.out.println(sk arguments?); // print statement 417 System.out.println(sk.peek()arguments?); // print statement 418 System.out.println(sk.pop()arguments?); // print statement 419 System.out.println(sk arguments?); // print statement 420 System.out.println(sk.pop().item_0 arguments?); // print statement 421 System.out.println(sk arguments?); // print statement 422 sk variableName? = sk.pop().item_1 value or expression?; // assignment 423 System.out.println(sk arguments?); // print statement 424 } // end main | ⟶ ⟶ ⟶ ⟶ ⟶ ⟶ ⟶ ⟶ ⟶ | 0 3 [cherry, banana, apple] cherry (cherry, [banana, apple]) [cherry, banana, apple] cherry [cherry, banana, apple] [banana, apple]

● Results of enqueue and dequeue on strings in a `QueueQueueQueueQueueQueue`:

+main 425 variable qu name? set to new Queue<of String>()value or expression?426 print(qu.length()arguments?)427 assign qu variableName? to qu.enqueue("apple")value or expression?428 assign qu variableName? to qu.enqueue("banana")value or expression?429 assign qu variableName? to qu.enqueue("cherry")value or expression?430 print(qu.length()arguments?)431 print(qu arguments?)432 print(qu.peek()arguments?)433 print(qu.dequeue()arguments?)434 print(qu arguments?)435 print(qu.dequeue().item_0 arguments?)436 print(qu arguments?)437 assign qu variableName? to qu.dequeue().item_1 value or expression?438 print(qu arguments?)439 end main +def main() -> None: 440 qu name? = Queue[str]()value or expression? # variable definition 441 print(qu.length()arguments?)442 qu variableName? = qu.enqueue("apple")value or expression? # assignment 443 qu variableName? = qu.enqueue("banana")value or expression? # assignment 444 qu variableName? = qu.enqueue("cherry")value or expression? # assignment 445 print(qu.length()arguments?)446 print(qu arguments?)447 print(qu.peek()arguments?)448 print(qu.dequeue()arguments?)449 print(qu arguments?)450 print(qu.dequeue().item_0 arguments?)451 print(qu arguments?)452 qu variableName? = qu.dequeue().item_1 value or expression? # assignment 453 print(qu arguments?)454 # end main +static void main() { 455 var qu name? = new Queue<string>()value or expression?;456 Console.WriteLine(qu.length()arguments?); // print statement 457 qu variableName? = qu.enqueue("apple")value or expression?; // assignment 458 qu variableName? = qu.enqueue("banana")value or expression?; // assignment 459 qu variableName? = qu.enqueue("cherry")value or expression?; // assignment 460 Console.WriteLine(qu.length()arguments?); // print statement 461 Console.WriteLine(qu arguments?); // print statement 462 Console.WriteLine(qu.peek()arguments?); // print statement 463 Console.WriteLine(qu.dequeue()arguments?); // print statement 464 Console.WriteLine(qu arguments?); // print statement 465 Console.WriteLine(qu.dequeue().item_0 arguments?); // print statement 466 Console.WriteLine(qu arguments?); // print statement 467 qu variableName? = qu.dequeue().item_1 value or expression?; // assignment 468 Console.WriteLine(qu arguments?); // print statement 469 } // end main +Sub main() 470 Dim qu name? = New Queue(Of String)()value or expression? ' variable definition 471 Console.WriteLine(qu.length()arguments?) ' print statement 472 qu variableName? = qu.enqueue("apple")value or expression? ' assignment 473 qu variableName? = qu.enqueue("banana")value or expression? ' assignment 474 qu variableName? = qu.enqueue("cherry")value or expression? ' assignment 475 Console.WriteLine(qu.length()arguments?) ' print statement 476 Console.WriteLine(qu arguments?) ' print statement 477 Console.WriteLine(qu.peek()arguments?) ' print statement 478 Console.WriteLine(qu.dequeue()arguments?) ' print statement 479 Console.WriteLine(qu arguments?) ' print statement 480 Console.WriteLine(qu.dequeue().item_0 arguments?) ' print statement 481 Console.WriteLine(qu arguments?) ' print statement 482 qu variableName? = qu.dequeue().item_1 value or expression? ' assignment 483 Console.WriteLine(qu arguments?) ' print statement 484 End Sub +static void main() { 485 var qu name? = new Queue<String>()value or expression?;486 System.out.println(qu.length()arguments?); // print statement 487 qu variableName? = qu.enqueue("apple")value or expression?; // assignment 488 qu variableName? = qu.enqueue("banana")value or expression?; // assignment 489 qu variableName? = qu.enqueue("cherry")value or expression?; // assignment 490 System.out.println(qu.length()arguments?); // print statement 491 System.out.println(qu arguments?); // print statement 492 System.out.println(qu.peek()arguments?); // print statement 493 System.out.println(qu.dequeue()arguments?); // print statement 494 System.out.println(qu arguments?); // print statement 495 System.out.println(qu.dequeue().item_0 arguments?); // print statement 496 System.out.println(qu arguments?); // print statement 497 qu variableName? = qu.dequeue().item_1 value or expression?; // assignment 498 System.out.println(qu arguments?); // print statement 499 } // end main | ⟶ ⟶ ⟶ ⟶ ⟶ ⟶ ⟶ ⟶ ⟶ | 0 3 [apple, banana, cherry] apple (apple, [banana, cherry]) [apple, banana, cherry] apple [apple, banana, cherry] [banana, cherry]

## Tuple

A Tuple is not a value or data structure type. Rather, it is a small collection of values of differing types held together and referenced by a single identifier.

It may be considered a lightweight alternative to defining a Class for some specific purpose.

The items in a Tuple may be literal or named values.

Tuples are referred to as 2-Tuples, 3-Tuples, etc. according to the number of values they hold.

An item within a Tuple may be another Tuple, giving nested Tuples.

A function may return a Tuple.

A Tuple differs from a List in that:

- A Tuple may hold items of different types.
- A Tuple is immutable: you may read, but not modify, the values it contains. Once defined, Tuples are effectively read-only.
  Nor, unlike a `ListlistListListList`, can you copy a Tuple from an existing one with specified differences except by referencing each of its items (see below).

Common uses include:

- Holding a pair of x,y coordinates (each of type `FloatfloatdoubleDoubledouble`) as a single unit.
- Allowing a function to pass back a result comprised of both a message in a `StringstrstringStringString` and a `BooleanboolboolBooleanboolean` indicating whether the operation was successful.
- Returning both an updated copy of a data structure and the value of an item from it, e.g. from method pop on a Stack .

### Defining a Tuple

A new Tuple is defined by a list of items separated by commas and enclosed in round brackets:

`variable pointname? set to (3, 4)value or expression?145pointname? = (3, 4)value or expression? # variable definition146var pointname? = (3, 4)value or expression?;147Dim pointname? = (3, 4)value or expression? ' variable definition148var pointname? = (3, 4)value or expression?;149` `variable tname? set to (3, "apple", true)value or expression?150tname? = (3, "apple", True)value or expression? # variable definition151var tname? = (3, "apple", true)value or expression?;152Dim tname? = (3, "apple", True)value or expression? ' variable definition153var tname? = (3, "apple", true)value or expression?;154`

### Accessing items in a Tuple

The items in a Tuple may be individually addressed by a dot reference and its special properties `item_item_item_item_item_`N, thus:

variable t name? set to (3, "apple", true)value or expression?500 t name? = (3, "apple", True)value or expression? # variable definition 501 var t name? = (3, "apple", true)value or expression?;502 Dim t name? = (3, "apple", True)value or expression? ' variable definition 503 var t name? = (3, "apple", true)value or expression?;504 | ⟶ ⟶ ⟶ ⟶ | (3, apple, true) 3 apple true

And where p1 and p2 represent points each with 2-Tuples containing two `FloatfloatdoubleDoubledouble` values, this function returns the distance between them:

+function distanceBetween name?(p1 as (Float, Float), p2 as (Float, Float)parameter definitions?) returns Float Type? 505 return sqrt(pow(p2.item_0 - p1.item_0, 2) + pow(p2.item_1 - p1.item_1, 2))value or expression?506 end function
+def distanceBetween name?(p1: tuple[float, float], p2: tuple[float, float]parameter definitions?) -> float Type?: # function 507 return sqrt(pow(p2.item_0 - p1.item_0, 2) + pow(p2.item_1 - p1.item_1, 2))value or expression?508 # end function
+static double Type? distanceBetween name?((double, double) p1, (double, double) p2 parameter definitions?) { // function 509 return sqrt(pow(p2.item_0 - p1.item_0, 2) + pow(p2.item_1 - p1.item_1, 2))value or expression?;510 } // end function
+Function distanceBetween name?(p1 As (Double, Double), p2 As (Double, Double)parameter definitions?) As Double Type? 511 Return sqrt(pow(p2.item_0 - p1.item_0, 2) + pow(p2.item_1 - p1.item_1, 2))value or expression?512 End Function
+static double Type? distanceBetween name?((double, double) p1, (double, double) p2 parameter definitions?) { // function 513 return sqrt(pow(p2.item_0 - p1.item_0, 2) + pow(p2.item_1 - p1.item_1, 2))value or expression?;514 } // end function

Note that the appropriate `item_item_item_item_item_`Ns will be listed in the Editor's drop-down menu options for the referenced Tuple.

### Function dot methods on a Tuple

function dot methods | argument types | return type | returns
--- | --- | --- | ---
equals | Tuple | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if the types, item values and order all equal those of the argument, – `falseFalsefalseFalsefalse` otherwise
notEqualTo | Tuple | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` if any of the types, item values and order differ from those of the argument, – `falseFalsefalseFalsefalse` otherwise
toString | (none) | `StringstrstringStringString` | String containing Tuple's items surrounded by brackets

# Graphic types

## Block graphics

Block graphics provides a simple way to create low resolution graphics, ideal for simple but engaging games for example.

The graphics are defined and displayed on a grid that is 40 blocks wide by 30 blocks high.

Each block is be rendered as a solid colour.

An example of block graphics to produce a rapidly changing pattern of coloured blocks:

+main 515 variable grid name? set to createBlockGraphics(white)value or expression?516 +while true condition? 517 variable x name? set to randint(0, 39)value or expression?518 variable y name? set to randint(0, 29)value or expression?519 variable colour name? set to randint(0, white - 1)value or expression?520 assign grid[x][y]variableName? to colour value or expression?521 call displayBlocks procedureName?(grid arguments?)522 end while end main
+def main() -> None: 523 grid name? = createBlockGraphics(white)value or expression? # variable definition 524 +while True condition?: 525 x name? = randint(0, 39)value or expression? # variable definition 526 y name? = randint(0, 29)value or expression? # variable definition 527 colour name? = randint(0, white - 1)value or expression? # variable definition 528 grid[x][y]variableName? = colour value or expression? # assignment 529 displayBlocks procedureName?(grid arguments?) # procedure call 530 # end while # end main
+static void main() { 531 var grid name? = createBlockGraphics(white)value or expression?;532 +while (true condition?) { 533 var x name? = randint(0, 39)value or expression?;534 var y name? = randint(0, 29)value or expression?;535 var colour name? = randint(0, white - 1)value or expression?;536 grid[x][y]variableName? = colour value or expression?; // assignment 537 displayBlocks procedureName?(grid arguments?); // procedure call 538 } // end while } // end main
+Sub main() 539 Dim grid name? = createBlockGraphics(white)value or expression? ' variable definition 540 +While True condition? 541 Dim x name? = randint(0, 39)value or expression? ' variable definition 542 Dim y name? = randint(0, 29)value or expression? ' variable definition 543 Dim colour name? = randint(0, white - 1)value or expression? ' variable definition 544 grid(x)(y)variableName? = colour value or expression? ' assignment 545 displayBlocks procedureName?(grid arguments?) ' procedure call 546 End While End Sub
+static void main() { 547 var grid name? = createBlockGraphics(white)value or expression?;548 +while (true condition?) { 549 var x name? = randint(0, 39)value or expression?;550 var y name? = randint(0, 29)value or expression?;551 var colour name? = randint(0, white - 1)value or expression?;552 grid[x][y]variableName? = colour value or expression?; // assignment 553 displayBlocks procedureName?(grid arguments?); // procedure call 554 } // end while } // end main

#### Notes

- The definition of the grid is made using the system method createBlockGraphics which initialises a `List<of List<of Int>>list[list[int]]List<List<int>>List(Of List(Of Integer))List<List<int>>` structure containing 40 columns × 30 rows.
- Each cell of the grid is referenced by integers x,y where x is in [0..39] and y is in [0..29].
- x,y is 0,0 at the top left cell of the grid, positive x to the right, positive y downwards.
- You may create multiple such structures holding different patterns of blocks, and switch between them just by passing the required one as the argument to method displayBlocks.
- Any `List<of List<of Int>>list[list[int]]List<List<int>>List(Of List(Of Integer))List<List<int>>` structure of the same 40 × 30 dimensions can be the argument to method displayBlocks.
- A colour is specified as an `IntintintIntegerint`, as described under Colours .

## Turtle graphics

Turtle graphics are implemented with output to the IDE's display pane, i.e. the 'paper' on which the turtle draws.

The area is 200 turtle units wide by 150 turtle units high, and both integer and floating point values of turtle units can be used. If a turtle is placed or moved outside the 200 × 150 area boundary, it will not cause an error, but the turtle and any lines drawn outside the boundary will not be visible.

The origin for turtle units (0,0) is at the centre of the area: positive x rightwards, positive y upwards. So the top left corner of the display is at (-100,75).

A new turtle's default starting position is at (0,0) facing upwards (`headingheadingheadingheadingheading` is 0), from where a move will be in the y direction.

You can move and turn a turtle, causing lines to be drawn, whether or not the turtle is showing.

### Procedure methods on a Turtle

procedure method | argument types | action
--- | --- | ---
clearAndReset | (none) | clears the turtle display and moves the turtle to its starting position and heading
hide | (none) | makes the turtle invisible in the display
move | `IntintintIntegerint` or `FloatfloatdoubleDoubledouble` | moves the turtle the specified number of turtle units in the direction of its heading or, if negative, in the opposite direction
moveTo | `IntintintIntegerint` or `FloatfloatdoubleDoubledouble`, `IntintintIntegerint` or `FloatfloatdoubleDoubledouble` | moves the turtle to the specified x,y position, drawing its path if its pen is down
penColour | `IntintintIntegerint` | changes the colour  of its path in the display to the literal or named value specified
penDown | (none) | makes the turtle's subsequent moves leave a trace of its path in the display
penUp | (none) | makes the turtle's subsequent moves leave no trace of its path in the display
penWidth | `IntintintIntegerint` or `FloatfloatdoubleDoubledouble` | changes the width of the line tracing the turtle's path in the display default (and minimum) is 1
placeAt | `IntintintIntegerint` or `FloatfloatdoubleDoubledouble`, `IntintintIntegerint` or `FloatfloatdoubleDoubledouble` | places or repositions the turtle at the x,y position specified without drawing a path
show | (none) | makes the turtle visible in the display as a green blob marked with a black radius that indicates its heading
turn | `IntintintIntegerint` or `FloatfloatdoubleDoubledouble` | turns the turtle through the specified number of degrees clockwise or, if negative, anticlockwise
turnToHeading | `IntintintIntegerint` or `FloatfloatdoubleDoubledouble` | turns the turtle to face in the direction specified in degrees where 0 is upward and increasing values go clockwise from there

### Properties of a Turtle

The current location and heading of the turtle may be read using the properties `xxxxx`, `yyyyy`, and `headingheadingheadingheadingheading`.

Property |
--- | ---
name | type | description | default
`headingheadingheadingheadingheading` | `FloatfloatdoubleDoubledouble` | the direction in which the turtle is pointing in degrees clockwise from North | 0.0 degrees, i.e. upward in the display
`xxxxx`, `yyyyy` | `FloatfloatdoubleDoubledouble`, `FloatfloatdoubleDoubledouble` | the x,y coordinates of the turtle's current position | 0.0, 0.0

#### Examples using turtle graphics

● To draw a square:

+main 555 variable t name? set to new Turtle()value or expression?556 call t.placeAt procedureName?(-75, 50 arguments?)557 call t.show procedureName?(arguments?)558 +for i item? in range(1, 5)source? 559 call t.turn procedureName?(90 arguments?)560 call t.move procedureName?(80 arguments?)561 call sleep procedureName?(0.5 arguments?)562 end for end main
+def main() -> None: 563 t name? = Turtle()value or expression? # variable definition 564 t.placeAt procedureName?(-75, 50 arguments?) # procedure call 565 t.show procedureName?(arguments?) # procedure call 566 +for i item? in range(1, 5)source?: 567 t.turn procedureName?(90 arguments?) # procedure call 568 t.move procedureName?(80 arguments?) # procedure call 569 sleep procedureName?(0.5 arguments?) # procedure call 570 # end for # end main
+static void main() { 571 var t name? = new Turtle()value or expression?;572 t.placeAt procedureName?(-75, 50 arguments?); // procedure call 573 t.show procedureName?(arguments?); // procedure call 574 +foreach (var i item? in range(1, 5)source?) { 575 t.turn procedureName?(90 arguments?); // procedure call 576 t.move procedureName?(80 arguments?); // procedure call 577 sleep procedureName?(0.5 arguments?); // procedure call 578 } // end foreach } // end main
+Sub main() 579 Dim t name? = New Turtle()value or expression? ' variable definition 580 t.placeAt procedureName?(-75, 50 arguments?) ' procedure call 581 t.show procedureName?(arguments?) ' procedure call 582 +For Each i item? In range(1, 5)source? 583 t.turn procedureName?(90 arguments?) ' procedure call 584 t.move procedureName?(80 arguments?) ' procedure call 585 sleep procedureName?(0.5 arguments?) ' procedure call 586 Next i End Sub
+static void main() { 587 var t name? = new Turtle()value or expression?;588 t.placeAt procedureName?(-75, 50 arguments?); // procedure call 589 t.show procedureName?(arguments?); // procedure call 590 +foreach (var i item? in range(1, 5)source?) { 591 t.turn procedureName?(90 arguments?); // procedure call 592 t.move procedureName?(80 arguments?); // procedure call 593 sleep procedureName?(0.5 arguments?); // procedure call 594 } // end foreach } // end main

● To draw a fractal snowflake, using a procedure and recursion:

+main 595 variable t name? set to new Turtle()value or expression?596 call t.placeAt procedureName?(-50, 30 arguments?)597 call t.turn procedureName?(90 arguments?)598 call t.show procedureName?(arguments?)599 +for i item? in range(1, 4)source? 600 call drawSide procedureName?(side, t arguments?)601 call t.turn procedureName?(120 arguments?)602 end for end main
+def main() -> None: 603 t name? = Turtle()value or expression? # variable definition 604 t.placeAt procedureName?(-50, 30 arguments?) # procedure call 605 t.turn procedureName?(90 arguments?) # procedure call 606 t.show procedureName?(arguments?) # procedure call 607 +for i item? in range(1, 4)source?: 608 drawSide procedureName?(side, t arguments?) # procedure call 609 t.turn procedureName?(120 arguments?) # procedure call 610 # end for # end main
+static void main() { 611 var t name? = new Turtle()value or expression?;612 t.placeAt procedureName?(-50, 30 arguments?); // procedure call 613 t.turn procedureName?(90 arguments?); // procedure call 614 t.show procedureName?(arguments?); // procedure call 615 +foreach (var i item? in range(1, 4)source?) { 616 drawSide procedureName?(side, t arguments?); // procedure call 617 t.turn procedureName?(120 arguments?); // procedure call 618 } // end foreach } // end main
+Sub main() 619 Dim t name? = New Turtle()value or expression? ' variable definition 620 t.placeAt procedureName?(-50, 30 arguments?) ' procedure call 621 t.turn procedureName?(90 arguments?) ' procedure call 622 t.show procedureName?(arguments?) ' procedure call 623 +For Each i item? In range(1, 4)source? 624 drawSide procedureName?(side, t arguments?) ' procedure call 625 t.turn procedureName?(120 arguments?) ' procedure call 626 Next i End Sub
+static void main() { 627 var t name? = new Turtle()value or expression?;628 t.placeAt procedureName?(-50, 30 arguments?); // procedure call 629 t.turn procedureName?(90 arguments?); // procedure call 630 t.show procedureName?(arguments?); // procedure call 631 +foreach (var i item? in range(1, 4)source?) { 632 drawSide procedureName?(side, t arguments?); // procedure call 633 t.turn procedureName?(120 arguments?); // procedure call 634 } // end foreach } // end main

## Vector graphics

Vector graphics are implemented using the SVG (Scalable Vector Graphics) Html tag <svg>, and are output to the display pane in the user interface.

The area is 100 units wide by 75 units high, and both integer and floating point values of the units can be used.

The origin of the units (0,0) is at the top left corner of the display: positive x rightwards, positive y downwards. So for example the centre of the display is at (50, 37.5).

The names of the shapes broadly correspond to the names of SVG tags:

- `CircleVGCircleVGCircleVGCircleVGCircleVG` for <circle../>
- `ImageVGImageVGImageVGImageVGImageVG` for <image../>
- `LineVGLineVGLineVGLineVGLineVG` for <line../>
- `RectangleVGRectangleVGRectangleVGRectangleVGRectangleVG` for <rect../>

The properties of these shapes are named to reflect the attributes used in the SVG tags but some names differ. For example, SVG's `stroke - widthstroke - widthstroke - widthstroke - widthstroke - width` is assigned with property `strokeWidthstrokeWidthstrokeWidthstrokeWidthstrokeWidth`, to make it a valid identifier . Also `strokestrokestrokestrokestroke` and `fillfillfillfillfill` are set by the properties `strokeColourstrokeColourstrokeColourstrokeColourstrokeColour` and `fillColourfillColourfillColourfillColourfillColour`.

In addition, graphics may be displayed from any valid string of SVG tags, as described in `RawVGRawVGRawVGRawVGRawVG` .

### Defining Vector graphic shapes

A set of SVG shapes is defined in either a `List<of VectorGraphic>list[VectorGraphic]List<VectorGraphic>List(Of VectorGraphic)List<VectorGraphic>` or a `ListlistListListList` of any specific type of `VectorGraphicVectorGraphicVectorGraphicVectorGraphicVectorGraphic` (e.g. `List<of CircleVG>list[CircleVG]List<CircleVG>List(Of CircleVG)List<CircleVG>`) by using the `ListlistListListList` append method.

createVectorGraphics is a convenience method that returns an empty `List<of VectorGraphic>list[VectorGraphic]List<VectorGraphic>List(Of VectorGraphic)List<VectorGraphic>`

`VectorGraphicVectorGraphicVectorGraphicVectorGraphicVectorGraphic` is the abstract superclass of all ..VG shapes. You use it when you want to define a `ListlistListListList` holding different types of shape.

Adding a shape returns a new instance of the list which must be assigned to a new or existing variable.

The constructors for the VG types require arguments defining the attributes of the relevant SVG tags, so defaults are supplied from the Class properties, as shown in the table below.

To change the value of property 'p..', call the setP.. procedure method on the vector graphic or, in a function, use the withP.. dot method on the vector graphic, in either case specifying new values in the arguments.

The `fillColourfillColourfillColourfillColourfillColour` and `strokeColourstrokeColourstrokeColourstrokeColourstrokeColour` properties may be specified as described under Colours . Only `fillColourfillColourfillColourfillColourfillColour` can be specified as `transparenttransparenttransparenttransparenttransparent`.

Note that the `heightheightheightheightheight` and `widthwidthwidthwidthwidth` properties of an image are also dependent on the dimensions of the original graphic file.

### Displaying Vector graphic shapes

As with Block  graphics, the assembled list of shapes is not displayed until call procedure displayVectorGraphics with the list as its argument, thus allowing you to make multiple changes before display.

And as with using SVG in Html, the shapes are drawn in the order in which they are added to the `VectorGraphicVectorGraphicVectorGraphicVectorGraphicVectorGraphic` instance. Later shapes are positioned in front of earlier ones.

### Function dot methods on Vector graphic shapes

function dot method | on type | argument types | return type | returns
--- | --- | --- | --- | ---
asHtml | `ImageVGImageVGImageVGImageVGImageVG` | none | `StringstrstringStringString` | string containing the Html <img> tag filled with the image's URL and attribute values
asSVG | `CircleVGCircleVGCircleVGCircleVGCircleVG` | none | `StringstrstringStringString` | string containing the SVG <circle> tag filled with the circle's attribute values
asSVG | `ImageVGImageVGImageVGImageVGImageVG` | none | `StringstrstringStringString` | string containing the SVG <image> tag filled with the image's URL and attribute values
asSVG | `LineVGLineVGLineVGLineVGLineVG` | none | `StringstrstringStringString` | string containing the SVG <line> tag filled with the line's attribute values
asSVG | `RectangleVGRectangleVGRectangleVGRectangleVGRectangleVG` | none | `StringstrstringStringString` | string containing the SVG <rectangle> tag filled with the rectangle's attribute values

### Properties of Vector graphic shapes

This table lists the properties of the Vector graphic shapes and their default values, together with the procedure and function methods provided to alter their values in a given instance.

Property | Vector graphic shape | Property | Method
--- | --- | --- | ---
name | type | CircleVG | ImageVG | LineVG | RectangleVG | description | default | procedure | function
`altaltaltaltalt` | `StringstrstringStringString` |  | ✔ |  |  | alternate textual description (for accessibility) | empty string | setAlt | withAlt
`centreXcentreXcentreXcentreXcentreX` | `FloatfloatdoubleDoubledouble` | ✔ |  |  |  | horizontal position of circle centre | 50 | setCentreX | withCentreX
`centreYcentreYcentreYcentreYcentreY` | `FloatfloatdoubleDoubledouble` | ✔ |  |  |  | vertical position of circle centre | 37.5 | setCentreY | withCentreY
`fillColourfillColourfillColourfillColourfillColour` | `IntintintIntegerint` | ✔ |  |  | ✔ | colour to fill the shape | `yellowyellowyellowyellowyellow` | setFillColour | withFillColour
`heightheightheightheightheight` | `FloatfloatdoubleDoubledouble` |  | ✔ |  | ✔ | height to render the shape or the image | Image: 13.2 Rectangle: 20 | setHeight | withHeight
`radiusradiusradiusradiusradius` | `FloatfloatdoubleDoubledouble` | ✔ |  |  |  | radius of circle | 10 | setRadius | withRadius
`strokeColourstrokeColourstrokeColourstrokeColourstrokeColour` | `IntintintIntegerint` | ✔ |  | ✔ | ✔ | colour of the strokes in the shape | `blackblackblackblackblack` | setStrokeColour | withStrokeColour
`strokeWidthstrokeWidthstrokeWidthstrokeWidthstrokeWidth` | `IntintintIntegerint` | ✔ |  | ✔ | ✔ | width of the strokes in the shape | 1 | setStrokeWidth | withStrokeWidth
`titletitletitletitletitle` | `FloatfloatdoubleDoubledouble` |  | ✔ |  |  | title text | empty string | setTitle | withTitle
`widthwidthwidthwidthwidth` | `FloatfloatdoubleDoubledouble` |  | ✔ |  | ✔ | width to render the shape or the image | Image: 13.2 Rectangle: 40 | setWidth | withWidth
`xxxxx`, `yyyyy` | `FloatfloatdoubleDoubledouble`, `FloatfloatdoubleDoubledouble` |  | ✔ ✔ |  | ✔ ✔ | image's x,y position from top left | Image: 0, 0 Rectangle: 10, 10 | setX, setY | withX, withY
`x1x1x1x1x1`, `y1y1y1y1y1` | `FloatfloatdoubleDoubledouble`, `FloatfloatdoubleDoubledouble` |  |  | ✔ ✔ |  | line's starting x,y position from top left | 10, 10 | setX1, setY1 | withX1, withY1
`x2x2x2x2x2`, `y2y2y2y2y2` | `FloatfloatdoubleDoubledouble`, `FloatfloatdoubleDoubledouble` |  |  | ✔ ✔ |  | line's ending x,y position from top left | 70, 40 | setX2, setY2 | withX2, withY2

#### Examples using simple vector graphics

● To draw a circle with a coloured circumference:

+main 635 variable vg name? set to createVectorGraphics()value or expression?636 variable circ name? set to new CircleVG()value or expression?637 call circ.setCentreX procedureName?(20 arguments?)638 call circ.setCentreY procedureName?(20 arguments?)639 call circ.setRadius procedureName?(5 arguments?)640 call circ.setFillColour procedureName?(green arguments?)641 call circ.setStrokeColour procedureName?(red arguments?)642 call circ.setStrokeWidth procedureName?(2 arguments?)643 call vg.append procedureName?(circ arguments?)644 call displayVectorGraphics procedureName?(vg arguments?)645 end main
+def main() -> None: 646 vg name? = createVectorGraphics()value or expression? # variable definition 647 circ name? = CircleVG()value or expression? # variable definition 648 circ.setCentreX procedureName?(20 arguments?) # procedure call 649 circ.setCentreY procedureName?(20 arguments?) # procedure call 650 circ.setRadius procedureName?(5 arguments?) # procedure call 651 circ.setFillColour procedureName?(green arguments?) # procedure call 652 circ.setStrokeColour procedureName?(red arguments?) # procedure call 653 circ.setStrokeWidth procedureName?(2 arguments?) # procedure call 654 vg.append procedureName?(circ arguments?) # procedure call 655 displayVectorGraphics procedureName?(vg arguments?) # procedure call 656 # end main
+static void main() { 657 var vg name? = createVectorGraphics()value or expression?;658 var circ name? = new CircleVG()value or expression?;659 circ.setCentreX procedureName?(20 arguments?); // procedure call 660 circ.setCentreY procedureName?(20 arguments?); // procedure call 661 circ.setRadius procedureName?(5 arguments?); // procedure call 662 circ.setFillColour procedureName?(green arguments?); // procedure call 663 circ.setStrokeColour procedureName?(red arguments?); // procedure call 664 circ.setStrokeWidth procedureName?(2 arguments?); // procedure call 665 vg.append procedureName?(circ arguments?); // procedure call 666 displayVectorGraphics procedureName?(vg arguments?); // procedure call 667 } // end main
+Sub main() 668 Dim vg name? = createVectorGraphics()value or expression? ' variable definition 669 Dim circ name? = New CircleVG()value or expression? ' variable definition 670 circ.setCentreX procedureName?(20 arguments?) ' procedure call 671 circ.setCentreY procedureName?(20 arguments?) ' procedure call 672 circ.setRadius procedureName?(5 arguments?) ' procedure call 673 circ.setFillColour procedureName?(green arguments?) ' procedure call 674 circ.setStrokeColour procedureName?(red arguments?) ' procedure call 675 circ.setStrokeWidth procedureName?(2 arguments?) ' procedure call 676 vg.append procedureName?(circ arguments?) ' procedure call 677 displayVectorGraphics procedureName?(vg arguments?) ' procedure call 678 End Sub
+static void main() { 679 var vg name? = createVectorGraphics()value or expression?;680 var circ name? = new CircleVG()value or expression?;681 circ.setCentreX procedureName?(20 arguments?); // procedure call 682 circ.setCentreY procedureName?(20 arguments?); // procedure call 683 circ.setRadius procedureName?(5 arguments?); // procedure call 684 circ.setFillColour procedureName?(green arguments?); // procedure call 685 circ.setStrokeColour procedureName?(red arguments?); // procedure call 686 circ.setStrokeWidth procedureName?(2 arguments?); // procedure call 687 vg.append procedureName?(circ arguments?); // procedure call 688 displayVectorGraphics procedureName?(vg arguments?); // procedure call 689 } // end main

● To draw a circle that changes between red and green every second:

+main 690 variable vg name? set to new List<of VectorGraphic>()value or expression?691 variable circ name? set to new CircleVG()value or expression?692 call circ.setCentreX procedureName?(50 arguments?)693 call circ.setCentreY procedureName?(37.5 arguments?)694 call circ.setRadius procedureName?(30 arguments?)695 call circ.setFillColour procedureName?(green arguments?)696 call vg.append procedureName?(circ arguments?)697 +while true condition? 698 call displayVectorGraphics procedureName?(vg arguments?)699 call sleep procedureName?(1 arguments?)700 call circ.setFillColour procedureName?(red arguments?)701 call displayVectorGraphics procedureName?(vg arguments?)702 call sleep procedureName?(1 arguments?)703 call circ.setFillColour procedureName?(green arguments?)704 end while call displayVectorGraphics procedureName?(vg arguments?)705 end main
+def main() -> None: 706 vg name? = list[VectorGraphic]()value or expression? # variable definition 707 circ name? = CircleVG()value or expression? # variable definition 708 circ.setCentreX procedureName?(50 arguments?) # procedure call 709 circ.setCentreY procedureName?(37.5 arguments?) # procedure call 710 circ.setRadius procedureName?(30 arguments?) # procedure call 711 circ.setFillColour procedureName?(green arguments?) # procedure call 712 vg.append procedureName?(circ arguments?) # procedure call 713 +while True condition?: 714 displayVectorGraphics procedureName?(vg arguments?) # procedure call 715 sleep procedureName?(1 arguments?) # procedure call 716 circ.setFillColour procedureName?(red arguments?) # procedure call 717 displayVectorGraphics procedureName?(vg arguments?) # procedure call 718 sleep procedureName?(1 arguments?) # procedure call 719 circ.setFillColour procedureName?(green arguments?) # procedure call 720 # end while displayVectorGraphics procedureName?(vg arguments?) # procedure call 721 # end main
+static void main() { 722 var vg name? = new List<VectorGraphic>()value or expression?;723 var circ name? = new CircleVG()value or expression?;724 circ.setCentreX procedureName?(50 arguments?); // procedure call 725 circ.setCentreY procedureName?(37.5 arguments?); // procedure call 726 circ.setRadius procedureName?(30 arguments?); // procedure call 727 circ.setFillColour procedureName?(green arguments?); // procedure call 728 vg.append procedureName?(circ arguments?); // procedure call 729 +while (true condition?) { 730 displayVectorGraphics procedureName?(vg arguments?); // procedure call 731 sleep procedureName?(1 arguments?); // procedure call 732 circ.setFillColour procedureName?(red arguments?); // procedure call 733 displayVectorGraphics procedureName?(vg arguments?); // procedure call 734 sleep procedureName?(1 arguments?); // procedure call 735 circ.setFillColour procedureName?(green arguments?); // procedure call 736 } // end while displayVectorGraphics procedureName?(vg arguments?); // procedure call 737 } // end main
+Sub main() 738 Dim vg name? = New List(Of VectorGraphic)()value or expression? ' variable definition 739 Dim circ name? = New CircleVG()value or expression? ' variable definition 740 circ.setCentreX procedureName?(50 arguments?) ' procedure call 741 circ.setCentreY procedureName?(37.5 arguments?) ' procedure call 742 circ.setRadius procedureName?(30 arguments?) ' procedure call 743 circ.setFillColour procedureName?(green arguments?) ' procedure call 744 vg.append procedureName?(circ arguments?) ' procedure call 745 +While True condition? 746 displayVectorGraphics procedureName?(vg arguments?) ' procedure call 747 sleep procedureName?(1 arguments?) ' procedure call 748 circ.setFillColour procedureName?(red arguments?) ' procedure call 749 displayVectorGraphics procedureName?(vg arguments?) ' procedure call 750 sleep procedureName?(1 arguments?) ' procedure call 751 circ.setFillColour procedureName?(green arguments?) ' procedure call 752 End While displayVectorGraphics procedureName?(vg arguments?) ' procedure call 753 End Sub
+static void main() { 754 var vg name? = new List<VectorGraphic>()value or expression?;755 var circ name? = new CircleVG()value or expression?;756 circ.setCentreX procedureName?(50 arguments?); // procedure call 757 circ.setCentreY procedureName?(37.5 arguments?); // procedure call 758 circ.setRadius procedureName?(30 arguments?); // procedure call 759 circ.setFillColour procedureName?(green arguments?); // procedure call 760 vg.append procedureName?(circ arguments?); // procedure call 761 +while (true condition?) { 762 displayVectorGraphics procedureName?(vg arguments?); // procedure call 763 sleep procedureName?(1 arguments?); // procedure call 764 circ.setFillColour procedureName?(red arguments?); // procedure call 765 displayVectorGraphics procedureName?(vg arguments?); // procedure call 766 sleep procedureName?(1 arguments?); // procedure call 767 circ.setFillColour procedureName?(green arguments?); // procedure call 768 } // end while displayVectorGraphics procedureName?(vg arguments?); // procedure call 769 } // end main

### `RawVGRawVGRawVGRawVGRawVG`

Strings containing raw SVG tags may be assembled and plotted directly using Class `RawVGRawVGRawVGRawVGRawVG`. By this means features such as simple SVG animation can be defined.

- The raw SVG content should be enclosed in double quotes within which the SVG attribute values must be enclosed in single quotes.
- To include interpolated  values, you precede the string with a $.
- The raw SVG may define multiple shapes.
- Multiple instances of `RawVGRawVGRawVGRawVGRawVG` may be added to the collection to be displayed, along with instances of other SVG types; hence the need for list-defining square brackets in the parameter of method displayVectorGraphics.
- Method withContent is used to specify the property of Class `RawVGRawVGRawVGRawVGRawVG` that must contain the SVG string.
- The example is of a simple animation in which the repetition defined in the SVG continues after the program has stopped, so you would then use the Clear button to blank the display.

#### Example using `RawVGRawVGRawVGRawVGRawVG`

● To display a repeating movement of a circle:

+main 770 variable movingCircle name? set to "<circle cx='50' cy='50' r='50' style='fill:red;'>\n<animate attributeName='cx' begin='0s' dur='2s' from='50' to='90%' repeatCount='indefinite' /></circle>"value or expression?771 variable raw name? set to (new RawVG()).withContent(movingCircle)value or expression?772 call displayVectorGraphics procedureName?([raw]arguments?)773 end main
+def main() -> None: 774 movingCircle name? = "<circle cx='50' cy='50' r='50' style='fill:red;'>\n<animate attributeName='cx' begin='0s' dur='2s' from='50' to='90%' repeatCount='indefinite' /></circle>"value or expression? # variable definition 775 raw name? = (RawVG()).withContent(movingCircle)value or expression? # variable definition 776 displayVectorGraphics procedureName?([raw]arguments?) # procedure call 777 # end main
+static void main() { 778 var movingCircle name? = "<circle cx='50' cy='50' r='50' style='fill:red;'>\n<animate attributeName='cx' begin='0s' dur='2s' from='50' to='90%' repeatCount='indefinite' /></circle>"value or expression?;779 var raw name? = (new RawVG()).withContent(movingCircle)value or expression?;780 displayVectorGraphics procedureName?(new [] {raw}arguments?); // procedure call 781 } // end main
+Sub main() 782 Dim movingCircle name? = "<circle cx='50' cy='50' r='50' style='fill:red;'>\n<animate attributeName='cx' begin='0s' dur='2s' from='50' to='90%' repeatCount='indefinite' /></circle>"value or expression? ' variable definition 783 Dim raw name? = (New RawVG()).withContent(movingCircle)value or expression? ' variable definition 784 displayVectorGraphics procedureName?({raw}arguments?) ' procedure call 785 End Sub
+static void main() { 786 var movingCircle name? = "<circle cx='50' cy='50' r='50' style='fill:red;'>\n<animate attributeName='cx' begin='0s' dur='2s' from='50' to='90%' repeatCount='indefinite' /></circle>"value or expression?;787 var raw name? = (new RawVG()).withContent(movingCircle)value or expression?;788 displayVectorGraphics procedureName?(list(raw)arguments?); // procedure call 789 } // end main

## Combining graphic outputs

Program outputs, whether text or graphical, can be combined in the display. In particular, Block graphics and text or Html printing can share the display along with either Vector graphics or Turtle graphics (but not both).

If you want to share the display in this way, remember that both text and Html print outputs appear sequentially down the display (which can be scrolled), whereas the graphic outputs are positioned in the display using their own absolute coordinate systems.

The order in which the outputs are displayed (and therefore overwrite) is:

1. Block graphics
2. Vector or Turtle graphics
3. Printed text or Html

So some care is needed to manage the layout in the display.

Note that, while vector graphics are being drawn, printed text that exceeds the height of the display does not scroll until the graphic completes.

# Other types

## Random

### Generating random numbers within a function

It is not possible to use the system methods  random or randint within a function because they create unseen side effects. You may use those system methods outside the function and pass the resulting random number (as an `IntintintIntegerint` or a `FloatfloatdoubleDoubledouble`) as an argument into a function.

It is, however, possible to create and use random numbers within a function, but it requires a different approach and is a little more complex. You use the special type `RandomRandomRandomRandomRandom`. (Note the upper case `RRRRR` required for a type name).

You start by getting a seed random number in your main routine or in a procedure using method initialiseFromClock:

`variable rndname? set to new Random()value or expression?155rndname? = Random()value or expression? # variable definition156var rndname? = new Random()value or expression?;157Dim rndname? = New Random()value or expression? ' variable definition158var rndname? = new Random()value or expression?;159`
`call rnd.initialiseFromClockprocedureName?(arguments?)160rnd.initialiseFromClockprocedureName?(arguments?) # procedure call161rnd.initialiseFromClockprocedureName?(arguments?); // procedure call162rnd.initialiseFromClockprocedureName?(arguments?) ' procedure call163rnd.initialiseFromClockprocedureName?(arguments?); // procedure call164`

Then, in a function, apply dot method asFloat or asInt as appropriate to the `RandomRandomRandomRandomRandom` passed in, and dot method nextGen to obtain a new instance of `RandomRandomRandomRandomRandom` for generating the next random number.

Avoid applying nextGen more than once on the same `RandomRandomRandomRandomRandom` instance, because it will return the same values.

If the initialiseFromClock call is absent, the program will still generate a sequence of random values, but the sequence will be exactly the same each time you run the program. Initialising from the clock ensures that you get a different sequence each run. Using `RandomRandomRandomRandomRandom` without so initialising, however, can be extremely useful for testing purposes since the results are repeatable.

### Function method for random seed

procedure method | argument type | action
--- | --- | ---
initialiseFromClock | (none) | uses the system clock to provide a seed from which to generate fresh random values

### Function dot methods on a `RandomRandomRandomRandomRandom`

function dot method | argument types | return type | returns
--- | --- | --- | ---
asFloat | (none) | `FloatfloatdoubleDoubledouble` | random `FloatfloatdoubleDoubledouble` value in the range (0.0, 1.0)
asInt | `IntintintIntegerint`, `IntintintIntegerint` | `IntintintIntegerint` | random `IntintintIntegerint` value in the range of the arguments
nextGen | (none) | `RandomRandomRandomRandomRandom` | a new instance of `RandomRandomRandomRandomRandom` for subsequent use

#### Example using `RandomRandomRandomRandomRandom`

● To roll a dice 20 times in a function that returns a 2-tuple of random value and a new instance of `RandomRandomRandomRandomRandom`

:
+main 790 variable rnd name? set to new Random()value or expression?791 call rnd.initialiseFromClock procedureName?(arguments?)792 +for i item? in range(1, 20)source? 793 print(randomThrow(rnd).item_0 arguments?)794 assign rnd variableName? to randomThrow(rnd).item_1 value or expression?795 end for end main
+def main() -> None: 796 rnd name? = Random()value or expression? # variable definition 797 rnd.initialiseFromClock procedureName?(arguments?) # procedure call 798 +for i item? in range(1, 20)source?: 799 print(randomThrow(rnd).item_0 arguments?)800 rnd variableName? = randomThrow(rnd).item_1 value or expression? # assignment 801 # end for # end main
+static void main() { 802 var rnd name? = new Random()value or expression?;803 rnd.initialiseFromClock procedureName?(arguments?); // procedure call 804 +foreach (var i item? in range(1, 20)source?) { 805 Console.WriteLine(randomThrow(rnd).item_0 arguments?); // print statement 806 rnd variableName? = randomThrow(rnd).item_1 value or expression?; // assignment 807 } // end foreach } // end main
+Sub main() 808 Dim rnd name? = New Random()value or expression? ' variable definition 809 rnd.initialiseFromClock procedureName?(arguments?) ' procedure call 810 +For Each i item? In range(1, 20)source? 811 Console.WriteLine(randomThrow(rnd).item_0 arguments?) ' print statement 812 rnd variableName? = randomThrow(rnd).item_1 value or expression? ' assignment 813 Next i End Sub
+static void main() { 814 var rnd name? = new Random()value or expression?;815 rnd.initialiseFromClock procedureName?(arguments?); // procedure call 816 +foreach (var i item? in range(1, 20)source?) { 817 System.out.println(randomThrow(rnd).item_0 arguments?); // print statement 818 rnd variableName? = randomThrow(rnd).item_1 value or expression?; // assignment 819 } // end foreach } // end main

# Input/output

This section covers a variety of input and output facilities:

- Keyboard input 
- Text file input/output 
- Rendering Html in the display 
- Displaying images from URLs 
- Sound 

## Keyboard input

soliciting and retrieving keyboard input requires using these system methods:

system method | argument types | return types | action
--- | --- | --- | ---
getKey | (none) | `StringstrstringStringString` | returns the last character last pressed on the keyboard during program execution
getKeyWithModifier | (none) | 2-Tuple: (`StringstrstringStringString`, `StringstrstringStringString`) | returns the last key combination pressed on the keyboard: the key pressed and the modifier key's name (if also pressed)
getNumericKey | (none) | `StringstrstringStringString` | returns either the numeric key last pressed or, if the last pressed key was not numeric, then `"-1""-1""-1""-1""-1"`
input | `StringstrstringStringString` | `StringstrstringStringString` | prints the string as a prompt, and returns the typed input when Enter is pressed, similar to the input statement.
inputStringWithLimits | `StringstrstringStringString`, `IntintintIntegerint`, `IntintintIntegerint` | `StringstrstringStringString` | prints the string as a prompt and returns the typed input when Enter is pressed provided the length of the response is within the minimum and maximum limits specified. If it is not, the prompt is repeated with the relevant limit displayed
inputStringFromOptions | `StringstrstringStringString`, `List<of String>list[str]List<string>List(Of String)List<String>` | `StringstrstringStringString` | prints the string as a prompt and returns the typed input when Enter is pressed provided it is one of the options in the list. If it is not, the prompt is repeated with the options displayed
inputInt | `StringstrstringStringString` | `IntintintIntegerint` | prints the string as a prompt and returns the value of the typed input when Enter is pressed provided that it is an integer. If it is not, the prompt is repeated with an error message
inputIntBetween | `StringstrstringStringString`, `IntintintIntegerint`, `IntintintIntegerint` | `IntintintIntegerint` | prints the string as a prompt and returns the value of the typed input when Enter is pressed provided that it is an integer with a value in the (inclusive) range. The first range value must be less than or equal to the second
inputFloat | `StringstrstringStringString` | `FloatfloatdoubleDoubledouble` | prints the string as a prompt and returns the value of the typed input when Enter is pressed provided that it is a number. If it is not, the prompt is repeated with an error message
inputFloatBetween | `StringstrstringStringString`, `IntintintIntegerint`, `IntintintIntegerint` | `FloatfloatdoubleDoubledouble` | prints the string as a prompt and returns the value of the typed input when Enter is pressed provided that it is a number with a value in the (inclusive) range. The first range value must be less than or equal to the second
waitForKey | (none) | `StringstrstringStringString` | pauses execution of the program until a key is pressed on the keyboard, and returns either a character or the name of a non-character key

### Reading keys 'on the fly'

In some applications – especially in games, for example – you want the program to react to a key pressed by the user, but without holding up the program to wait for value to be input.

Whether your application makes use of graphics, or uses the display just for text, reading keystrokes 'on the fly' is done via one of the three methods shown here:

+main 820 variable key1 name? set to getKey()value or expression?821 variable key2 name? set to getNumericKey()value or expression?822 variable km name? set to getKeyWithModifier()value or expression?823 variable keyCap name? set to km.item_0 value or expression?824 variable keyMod name? set to km.item_1 value or expression?825 end main
+def main() -> None: 826 key1 name? = getKey()value or expression? # variable definition 827 key2 name? = getNumericKey()value or expression? # variable definition 828 km name? = getKeyWithModifier()value or expression? # variable definition 829 keyCap name? = km.item_0 value or expression? # variable definition 830 keyMod name? = km.item_1 value or expression? # variable definition 831 # end main
+static void main() { 832 var key1 name? = getKey()value or expression?;833 var key2 name? = getNumericKey()value or expression?;834 var km name? = getKeyWithModifier()value or expression?;835 var keyCap name? = km.item_0 value or expression?;836 var keyMod name? = km.item_1 value or expression?;837 } // end main
+Sub main() 838 Dim key1 name? = getKey()value or expression? ' variable definition 839 Dim key2 name? = getNumericKey()value or expression? ' variable definition 840 Dim km name? = getKeyWithModifier()value or expression? ' variable definition 841 Dim keyCap name? = km.item_0 value or expression? ' variable definition 842 Dim keyMod name? = km.item_1 value or expression? ' variable definition 843 End Sub
+static void main() { 844 var key1 name? = getKey()value or expression?;845 var key2 name? = getNumericKey()value or expression?;846 var km name? = getKeyWithModifier()value or expression?;847 var keyCap name? = km.item_0 value or expression?;848 var keyMod name? = km.item_1 value or expression?;849 } // end main

- When any of these functions (except waitForKey) is called, the system does not wait for a response, but immediately returns a `StringstrstringStringString` or Tuple.
- getKey returns a string containing the keyboard character last pressed, possibly shifted, e.g. "z" or "@".
- getNumericKey returns a string containing either a digit ("0".."9") or, if the last key pressed was not numeric, then "-1". A digit will be returned if the key pressed was either from the main keyboard, or from the numeric keypad when NumLock is on.
- getKeyWithModifier returns a 2-Tuple of two strings: the key last pressed and the name of one modifier key `"Shift""Shift""Shift""Shift""Shift"`, `"Ctrl""Ctrl""Ctrl""Ctrl""Ctrl"` or `"Alt""Alt""Alt""Alt""Alt"` if simultaneously pressed. If no modifier had been pressed, the Tuple's second item will be the empty string. Note that a few such modified keys will be acted on by the browser and may not then be passed to your program.
- Non-printable keys will also be returned as strings, e.g. `"Home""Home""Home""Home""Home"`, `"End""End""End""End""End"`, `"Delete""Delete""Delete""Delete""Delete"`, `"Tab""Tab""Tab""Tab""Tab"`, `"Backspace""Backspace""Backspace""Backspace""Backspace"`, `"Enter""Enter""Enter""Enter""Enter"`, `"Escape""Escape""Escape""Escape""Escape"`, `"ArrowUp""ArrowUp""ArrowUp""ArrowUp""ArrowUp"` etc., function key `"Fn""Fn""Fn""Fn""Fn"`, `"AltGraph""AltGraph""AltGraph""AltGraph""AltGraph"`, `"Meta""Meta""Meta""Meta""Meta"`, `"ContextMenu""ContextMenu""ContextMenu""ContextMenu""ContextMenu"`, as well as most others.
- Pressing just control keys Shift, Ctrl (⌘ Command under macOS) or Alt keys will not be detected by getKey.
- If no key has been pressed (since the last time the method was called), it will return the empty string.
- All these methods are system methods because they have a dependency on the system and so may be used only within a procedure or in main routine.
- Use the procedure method clearKeyBuffer if you want to enforce that the user cannot get too far ahead of the program by hitting keys in rapid succession.
- Method waitForKey waits for a key to be pressed, and returns it.
- Procedure methodpressAnyKeyToContinue gives an optional prompt and is used when you don't need to know which key was pressed. Its argument is a Boolean value:
  if `trueTruetrueTruetrue`, the prompt "Press any key to continue" appears,
  if `falseFalsefalseFalsefalse`, no prompt appears.

+main 850 call pressAnyKeyToContinue procedureName?(arguments?)851 print("OK, press A or B"arguments?)852 variable key name? set to waitForKey()value or expression?853 print($"That was {key}"arguments?)854 end main
+def main() -> None: 855 pressAnyKeyToContinue procedureName?(arguments?) # procedure call 856 print("OK, press A or B"arguments?)857 key name? = waitForKey()value or expression? # variable definition 858 print(f"That was {key}"arguments?)859 # end main
+static void main() { 860 pressAnyKeyToContinue procedureName?(arguments?); // procedure call 861 Console.WriteLine("OK, press A or B"arguments?); // print statement 862 var key name? = waitForKey()value or expression?;863 Console.WriteLine($"That was {key}"arguments?); // print statement 864 } // end main
+Sub main() 865 pressAnyKeyToContinue procedureName?(arguments?) ' procedure call 866 Console.WriteLine("OK, press A or B"arguments?) ' print statement 867 Dim key name? = waitForKey()value or expression? ' variable definition 868 Console.WriteLine($"That was {key}"arguments?) ' print statement 869 End Sub
+static void main() { 870 pressAnyKeyToContinue procedureName?(arguments?); // procedure call 871 System.out.println("OK, press A or B"arguments?); // print statement 872 var key name? = waitForKey()value or expression?;873 System.out.println(String.format("That was %", key)arguments?); // print statement 874 } // end main

## Text file input/output

Reading or writing a text file requires that you open (for reading) or create (for writing) a file using these system methods:

system method | argument types | return Class | action
--- | --- | --- | ---
createFileForWriting | `StringstrstringStringString` | `TextFileWriterTextFileWriterTextFileWriterTextFileWriterTextFileWriter` | sets up a buffer for the data to be output, and specifies a filename (or the empty string) with or without the default filetype of .txt, and returns a file handle see Writing text files 
openFileForReading | (none) | `TextFileReaderTextFileReaderTextFileReaderTextFileReaderTextFileReader` | opens a file system dialog to choose the filename of filetype .txt to be read, and returns a file handle see Reading text files 

### Writing text files

The `TextFileWriterTextFileWriterTextFileWriterTextFileWriterTextFileWriter` Class is used to write textual data to a file.

An instance is created by the system method createFileForWriting.

The available procedure methods are:

procedure method | argument type | action
--- | --- | ---
writeLine | `StringstrstringStringString` | writes the string to the buffer
writeWholeFile | `StringstrstringStringString` | writes the string to the buffer and then outputs the buffer to the file system
saveAndClose | none | writes the buffer to the file system

These methods may be used to write a whole file in one go:

+main 875 variable file name? set to createFileForWriting("myFile.txt")value or expression?876 call file.writeWholeFile procedureName?("Text line 1\nText line 2"arguments?)877 end main
+def main() -> None: 878 file name? = createFileForWriting("myFile.txt")value or expression? # variable definition 879 file.writeWholeFile procedureName?("Text line 1\nText line 2"arguments?) # procedure call 880 # end main
+static void main() { 881 var file name? = createFileForWriting("myFile.txt")value or expression?;882 file.writeWholeFile procedureName?("Text line 1\nText line 2"arguments?); // procedure call 883 } // end main
+Sub main() 884 Dim file name? = createFileForWriting("myFile.txt")value or expression? ' variable definition 885 file.writeWholeFile procedureName?("Text line 1\nText line 2"arguments?) ' procedure call 886 End Sub
+static void main() { 887 var file name? = createFileForWriting("myFile.txt")value or expression?;888 file.writeWholeFile procedureName?("Text line 1\nText line 2"arguments?); // procedure call 889 } // end main

#### Notes

- `writeLinewriteLinewriteLinewriteLinewriteLine` adds the string it is passed onto the end of any data previously written, with a newline character (\n) automatically appended.
- When execution reaches `saveAndClosesaveAndClosesaveAndClosesaveAndClosesaveAndClose` you will be presented with a dialog to confirm (or edit) the given filename and location where it is to be saved. It is not therefore strictly necessary to specify a filename when creating the file, since it can be specified by the user in the dialog so, in that case, you might put the empty string `""""""""""` into the parameter of `createFileForWritingcreateFileForWritingcreateFileForWritingcreateFileForWritingcreateFileForWriting`.
- `writeWholeFilewriteWholeFilewriteWholeFilewriteWholeFilewriteWholeFile` puts the string it is given into the file and then automatically saves the file, so the user will be presented with the same dialog as if `saveAndClosesaveAndClosesaveAndClosesaveAndClosesaveAndClose` had been called.
- Calling any method on a file that has already been closed (by calling either `saveAndClosesaveAndClosesaveAndClosesaveAndClosesaveAndClose` or by `writeWholeFilewriteWholeFilewriteWholeFilewriteWholeFilewriteWholeFile`) will result in a runtime error.
- If the user were to click Cancel in the save dialogue, then the program will exit with an error. To guard against this possibility (it might mean the loss of important data), you should perform the save and close within a try statement like this (where `CustomErrorCustomErrorCustomErrorCustomErrorCustomError`  is a Class provided by Elan for this purpose):
  main
  main
  main
  main
  main
  or you could make the code offer the user options: to save again, or to continue without saving.

### Reading text files

The `TextFileReaderTextFileReaderTextFileReaderTextFileReaderTextFileReader` Class is used to read text data from a file with type extension .txt.

An instance is created by the system method openFileForReading.

The available procedure methods are:

procedure method | argument type | action
--- | --- | ---
readLine | (none) | reads the next substring from the file that is terminated with a newline
readWholeFile | (none) | reads the whole file and closes the file
endOfFile | (none) | returns `trueTruetrueTruetrue` after the last line has been read – otherwise `falseFalsefalseFalsefalse`
close | (none) | closes the file

These methods may be used to read a whole file in one go:

+main 890 variable file name? set to openFileForReading()value or expression?891 variable text name? set to file.readWholeFile()value or expression?892 print(text arguments?)893 end main
+def main() -> None: 894 file name? = openFileForReading()value or expression? # variable definition 895 text name? = file.readWholeFile()value or expression? # variable definition 896 print(text arguments?)897 # end main
+static void main() { 898 var file name? = openFileForReading()value or expression?;899 var text name? = file.readWholeFile()value or expression?;900 Console.WriteLine(text arguments?); // print statement 901 } // end main
+Sub main() 902 Dim file name? = openFileForReading()value or expression? ' variable definition 903 Dim text name? = file.readWholeFile()value or expression? ' variable definition 904 Console.WriteLine(text arguments?) ' print statement 905 End Sub
+static void main() { 906 var file name? = openFileForReading()value or expression?;907 var text name? = file.readWholeFile()value or expression?;908 System.out.println(text arguments?); // print statement 909 } // end main

#### Notes

- `openFileForReadingopenFileForReadingopenFileForReadingopenFileForReadingopenFileForReading` will present the user with a dialog to select the file.
- `readWholeFilereadWholeFilereadWholeFilereadWholeFilereadWholeFile` returns a `StringstrstringStringString` containing every character in the file, without any trimming. It automatically closes the file after the read.
- `readLinereadLinereadLinereadLinereadLine` reads as far as the next newline character (\n) and then automatically trims the line to remove any spaces and/or carriage-returns (which some file systems insert after the newline automatically) from the resulting line returned as a `StringstrstringStringString`. If this behaviour is not desired, you can use `readWholeFilereadWholeFilereadWholeFilereadWholeFilereadWholeFile`, which does no trimming, and then parse the resulting `StringstrstringStringString` into separate lines.
- Calling `file.closefile.closefile.closefile.closefile.close` after reading line by line is strongly recommended to avoid any risk of leaving the file locked. It is not necessary to call it after using `readWholeFilereadWholeFilereadWholeFilereadWholeFilereadWholeFile` because that method automatically closes the file.
- Calling any method on a file that is already closed will result in a runtime error.

## Rendering Html in the display

If you embed Html code in a string and then attempt to print it, you will see the string displayed literally: the Html tags will not be recognised. This is for security reasons. However, it is possible to display formatted Html in the display. The following code:

call displayHtml procedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?)910
displayHtml procedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?) # procedure call 911
displayHtml procedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?); // procedure call 912
displayHtml procedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?) ' procedure call 913
displayHtml procedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?); // procedure call 914

will produce:

This Html forms another 'layer' in the IDE's display pane. Any plain text that you print (using call procedure print() or any of the print procedures) will be overlaid on top of this.

You can clear just the Html layer in the display using the procedure clearHtml .

For specifying style or other attributes within Html tags, the attribute values should be enclosed in single quotation marks ' as shown above. Html will recognise single or double quotation marks, but entering double quotation marks would terminate the Elan string. Alternatively, you could use the constant `quotesquotesquotesquotesquotes` within curly braces as an interpolated field .

### Using an embedded CSS stylesheet

You can also specify a <style> tag at the start of your Html string, to apply to the whole Html being displayed. In this case you would put the style definition into a named value as a literal but enclosed in single quotes, for example:

+main 915 variable style name? set to "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression?916 call displayHtml procedureName?($"{style}<h1>New heading</h1><p>some new text</p>"arguments?)917 end main
+def main() -> None: 918 style name? = "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression? # variable definition 919 displayHtml procedureName?(f"{style}<h1>New heading</h1><p>some new text</p>"arguments?) # procedure call 920 # end main
+static void main() { 921 var style name? = "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression?;922 displayHtml procedureName?($"{style}<h1>New heading</h1><p>some new text</p>"arguments?); // procedure call 923 } // end main
+Sub main() 924 Dim style name? = "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression? ' variable definition 925 displayHtml procedureName?($"{style}<h1>New heading</h1><p>some new text</p>"arguments?) ' procedure call 926 End Sub
+static void main() { 927 var style name? = "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression?;928 displayHtml procedureName?(String.format("%<h1>New heading</h1><p>some new text</p>", style)arguments?); // procedure call 929 } // end main

will produce:

## Displaying images from URLs

An image that can be retrieved with an http or https URL may be sent to the display, though note that other URI schemes, such as in file://host/path to access an image from your local file system, are not supported. Here are two techniques:

- put the Html <img> tag into a string and then call the displayHtml method on it, thus:
  +main 930 variable pic name? set to "<img src='https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_%2828225976491%29.jpg' width='400' height='200' title='shark' alt='shark'>"value or expression?931 call displayHtml procedureName?(pic arguments?)932 end main
  +def main() -> None: 933 pic name? = "<img src='https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_%2828225976491%29.jpg' width='400' height='200' title='shark' alt='shark'>"value or expression? # variable definition 934 displayHtml procedureName?(pic arguments?) # procedure call 935 # end main
  +static void main() { 936 var pic name? = "<img src='https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_%2828225976491%29.jpg' width='400' height='200' title='shark' alt='shark'>"value or expression?;937 displayHtml procedureName?(pic arguments?); // procedure call 938 } // end main
  +Sub main() 939 Dim pic name? = "<img src='https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_%2828225976491%29.jpg' width='400' height='200' title='shark' alt='shark'>"value or expression? ' variable definition 940 displayHtml procedureName?(pic arguments?) ' procedure call 941 End Sub
  +static void main() { 942 var pic name? = "<img src='https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_%2828225976491%29.jpg' width='400' height='200' title='shark' alt='shark'>"value or expression?;943 displayHtml procedureName?(pic arguments?); // procedure call 944 } // end main

  The usual <img> tag attributes are respected, though `altaltaltaltalt` does not give the expected tooltip when hovering over the image, and `titletitletitletitletitle` is only a descriptive comment.

- put the URL into a Vector Graphics `ImageVGImageVGImageVGImageVGImageVG` definition, set properties by calling vector graphic procedures , then call the method displayVectorGraphics on it, thus:
  +main 945 variable sharkUrl name? set to "https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_(28225976491).jpg"value or expression?946 variable sharkVG name? set to new ImageVG(sharkUrl)value or expression?947 call sharkVG.setWidth procedureName?(400 arguments?)948 call sharkVG.setHeight procedureName?(200 arguments?)949 call sharkVG.setAlt procedureName?("Shark"arguments?)950 call displayVectorGraphics procedureName?([sharkVG]arguments?)951 end main
  +def main() -> None: 952 sharkUrl name? = "https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_(28225976491).jpg"value or expression? # variable definition 953 sharkVG name? = ImageVG(sharkUrl)value or expression? # variable definition 954 sharkVG.setWidth procedureName?(400 arguments?) # procedure call 955 sharkVG.setHeight procedureName?(200 arguments?) # procedure call 956 sharkVG.setAlt procedureName?("Shark"arguments?) # procedure call 957 displayVectorGraphics procedureName?([sharkVG]arguments?) # procedure call 958 # end main
  +static void main() { 959 var sharkUrl name? = "https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_(28225976491).jpg"value or expression?;960 var sharkVG name? = new ImageVG(sharkUrl)value or expression?;961 sharkVG.setWidth procedureName?(400 arguments?); // procedure call 962 sharkVG.setHeight procedureName?(200 arguments?); // procedure call 963 sharkVG.setAlt procedureName?("Shark"arguments?); // procedure call 964 displayVectorGraphics procedureName?(new [] {sharkVG}arguments?); // procedure call 965 } // end main
  +Sub main() 966 Dim sharkUrl name? = "https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_(28225976491).jpg"value or expression? ' variable definition 967 Dim sharkVG name? = New ImageVG(sharkUrl)value or expression? ' variable definition 968 sharkVG.setWidth procedureName?(400 arguments?) ' procedure call 969 sharkVG.setHeight procedureName?(200 arguments?) ' procedure call 970 sharkVG.setAlt procedureName?("Shark"arguments?) ' procedure call 971 displayVectorGraphics procedureName?({sharkVG}arguments?) ' procedure call 972 End Sub
  +static void main() { 973 var sharkUrl name? = "https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_(28225976491).jpg"value or expression?;974 var sharkVG name? = new ImageVG(sharkUrl)value or expression?;975 sharkVG.setWidth procedureName?(400 arguments?); // procedure call 976 sharkVG.setHeight procedureName?(200 arguments?); // procedure call 977 sharkVG.setAlt procedureName?("Shark"arguments?); // procedure call 978 displayVectorGraphics procedureName?(list(sharkVG)arguments?); // procedure call 979 } // end main

## Sound

The tone procedure allows the generation of a simple tone. It requires three arguments to be provided:

- the duration of the generated tone specified in milliseconds (`IntintintIntegerint`)
- the frequency of the generated tone in Hertz (`IntintintIntegerint`)
- the volume of the tone (`FloatfloatdoubleDoubledouble`)

Note that the volume parameter is only relative in that the actual volume will be modified by the various sound settings on the output device, and may even be muted.

#### Example using tone

● An example that plays a C major scale first ascending then descending:

+main 980 variable scale name? set to [262, 294, 330, 349, 392, 440, 494, 523]value or expression?981 variable scaleL name? set to scale.length()value or expression?982 variable quaver name? set to 250 value or expression?983 variable volume name? set to 1.5 value or expression?984 +for i item? in range(0, scaleL)source? 985 call tone procedureName?(quaver, scale[i], volume arguments?)986 end for call sleep procedureName?(1 arguments?)987 +for i item? in range(0, scaleL)source? 988 call tone procedureName?(quaver, scale[scaleL - 1 - i], volume arguments?)989 end for end main
+def main() -> None: 990 scale name? = [262, 294, 330, 349, 392, 440, 494, 523]value or expression? # variable definition 991 scaleL name? = scale.length()value or expression? # variable definition 992 quaver name? = 250 value or expression? # variable definition 993 volume name? = 1.5 value or expression? # variable definition 994 +for i item? in range(0, scaleL)source?: 995 tone procedureName?(quaver, scale[i], volume arguments?) # procedure call 996 # end for sleep procedureName?(1 arguments?) # procedure call 997 +for i item? in range(0, scaleL)source?: 998 tone procedureName?(quaver, scale[scaleL - 1 - i], volume arguments?) # procedure call 999 # end for # end main
+static void main() { 1000 var scale name? = new [] {262, 294, 330, 349, 392, 440, 494, 523}value or expression?;1001 var scaleL name? = scale.length()value or expression?;1002 var quaver name? = 250 value or expression?;1003 var volume name? = 1.5 value or expression?;1004 +foreach (var i item? in range(0, scaleL)source?) { 1005 tone procedureName?(quaver, scale[i], volume arguments?); // procedure call 1006 } // end foreach sleep procedureName?(1 arguments?); // procedure call 1007 +foreach (var i item? in range(0, scaleL)source?) { 1008 tone procedureName?(quaver, scale[scaleL - 1 - i], volume arguments?); // procedure call 1009 } // end foreach } // end main
+Sub main() 1010 Dim scale name? = {262, 294, 330, 349, 392, 440, 494, 523}value or expression? ' variable definition 1011 Dim scaleL name? = scale.length()value or expression? ' variable definition 1012 Dim quaver name? = 250 value or expression? ' variable definition 1013 Dim volume name? = 1.5 value or expression? ' variable definition 1014 +For Each i item? In range(0, scaleL)source? 1015 tone procedureName?(quaver, scale(i), volume arguments?) ' procedure call 1016 Next i sleep procedureName?(1 arguments?) ' procedure call 1017 +For Each i item? In range(0, scaleL)source? 1018 tone procedureName?(quaver, scale(scaleL - 1 - i), volume arguments?) ' procedure call 1019 Next i End Sub
+static void main() { 1020 var scale name? = list(262, 294, 330, 349, 392, 440, 494, 523)value or expression?;1021 var scaleL name? = scale.length()value or expression?;1022 var quaver name? = 250 value or expression?;1023 var volume name? = 1.5 value or expression?;1024 +foreach (var i item? in range(0, scaleL)source?) { 1025 tone procedureName?(quaver, scale[i], volume arguments?); // procedure call 1026 } // end foreach sleep procedureName?(1 arguments?); // procedure call 1027 +foreach (var i item? in range(0, scaleL)source?) { 1028 tone procedureName?(quaver, scale[scaleL - 1 - i], volume arguments?); // procedure call 1029 } // end foreach } // end main

# Common methods

## Common dot methods

Click on a type to go to the type's function dot methods, or on  to go to the specific method on that type.

Dot method | Value type | Reference type | Tuple
--- | --- | --- | ---
| `IntintintIntegerint`  | `FloatfloatdoubleDoubledouble`  | `BooleanboolboolBooleanboolean`  | `StringstrstringStringString`  | `ListlistListListList`  | `DictionaryDictionaryDictionaryDictionaryDictionary`  | `HashSetHashSetHashSetHashSetHashSet`  | `StackStackStackStackStack`  | `QueueQueueQueueQueueQueue`  |
ceiling |  note 2. |  |  |  |  |  |  |  |  |
contains |  |  |  |  |  |  note 4. |  |  |  |
equals |  |  |  |  |  |  |  |  |  | 
floor |  note 2. |  |  |  |  |  |  |  |  |
indexOf |  |  |  |  |  |  |  |  |  |
isInfinite |  note 2. |  |  |  |  |  |  |  |  |
isNan |  note 2. |  |  |  |  |  |  |  |  |
length |  |  |  |  |  |  note 3. |  |  |  |
notEqualTo |  |  |  |  |  |  |  |  |  | 
peek |  |  |  |  |  |  |  |  |  |
round |  note 2. |  |  |  |  |  |  |  |  |
toString note 1. |  |  |  |  |  |  |  |  |  | 
withSet |  |  |  |  |  |  |  |  |  |
withRemoveAt |  |  |  |  |  |  |  |  |  |

#### Notes

1. The method toString is so widely applicable because it enables you to print all variables and data structures to the IDE's display pane for debugging purposes.
2. methods ceiling, floor, isInfinite, isNaN and round are designed for use on `FloatfloatdoubleDoubledouble` values, but they can accept `IntintintIntegerint` values without raising an error.
3. The length of a `DictionaryDictionaryDictionaryDictionaryDictionary` can be found by applying method length to the list returned by method keys on the dictionary:

   `print(di.keys().length()arguments?)165print(di.keys().length()arguments?)166Console.WriteLine(di.keys().length()arguments?); // print statement167Console.WriteLine(di.keys().length()arguments?) ' print statement168System.out.println(di.keys().length()arguments?); // print statement169` | ⟶ | 15

4. Checking whether an item is contained in a `DictionaryDictionaryDictionaryDictionaryDictionary` can be done by applying method contains to the list returned by methods keys and values on the dictionary:

   `print(di.keys().contains("widget")arguments?)170print(di.keys().contains("widget")arguments?)171Console.WriteLine(di.keys().contains("widget")arguments?); // print statement172Console.WriteLine(di.keys().contains("widget")arguments?) ' print statement173System.out.println(di.keys().contains("widget")arguments?); // print statement174` | ⟶ | true or false
   `print(di.values().contains(42)arguments?)175print(di.values().contains(42)arguments?)176Console.WriteLine(di.values().contains(42)arguments?); // print statement177Console.WriteLine(di.values().contains(42)arguments?) ' print statement178System.out.println(di.values().contains(42)arguments?); // print statement179` | ⟶ | true or false

# Library procedures

All procedures are accessed via a `callcallcallcallcall`  instruction.

## Standalone procedures

procedure | input argument types | output argument types | action
--- | --- | --- | ---
clearPrintedText | (none) | (none) | clears the IDE's display pane
clearBlocks | (none) | (none) | clears the block graphics layer of the IDE's display pane
clearVectorGraphics | (none) | (none) | clears the vector graphics layer of the IDE's display pane
clearHtml | (none) | (none) | clears the Html layer of the IDE's display pane
clearAllDisplays | (none) | (none) | clears display pane as well as the blocks, vector graphics and Html layers
clearKeyBuffer | (none) | (none) | clears the IDE's keyboard input
pressAnyKeyToContinue | `BooleanboolboolBooleanboolean` | (none) | pauses execution of the program until a keyboard key is pressed if the argument is `trueTruetrueTruetrue` 'Press any key to continue' is first displayed, if `falseFalsefalseFalsefalse` nothing is displayed
printNoLine | `StringstrstringStringString` | (none) | prints the string to the display without appending a newline so a following call will output on the same line. You can put your own \n newlines in the argument string
printTab | `IntintintIntegerint`, `StringstrstringStringString` | (none) | prints the string to the display starting at the tab position given (from 0) without appending a newline
sleep | `IntintintIntegerint` | (none) | pauses the execution of the program for the specified number of seconds, e.g. for a game `sleep(1.5)sleep(1.5)sleep(1.5)sleep(1.5)sleep(1.5)` delays execution for 1.5 seconds
sleep_ms | `IntintintIntegerint` | (none) | pauses the execution of the program for the specified number of milliseconds, e.g. `sleep(100)sleep(100)sleep(100)sleep(100)sleep(100)` delays execution for one tenth of a second

#### Examples using print and printTab

● Procedure print sends text strings to the display pane:

+main 1030 print("Hello"arguments?)1031 variable a name? set to 3 value or expression?1032 variable b name? set to 4 value or expression?1033 print(a*b arguments?)1034 print($"{a} times {b}) equals {a*b}"arguments?)1035 variable t name? set to (true, 42)value or expression?1036 print(t.item_0 arguments?)1037 print(t.item_1 arguments?)1038 end main +def main() -> None: 1039 print("Hello"arguments?)1040 a name? = 3 value or expression? # variable definition 1041 b name? = 4 value or expression? # variable definition 1042 print(a*b arguments?)1043 print(f"{a} times {b}) equals {a*b}"arguments?)1044 t name? = (True, 42)value or expression? # variable definition 1045 print(t.item_0 arguments?)1046 print(t.item_1 arguments?)1047 # end main +static void main() { 1048 Console.WriteLine("Hello"arguments?); // print statement 1049 var a name? = 3 value or expression?;1050 var b name? = 4 value or expression?;1051 Console.WriteLine(a*b arguments?); // print statement 1052 Console.WriteLine($"{a} times {b}) equals {a*b}"arguments?); // print statement 1053 var t name? = (true, 42)value or expression?;1054 Console.WriteLine(t.item_0 arguments?); // print statement 1055 Console.WriteLine(t.item_1 arguments?); // print statement 1056 } // end main +Sub main() 1057 Console.WriteLine("Hello"arguments?) ' print statement 1058 Dim a name? = 3 value or expression? ' variable definition 1059 Dim b name? = 4 value or expression? ' variable definition 1060 Console.WriteLine(a*b arguments?) ' print statement 1061 Console.WriteLine($"{a} times {b}) equals {a*b}"arguments?) ' print statement 1062 Dim t name? = (True, 42)value or expression? ' variable definition 1063 Console.WriteLine(t.item_0 arguments?) ' print statement 1064 Console.WriteLine(t.item_1 arguments?) ' print statement 1065 End Sub +static void main() { 1066 System.out.println("Hello"arguments?); // print statement 1067 var a name? = 3 value or expression?;1068 var b name? = 4 value or expression?;1069 System.out.println(a*b arguments?); // print statement 1070 System.out.println(String.format("% times %) equals %", a, b, a*b)arguments?); // print statement 1071 var t name? = (true, 42)value or expression?;1072 System.out.println(t.item_0 arguments?); // print statement 1073 System.out.println(t.item_1 arguments?); // print statement 1074 } // end main | ⟶ ⟶ ⟶ ⟶ ⟶ | Hello 12 3 times 4 equals 12 [using interpolated strings ] [defining a 2-Tuple ] true 42

● Procedure printTab helps in the layout of information printed to the display, e.g. when printing columns of data:

+main 1075 call printTab procedureName?(0, "Number"arguments?)1076 call printTab procedureName?(10, "Square"arguments?)1077 call printTab procedureName?(20, "Cube\n"arguments?)1078 +for i item? in range(1, 11)source? 1079 call printTab procedureName?(0, i.toString()arguments?)1080 call printTab procedureName?(10, $"{pow(i, 2)}"arguments?)1081 call printTab procedureName?(20, $"{pow(i, 3)}\n"arguments?)1082 end for end main
+def main() -> None: 1083 printTab procedureName?(0, "Number"arguments?) # procedure call 1084 printTab procedureName?(10, "Square"arguments?) # procedure call 1085 printTab procedureName?(20, "Cube\n"arguments?) # procedure call 1086 +for i item? in range(1, 11)source?: 1087 printTab procedureName?(0, i.toString()arguments?) # procedure call 1088 printTab procedureName?(10, f"{pow(i, 2)}"arguments?) # procedure call 1089 printTab procedureName?(20, f"{pow(i, 3)}\n"arguments?) # procedure call 1090 # end for # end main
+static void main() { 1091 printTab procedureName?(0, "Number"arguments?); // procedure call 1092 printTab procedureName?(10, "Square"arguments?); // procedure call 1093 printTab procedureName?(20, "Cube\n"arguments?); // procedure call 1094 +foreach (var i item? in range(1, 11)source?) { 1095 printTab procedureName?(0, i.toString()arguments?); // procedure call 1096 printTab procedureName?(10, $"{pow(i, 2)}"arguments?); // procedure call 1097 printTab procedureName?(20, $"{pow(i, 3)}\n"arguments?); // procedure call 1098 } // end foreach } // end main
+Sub main() 1099 printTab procedureName?(0, "Number"arguments?) ' procedure call 1100 printTab procedureName?(10, "Square"arguments?) ' procedure call 1101 printTab procedureName?(20, "Cube\n"arguments?) ' procedure call 1102 +For Each i item? In range(1, 11)source? 1103 printTab procedureName?(0, i.toString()arguments?) ' procedure call 1104 printTab procedureName?(10, $"{pow(i, 2)}"arguments?) ' procedure call 1105 printTab procedureName?(20, $"{pow(i, 3)}\n"arguments?) ' procedure call 1106 Next i End Sub
+static void main() { 1107 printTab procedureName?(0, "Number"arguments?); // procedure call 1108 printTab procedureName?(10, "Square"arguments?); // procedure call 1109 printTab procedureName?(20, "Cube\n"arguments?); // procedure call 1110 +foreach (var i item? in range(1, 11)source?) { 1111 printTab procedureName?(0, i.toString()arguments?); // procedure call 1112 printTab procedureName?(10, String.format("%", pow(i, 2))arguments?); // procedure call 1113 printTab procedureName?(20, String.format("%\n", pow(i, 3))arguments?); // procedure call 1114 } // end foreach } // end main

● For numeric output, it is preferable to right-align the columns, e.g. when listing powers of 9:

main
main
main
main
main

## Type instance procedures

Procedures applicable to standard Reference types are linked from:

- Procedure methods on a `ListlistListListList` 
- Procedure methods on a `DictionaryDictionaryDictionaryDictionaryDictionary` 
- Procedure methods on a `TurtleTurtleTurtleTurtleTurtle` 

User-defined Classes may have procedures that can be applied to their Class instances.

# Library methods

These methods may be referenced from within a function.

## Standalone functions

Standalone library functions always return a value and are therefore used in contexts that expect a value, such as in the right-hand side of a variable definition declaration or a reassign variable, either on their own or within a more complex expression.

Standalone library functions require at least one argument to be passed (in round brackets), corresponding to the parameters defined for that function.

system method | argument types | return types | returns
--- | --- | --- | ---
sFloat | `StringstrstringStringString` | `FloatfloatdoubleDoubledouble` | Will throw an exception if the string does not parse as an integer
asInt | `StringstrstringStringString` | `IntintintIntegerint` | Will throw an exception if the string does not parse as an integer
unicode | `IntintintIntegerint` | `StringstrstringStringString` | a string containing the one character defined at the given Unicode code point

#### Examples using standalone functions

● Deconstructing the 2-Tuple returned by parseAsInt:

`variable successname? set to parseAsInt(s).item_0value or expression?180successname? = parseAsInt(s).item_0value or expression? # variable definition181var successname? = parseAsInt(s).item_0value or expression?;182Dim successname? = parseAsInt(s).item_0value or expression? ' variable definition183var successname? = parseAsInt(s).item_0value or expression?;184` `variable valuename? set to parseAsInt(s).item_1value or expression?185valuename? = parseAsInt(s).item_1value or expression? # variable definition186var valuename? = parseAsInt(s).item_1value or expression?;187Dim valuename? = parseAsInt(s).item_1value or expression? ' variable definition188var valuename? = parseAsInt(s).item_1value or expression?;189`

Always check the `BooleanboolboolBooleanboolean` (`successsuccesssuccesssuccesssuccess`) before using the returned value (`valuevaluevaluevaluevalue`) in case the latter is zero only because the parse was unsuccessful.

● Test assertions that use methods parseAsInt and parseAsFloat:

+test test_parse test_name? 1115 assert parseAsInt("31")actual (computed) value? is (true, 31)expected value? not run 1116 assert parseAsInt("0")actual (computed) value? is (true, 0)expected value? not run 1117 assert parseAsInt("thirty one")actual (computed) value? is (false, 0)expected value? not run 1118 assert parseAsInt("3.1")actual (computed) value? is (false, 0)expected value? not run 1119 assert parseAsFloat("31")actual (computed) value? is (true, 31)expected value? not run 1120 assert parseAsFloat("0")actual (computed) value? is (true, 0)expected value? not run 1121 assert parseAsFloat("3.1")actual (computed) value? is (true, 3.1)expected value? not run 1122 end test
+class Test_parse(unittest.TestCase):
def test_parse test_name?(self) -> None: 1123 self.assertEqual(parseAsInt("31")actual (computed) value?, (True, 31)expected value?) not run 1124 self.assertEqual(parseAsInt("0")actual (computed) value?, (True, 0)expected value?) not run 1125 self.assertEqual(parseAsInt("thirty one")actual (computed) value?, (False, 0)expected value?) not run 1126 self.assertEqual(parseAsInt("3.1")actual (computed) value?, (False, 0)expected value?) not run 1127 self.assertEqual(parseAsFloat("31")actual (computed) value?, (True, 31)expected value?) not run 1128 self.assertEqual(parseAsFloat("0")actual (computed) value?, (True, 0)expected value?) not run 1129 self.assertEqual(parseAsFloat("3.1")actual (computed) value?, (True, 3.1)expected value?) not run 1130 # end test
+[TestClass] class Test_parse
[TestMethod] static void test_parse test_name?() { 1131 Assert.AreEqual((true, 31)expected value?, parseAsInt("31")actual (computed) value?); not run 1132 Assert.AreEqual((true, 0)expected value?, parseAsInt("0")actual (computed) value?); not run 1133 Assert.AreEqual((false, 0)expected value?, parseAsInt("thirty one")actual (computed) value?); not run 1134 Assert.AreEqual((false, 0)expected value?, parseAsInt("3.1")actual (computed) value?); not run 1135 Assert.AreEqual((true, 31)expected value?, parseAsFloat("31")actual (computed) value?); not run 1136 Assert.AreEqual((true, 0)expected value?, parseAsFloat("0")actual (computed) value?); not run 1137 Assert.AreEqual((true, 3.1)expected value?, parseAsFloat("3.1")actual (computed) value?); not run 1138 }} // end test
+<TestClass Class Test_parse
<TestMethod> Sub test_parse test_name?() 1139 Assert.AreEqual((True, 31)expected value?, parseAsInt("31")actual (computed) value?) not run 1140 Assert.AreEqual((True, 0)expected value?, parseAsInt("0")actual (computed) value?) not run 1141 Assert.AreEqual((False, 0)expected value?, parseAsInt("thirty one")actual (computed) value?) not run 1142 Assert.AreEqual((False, 0)expected value?, parseAsInt("3.1")actual (computed) value?) not run 1143 Assert.AreEqual((True, 31)expected value?, parseAsFloat("31")actual (computed) value?) not run 1144 Assert.AreEqual((True, 0)expected value?, parseAsFloat("0")actual (computed) value?) not run 1145 Assert.AreEqual((True, 3.1)expected value?, parseAsFloat("3.1")actual (computed) value?) not run 1146 End Sub
End Class
+class Test_parse {
@Test static void test_parse test_name?() { 1147 assertEquals((true, 31)expected value?, parseAsInt("31")actual (computed) value?); not run 1148 assertEquals((true, 0)expected value?, parseAsInt("0")actual (computed) value?); not run 1149 assertEquals((false, 0)expected value?, parseAsInt("thirty one")actual (computed) value?); not run 1150 assertEquals((false, 0)expected value?, parseAsInt("3.1")actual (computed) value?); not run 1151 assertEquals((true, 31)expected value?, parseAsFloat("31")actual (computed) value?); not run 1152 assertEquals((true, 0)expected value?, parseAsFloat("0")actual (computed) value?); not run 1153 assertEquals((true, 3.1)expected value?, parseAsFloat("3.1")actual (computed) value?); not run 1154 }} // end test

##### Notes

- Any string that parses as an `IntintintIntegerint` will also parse as a `FloatfloatdoubleDoubledouble`.
- When validating user input,it may be easier to use the various input methods .

● Using method unicode:

`print(unicode(0x2665)arguments?)190print(unicode(0x2665)arguments?)191Console.WriteLine(unicode(0x2665)arguments?); // print statement192Console.WriteLine(unicode(&H2665)arguments?) ' print statement193System.out.println(unicode(0x2665)arguments?); // print statement194` | ⟶ | ♥

## Maths functions

All the maths functions expect `FloatfloatdoubleDoubledouble` arguments, but `IntintintIntegerint` arguments are accepted. They all return a value of type `FloatfloatdoubleDoubledouble`, except for divAsInt which returns an `IntintintIntegerint`.

function | argument type | input unit | returns | output unit
--- | --- | --- | --- | ---
abs | `FloatfloatdoubleDoubledouble` |  | absolute value of the input |
divAsFloat | `FloatfloatdoubleDoubledouble`, `FloatfloatdoubleDoubledouble` |  | first input value divided by second input value |
divAsInt | `FloatfloatdoubleDoubledouble`, `FloatfloatdoubleDoubledouble` |  | first input value divided by second input value and result rounded down to integer |
pow | `FloatfloatdoubleDoubledouble`, `FloatfloatdoubleDoubledouble` |  | result of raising first input to the power of the second |
sqrt | `FloatfloatdoubleDoubledouble` |  | positive square root of the input |
exp | `FloatfloatdoubleDoubledouble` |  | 𝑒𝑥 where 𝑥 is the argument and 𝑒 is Euler's number 2.718281828459045.. the base of natural logarithms |
logE | `FloatfloatdoubleDoubledouble` |  | natural logarithm of the input |
log10 | `FloatfloatdoubleDoubledouble` |  | base-10 logarithm of the input |
log2 | `FloatfloatdoubleDoubledouble` |  | base-2 logarithm of the input |
sin | `FloatfloatdoubleDoubledouble` | radians | sine of the input |
cos | `FloatfloatdoubleDoubledouble` | radians | cosine of the input |
tan | `FloatfloatdoubleDoubledouble` | radians | tangent of the input |
asin | `FloatfloatdoubleDoubledouble` |  | arcsine of the input | radians
acos | `FloatfloatdoubleDoubledouble` |  | arccosine of the input | radians
atan | `FloatfloatdoubleDoubledouble` |  | arctangent of the input | radians
radians | `FloatfloatdoubleDoubledouble` | degrees | converts input from degrees to radians | radians
degrees | `FloatfloatdoubleDoubledouble` | radians | converts input from radians to degrees | degrees

Examples of some maths functions and constants being tested:

+test test_maths test_name? 1155 assert pi actual (computed) value? is 3.141592653589793 expected value? not run 1156 assert abs(-3.7)actual (computed) value? is 3.7 expected value? not run 1157 assert pow(2, 10)actual (computed) value? is 1024 expected value? not run 1158 assert sqrt(2).round(3)actual (computed) value? is 1.414 expected value? not run 1159 assert asin(0.5).round(3)actual (computed) value? is 0.524 expected value? not run 1160 assert acos(0.5).round(3)actual (computed) value? is 1.047 expected value? not run 1161 assert atan(1).round(2)actual (computed) value? is 0.79 expected value? not run 1162 assert sin(pi/6).round(2)actual (computed) value? is 0.5 expected value? not run 1163 assert cos(pi/4).round(3)actual (computed) value? is 0.707 expected value? not run 1164 assert tan(pi/4).round(2)actual (computed) value? is 1 expected value? not run 1165 assert exp(2).round(3)actual (computed) value? is 7.389 expected value? not run 1166 assert logE(7.389).round(2)actual (computed) value? is 2 expected value? not run 1167 assert log10(1000)actual (computed) value? is 3 expected value? not run 1168 assert log2(65536)actual (computed) value? is 16 expected value? not run 1169 assert log2(0x10000)actual (computed) value? is 16 expected value? not run 1170 end test
+class Test_maths(unittest.TestCase):
def test_maths test_name?(self) -> None: 1171 self.assertEqual(pi actual (computed) value?, 3.141592653589793 expected value?) not run 1172 self.assertEqual(abs(-3.7)actual (computed) value?, 3.7 expected value?) not run 1173 self.assertEqual(pow(2, 10)actual (computed) value?, 1024 expected value?) not run 1174 self.assertEqual(sqrt(2).round(3)actual (computed) value?, 1.414 expected value?) not run 1175 self.assertEqual(asin(0.5).round(3)actual (computed) value?, 0.524 expected value?) not run 1176 self.assertEqual(acos(0.5).round(3)actual (computed) value?, 1.047 expected value?) not run 1177 self.assertEqual(atan(1).round(2)actual (computed) value?, 0.79 expected value?) not run 1178 self.assertEqual(sin(pi/6).round(2)actual (computed) value?, 0.5 expected value?) not run 1179 self.assertEqual(cos(pi/4).round(3)actual (computed) value?, 0.707 expected value?) not run 1180 self.assertEqual(tan(pi/4).round(2)actual (computed) value?, 1 expected value?) not run 1181 self.assertEqual(exp(2).round(3)actual (computed) value?, 7.389 expected value?) not run 1182 self.assertEqual(logE(7.389).round(2)actual (computed) value?, 2 expected value?) not run 1183 self.assertEqual(log10(1000)actual (computed) value?, 3 expected value?) not run 1184 self.assertEqual(log2(65536)actual (computed) value?, 16 expected value?) not run 1185 self.assertEqual(log2(0x10000)actual (computed) value?, 16 expected value?) not run 1186 # end test
+[TestClass] class Test_maths
[TestMethod] static void test_maths test_name?() { 1187 Assert.AreEqual(3.141592653589793 expected value?, pi actual (computed) value?); not run 1188 Assert.AreEqual(3.7 expected value?, abs(-3.7)actual (computed) value?); not run 1189 Assert.AreEqual(1024 expected value?, pow(2, 10)actual (computed) value?); not run 1190 Assert.AreEqual(1.414 expected value?, sqrt(2).round(3)actual (computed) value?); not run 1191 Assert.AreEqual(0.524 expected value?, asin(0.5).round(3)actual (computed) value?); not run 1192 Assert.AreEqual(1.047 expected value?, acos(0.5).round(3)actual (computed) value?); not run 1193 Assert.AreEqual(0.79 expected value?, atan(1).round(2)actual (computed) value?); not run 1194 Assert.AreEqual(0.5 expected value?, sin(pi/6).round(2)actual (computed) value?); not run 1195 Assert.AreEqual(0.707 expected value?, cos(pi/4).round(3)actual (computed) value?); not run 1196 Assert.AreEqual(1 expected value?, tan(pi/4).round(2)actual (computed) value?); not run 1197 Assert.AreEqual(7.389 expected value?, exp(2).round(3)actual (computed) value?); not run 1198 Assert.AreEqual(2 expected value?, logE(7.389).round(2)actual (computed) value?); not run 1199 Assert.AreEqual(3 expected value?, log10(1000)actual (computed) value?); not run 1200 Assert.AreEqual(16 expected value?, log2(65536)actual (computed) value?); not run 1201 Assert.AreEqual(16 expected value?, log2(0x10000)actual (computed) value?); not run 1202 }} // end test
+<TestClass Class Test_maths
<TestMethod> Sub test_maths test_name?() 1203 Assert.AreEqual(3.141592653589793 expected value?, pi actual (computed) value?) not run 1204 Assert.AreEqual(3.7 expected value?, abs(-3.7)actual (computed) value?) not run 1205 Assert.AreEqual(1024 expected value?, pow(2, 10)actual (computed) value?) not run 1206 Assert.AreEqual(1.414 expected value?, sqrt(2).round(3)actual (computed) value?) not run 1207 Assert.AreEqual(0.524 expected value?, asin(0.5).round(3)actual (computed) value?) not run 1208 Assert.AreEqual(1.047 expected value?, acos(0.5).round(3)actual (computed) value?) not run 1209 Assert.AreEqual(0.79 expected value?, atan(1).round(2)actual (computed) value?) not run 1210 Assert.AreEqual(0.5 expected value?, sin(pi/6).round(2)actual (computed) value?) not run 1211 Assert.AreEqual(0.707 expected value?, cos(pi/4).round(3)actual (computed) value?) not run 1212 Assert.AreEqual(1 expected value?, tan(pi/4).round(2)actual (computed) value?) not run 1213 Assert.AreEqual(7.389 expected value?, exp(2).round(3)actual (computed) value?) not run 1214 Assert.AreEqual(2 expected value?, logE(7.389).round(2)actual (computed) value?) not run 1215 Assert.AreEqual(3 expected value?, log10(1000)actual (computed) value?) not run 1216 Assert.AreEqual(16 expected value?, log2(65536)actual (computed) value?) not run 1217 Assert.AreEqual(16 expected value?, log2(&H10000)actual (computed) value?) not run 1218 End Sub
End Class
+class Test_maths {
@Test static void test_maths test_name?() { 1219 assertEquals(3.141592653589793 expected value?, pi actual (computed) value?); not run 1220 assertEquals(3.7 expected value?, abs(-3.7)actual (computed) value?); not run 1221 assertEquals(1024 expected value?, pow(2, 10)actual (computed) value?); not run 1222 assertEquals(1.414 expected value?, sqrt(2).round(3)actual (computed) value?); not run 1223 assertEquals(0.524 expected value?, asin(0.5).round(3)actual (computed) value?); not run 1224 assertEquals(1.047 expected value?, acos(0.5).round(3)actual (computed) value?); not run 1225 assertEquals(0.79 expected value?, atan(1).round(2)actual (computed) value?); not run 1226 assertEquals(0.5 expected value?, sin(pi/6).round(2)actual (computed) value?); not run 1227 assertEquals(0.707 expected value?, cos(pi/4).round(3)actual (computed) value?); not run 1228 assertEquals(1 expected value?, tan(pi/4).round(2)actual (computed) value?); not run 1229 assertEquals(7.389 expected value?, exp(2).round(3)actual (computed) value?); not run 1230 assertEquals(2 expected value?, logE(7.389).round(2)actual (computed) value?); not run 1231 assertEquals(3 expected value?, log10(1000)actual (computed) value?); not run 1232 assertEquals(16 expected value?, log2(65536)actual (computed) value?); not run 1233 assertEquals(16 expected value?, log2(0x10000)actual (computed) value?); not run 1234 }} // end test

## Bitwise functions

These functions take in an integer value, and manipulate the bit representation of that value.

function | argument types | return type | returns
--- | --- | --- | ---
bitAnd | `IntintintIntegerint`, `IntintintIntegerint` | `IntintintIntegerint` | integer whose binary representation is the bitwise AND of the inputs
bitOr | `IntintintIntegerint`, `IntintintIntegerint` | `IntintintIntegerint` | integer whose binary representation is the bitwise OR of the inputs
bitNot | `IntintintIntegerint` | `IntintintIntegerint` | integer whose binary representation is the bitwise complement of the input
bitXor | `IntintintIntegerint`, `IntintintIntegerint` | `IntintintIntegerint` | integer whose binary representation is the bitwise XOR of the inputs
bitShiftL | `IntintintIntegerint`, `IntintintIntegerint` | `IntintintIntegerint` | integer bit shifted to the left by the value of the second argument, i.e. multiplied by 2 to the power of the second argument
bitShiftR | `IntintintIntegerint`, `IntintintIntegerint` | `IntintintIntegerint` | integer bit shifted to the right by the value of the second argument, i.e. divided by 2 to the power of the second argument

#### Examples of the bitwise functions being tested

● Examples of the bitwise functions being tested

+test test_bitwise test_name? 1235 variable a name? set to 13 value or expression?1236 assert a actual (computed) value? is 0xd expected value? not run 1237 assert a actual (computed) value? is 0b1101 expected value? not run 1238 assert a.asBinary()actual (computed) value? is "1101"expected value? not run 1239 variable b name? set to 30 value or expression?1240 assert b actual (computed) value? is 0b11110 expected value? not run 1241 assert bitAnd(a, b)actual (computed) value? is 0b1100 expected value? not run 1242 variable aob name? set to bitOr(a, b)value or expression?1243 assert aob actual (computed) value? is 0b11111 expected value? not run 1244 variable axb name? set to bitXor(a, b)value or expression?1245 assert axb actual (computed) value? is 0b10011 expected value? not run 1246 variable nota name? set to bitNot(a)value or expression?1247 assert nota actual (computed) value? is -14 expected value? not run 1248 variable aL name? set to bitShiftL(a, 2)value or expression?1249 assert aL actual (computed) value? is 0b110100 expected value? not run 1250 assert bitShiftR(a, 2)actual (computed) value? is 0b11 expected value? not run 1251 end test
+class Test_bitwise(unittest.TestCase):
def test_bitwise test_name?(self) -> None: 1252 a name? = 13 value or expression? # variable definition 1253 self.assertEqual(a actual (computed) value?, 0xd expected value?) not run 1254 self.assertEqual(a actual (computed) value?, 0b1101 expected value?) not run 1255 self.assertEqual(a.asBinary()actual (computed) value?, "1101"expected value?) not run 1256 b name? = 30 value or expression? # variable definition 1257 self.assertEqual(b actual (computed) value?, 0b11110 expected value?) not run 1258 self.assertEqual(bitAnd(a, b)actual (computed) value?, 0b1100 expected value?) not run 1259 aob name? = bitOr(a, b)value or expression? # variable definition 1260 self.assertEqual(aob actual (computed) value?, 0b11111 expected value?) not run 1261 axb name? = bitXor(a, b)value or expression? # variable definition 1262 self.assertEqual(axb actual (computed) value?, 0b10011 expected value?) not run 1263 nota name? = bitNot(a)value or expression? # variable definition 1264 self.assertEqual(nota actual (computed) value?, -14 expected value?) not run 1265 aL name? = bitShiftL(a, 2)value or expression? # variable definition 1266 self.assertEqual(aL actual (computed) value?, 0b110100 expected value?) not run 1267 self.assertEqual(bitShiftR(a, 2)actual (computed) value?, 0b11 expected value?) not run 1268 # end test
+[TestClass] class Test_bitwise
[TestMethod] static void test_bitwise test_name?() { 1269 var a name? = 13 value or expression?;1270 Assert.AreEqual(0xd expected value?, a actual (computed) value?); not run 1271 Assert.AreEqual(0b1101 expected value?, a actual (computed) value?); not run 1272 Assert.AreEqual("1101"expected value?, a.asBinary()actual (computed) value?); not run 1273 var b name? = 30 value or expression?;1274 Assert.AreEqual(0b11110 expected value?, b actual (computed) value?); not run 1275 Assert.AreEqual(0b1100 expected value?, bitAnd(a, b)actual (computed) value?); not run 1276 var aob name? = bitOr(a, b)value or expression?;1277 Assert.AreEqual(0b11111 expected value?, aob actual (computed) value?); not run 1278 var axb name? = bitXor(a, b)value or expression?;1279 Assert.AreEqual(0b10011 expected value?, axb actual (computed) value?); not run 1280 var nota name? = bitNot(a)value or expression?;1281 Assert.AreEqual(-14 expected value?, nota actual (computed) value?); not run 1282 var aL name? = bitShiftL(a, 2)value or expression?;1283 Assert.AreEqual(0b110100 expected value?, aL actual (computed) value?); not run 1284 Assert.AreEqual(0b11 expected value?, bitShiftR(a, 2)actual (computed) value?); not run 1285 }} // end test
+<TestClass Class Test_bitwise
<TestMethod> Sub test_bitwise test_name?() 1286 Dim a name? = 13 value or expression? ' variable definition 1287 Assert.AreEqual(&Hd expected value?, a actual (computed) value?) not run 1288 Assert.AreEqual(&B1101 expected value?, a actual (computed) value?) not run 1289 Assert.AreEqual("1101"expected value?, a.asBinary()actual (computed) value?) not run 1290 Dim b name? = 30 value or expression? ' variable definition 1291 Assert.AreEqual(&B11110 expected value?, b actual (computed) value?) not run 1292 Assert.AreEqual(&B1100 expected value?, bitAnd(a, b)actual (computed) value?) not run 1293 Dim aob name? = bitOr(a, b)value or expression? ' variable definition 1294 Assert.AreEqual(&B11111 expected value?, aob actual (computed) value?) not run 1295 Dim axb name? = bitXor(a, b)value or expression? ' variable definition 1296 Assert.AreEqual(&B10011 expected value?, axb actual (computed) value?) not run 1297 Dim nota name? = bitNot(a)value or expression? ' variable definition 1298 Assert.AreEqual(-14 expected value?, nota actual (computed) value?) not run 1299 Dim aL name? = bitShiftL(a, 2)value or expression? ' variable definition 1300 Assert.AreEqual(&B110100 expected value?, aL actual (computed) value?) not run 1301 Assert.AreEqual(&B11 expected value?, bitShiftR(a, 2)actual (computed) value?) not run 1302 End Sub
End Class
+class Test_bitwise {
@Test static void test_bitwise test_name?() { 1303 var a name? = 13 value or expression?;1304 assertEquals(0xd expected value?, a actual (computed) value?); not run 1305 assertEquals(0b1101 expected value?, a actual (computed) value?); not run 1306 assertEquals("1101"expected value?, a.asBinary()actual (computed) value?); not run 1307 var b name? = 30 value or expression?;1308 assertEquals(0b11110 expected value?, b actual (computed) value?); not run 1309 assertEquals(0b1100 expected value?, bitAnd(a, b)actual (computed) value?); not run 1310 var aob name? = bitOr(a, b)value or expression?;1311 assertEquals(0b11111 expected value?, aob actual (computed) value?); not run 1312 var axb name? = bitXor(a, b)value or expression?;1313 assertEquals(0b10011 expected value?, axb actual (computed) value?); not run 1314 var nota name? = bitNot(a)value or expression?;1315 assertEquals(-14 expected value?, nota actual (computed) value?); not run 1316 var aL name? = bitShiftL(a, 2)value or expression?;1317 assertEquals(0b110100 expected value?, aL actual (computed) value?); not run 1318 assertEquals(0b11 expected value?, bitShiftR(a, 2)actual (computed) value?); not run 1319 }} // end test

The result of bitNot(`aaaaa`) being `-14-14-14-14-14` , when a is `1313131313`, might be a surprise. But this is because the bitwise functions assume that the arguments are represented as 32-bit signed binary integers. So 13 is represented as
`0000000000000000000000000000110100000000000000000000000000001101000000000000000000000000000011010000000000000000000000000000110100000000000000000000000000001101`, and applying bitNot gives
`1111111111111111111111111111001011111111111111111111111111110010111111111111111111111111111100101111111111111111111111111111001011111111111111111111111111110010`which is the value `-14-14-14-14-14`in signed two's complement format,
the left-most bit being the sign (`00000` positive, `11111` negative).

## RegExp functions

Elan's regular expressions are modelled on those of JavaScript, including the syntax for literal regular expressions. See, for example this Guide to Regular Expressions .

More functions for using regular expressions will be added in a future release of Elan. For now:

The method matchesRegExp is applied to a `StringstrstringStringString` using dot syntax  and requires a `RegExpRegExpRegExpRegExpRegExp` parameter specified as a literal or as variable. It returns a `BooleanboolboolBooleanboolean`. For example:

+test test_matchesRegExp test_name? 1320 variable s1 name? set to "hello"value or expression?1321 variable s2 name? set to "World"value or expression?1322 variable r name? set to /^[a-z]*$/value or expression?1323 assert s1.matchesRegExp(r)actual (computed) value? is true expected value? not run 1324 assert s2.matchesRegExp(r)actual (computed) value? is false expected value? not run 1325 end test
+class Test_matchesRegExp(unittest.TestCase):
def test_matchesRegExp test_name?(self) -> None: 1326 s1 name? = "hello"value or expression? # variable definition 1327 s2 name? = "World"value or expression? # variable definition 1328 r name? = /^[a-z]*$/value or expression? # variable definition 1329 self.assertEqual(s1.matchesRegExp(r)actual (computed) value?, True expected value?) not run 1330 self.assertEqual(s2.matchesRegExp(r)actual (computed) value?, False expected value?) not run 1331 # end test
+[TestClass] class Test_matchesRegExp
[TestMethod] static void test_matchesRegExp test_name?() { 1332 var s1 name? = "hello"value or expression?;1333 var s2 name? = "World"value or expression?;1334 var r name? = /^[a-z]*$/value or expression?;1335 Assert.AreEqual(true expected value?, s1.matchesRegExp(r)actual (computed) value?); not run 1336 Assert.AreEqual(false expected value?, s2.matchesRegExp(r)actual (computed) value?); not run 1337 }} // end test
+<TestClass Class Test_matchesRegExp
<TestMethod> Sub test_matchesRegExp test_name?() 1338 Dim s1 name? = "hello"value or expression? ' variable definition 1339 Dim s2 name? = "World"value or expression? ' variable definition 1340 Dim r name? = /^(a-z)*$/value or expression? ' variable definition 1341 Assert.AreEqual(True expected value?, s1.matchesRegExp(r)actual (computed) value?) not run 1342 Assert.AreEqual(False expected value?, s2.matchesRegExp(r)actual (computed) value?) not run 1343 End Sub
End Class
+class Test_matchesRegExp {
@Test static void test_matchesRegExp test_name?() { 1344 var s1 name? = "hello"value or expression?;1345 var s2 name? = "World"value or expression?;1346 var r name? = /^[a-z]*$/value or expression?;1347 assertEquals(true expected value?, s1.matchesRegExp(r)actual (computed) value?); not run 1348 assertEquals(false expected value?, s2.matchesRegExp(r)actual (computed) value?); not run 1349 }} // end test

You can convert a valid string without `/..//..//..//..//../` delimiters to a `RegExpRegExpRegExpRegExpRegExp` using function asRegExp:

+test test_matchesRegExp test_name? 1350 variable s1 name? set to "hello"value or expression?1351 variable s2 name? set to "World"value or expression?1352 variable r name? set to "^[a-z]*$".asRegExp()value or expression?1353 assert s1.matchesRegExp(r)actual (computed) value? is true expected value? not run 1354 assert s2.matchesRegExp(r)actual (computed) value? is false expected value? not run 1355 end test
+class Test_matchesRegExp(unittest.TestCase):
def test_matchesRegExp test_name?(self) -> None: 1356 s1 name? = "hello"value or expression? # variable definition 1357 s2 name? = "World"value or expression? # variable definition 1358 r name? = "^[a-z]*$".asRegExp()value or expression? # variable definition 1359 self.assertEqual(s1.matchesRegExp(r)actual (computed) value?, True expected value?) not run 1360 self.assertEqual(s2.matchesRegExp(r)actual (computed) value?, False expected value?) not run 1361 # end test
+[TestClass] class Test_matchesRegExp
[TestMethod] static void test_matchesRegExp test_name?() { 1362 var s1 name? = "hello"value or expression?;1363 var s2 name? = "World"value or expression?;1364 var r name? = "^[a-z]*$".asRegExp()value or expression?;1365 Assert.AreEqual(true expected value?, s1.matchesRegExp(r)actual (computed) value?); not run 1366 Assert.AreEqual(false expected value?, s2.matchesRegExp(r)actual (computed) value?); not run 1367 }} // end test
+<TestClass Class Test_matchesRegExp
<TestMethod> Sub test_matchesRegExp test_name?() 1368 Dim s1 name? = "hello"value or expression? ' variable definition 1369 Dim s2 name? = "World"value or expression? ' variable definition 1370 Dim r name? = "^(a-z)*$".asRegExp()value or expression? ' variable definition 1371 Assert.AreEqual(True expected value?, s1.matchesRegExp(r)actual (computed) value?) not run 1372 Assert.AreEqual(False expected value?, s2.matchesRegExp(r)actual (computed) value?) not run 1373 End Sub
End Class
+class Test_matchesRegExp {
@Test static void test_matchesRegExp test_name?() { 1374 var s1 name? = "hello"value or expression?;1375 var s2 name? = "World"value or expression?;1376 var r name? = "^[a-z]*$".asRegExp()value or expression?;1377 assertEquals(true expected value?, s1.matchesRegExp(r)actual (computed) value?); not run 1378 assertEquals(false expected value?, s2.matchesRegExp(r)actual (computed) value?); not run 1379 }} // end test

Although it is recommended that literal regular expressions are written with `/..//..//..//..//../` delimiters, the ability to convert a `stringstringstringstringstring` allows you to input a regular expression into a running program.

# System methods

System methods appear to work like functions, because:

- they may require one or more arguments to be provided
- they always return a value
- they can be used in expressions

They are not, however, pure functions because:

- they may have a dependency on data that is not provided in an argument
- they may generate side effects, such as changing the screen display or writing to a file

Because of these properties, system methods may be used only within the main routine or a procedure. They may not be used inside a function that you have defined, because to do so would prevent the function from being pure.

You cannot write a system method yourself.

## Input/output

- Keyboard input 
- Text file input/output 

## Clock and random numbers

Methods random and randint cannot be used in a function because of their dependence on external factors, i.e. they are subject to side effects.
To obtain random numbers within a function, use type `RandomRandomRandomRandomRandom` .

system method | argument types | return types | returns
--- | --- | --- | ---
clock | (none) | `IntintintIntegerint` | the current value (in milliseconds) of a system clock. Useful for measuring elapsed time by comparing the values returned by two calls
random | (none) | `FloatfloatdoubleDoubledouble` | a random number in the range [0..1]
randint | `IntintintIntegerint`, `IntintintIntegerint` | `IntintintIntegerint` | a random number in the (inclusive) range between the two arguments

## System functions

These methods are pure functions and so may be referenced in your functions as well as in procedures:

system method | argument types | return types | returns
--- | --- | --- | ---
copy | named value of any type | same type as argument | a copy of the named value
createDictionary | `ListlistListListList` of 2-tuples, each containg a key:value pair | `Dictionary<of KeyType, ValueType>Dictionary[KeyType, ValueType]Dictionary<KeyType, ValueType>Dictionary(Of KeyType, ValueType)Dictionary<KeyType, ValueType>` | a Dictionary containing the specified key:value pairs
createPopulatedList | `IntintintIntegerint`, value of `ListlistListListList` item's type | `List<of ItemType>list[ItemType]List<ItemType>List(Of ItemType)List<ItemType>` | a List containing the specified number of items each initialised to the value in the second argument
createPopulatedListofLists | `IntintintIntegerint`, `IntintintIntegerint`, value of `ListlistListListList` item's type | `List<of List<of ItemType>>list[list[ItemType]]List<List<ItemType>>List(Of List(Of ItemType))List<List<ItemType>>` | a List of length the first argument containing that number of Lists each initialised to a List of length the second argument with each item therein initialised to the value in the third argument
max | `List<of Int>list[int]List<int>List(Of Integer)List<int>` or `List<of Float>list[float]List<double>List(Of Double)List<double>` | `IntintintIntegerint` or `FloatfloatdoubleDoubledouble` | the maximum value found in the List
min | `List<of Int>list[int]List<int>List(Of Integer)List<int>` or `List<of Float>list[float]List<double>List(Of Double)List<double>` | `IntintintIntegerint` or `FloatfloatdoubleDoubledouble` | the minimum value found in the List
range | `IntintintIntegerint`, `IntintintIntegerint` | `ListlistListListList` | a List containing the integers from the first argument to one less than the second argument. If the second argument is not greater than the first, then the empty List is returned
rangeInSteps | `IntintintIntegerint`, `IntintintIntegerint`, `IntintintIntegerint` | `ListlistListListList` | a List containing the integers from the first argument to one less than the second argument in increments specified by the third argument. If the third argument is negative, the second argument must be less than the first, and the integers returned will run from the first to one more than the second

#### Examples using range or rangeInSteps

● Print every second item in a List:

+main 1380 variable numbers name? set to ["zero", "one", "two", "three", "four", "five", "six"]value or expression?1381 +for n item? in rangeInSteps(0, numbers.length() + 1, 2)source? 1382 print(numbers[n]arguments?)1383 end for end main
+def main() -> None: 1384 numbers name? = ["zero", "one", "two", "three", "four", "five", "six"]value or expression? # variable definition 1385 +for n item? in rangeInSteps(0, numbers.length() + 1, 2)source?: 1386 print(numbers[n]arguments?)1387 # end for # end main
+static void main() { 1388 var numbers name? = new [] {"zero", "one", "two", "three", "four", "five", "six"}value or expression?;1389 +foreach (var n item? in rangeInSteps(0, numbers.length() + 1, 2)source?) { 1390 Console.WriteLine(numbers[n]arguments?); // print statement 1391 } // end foreach } // end main
+Sub main() 1392 Dim numbers name? = {"zero", "one", "two", "three", "four", "five", "six"}value or expression? ' variable definition 1393 +For Each n item? In rangeInSteps(0, numbers.length() + 1, 2)source? 1394 Console.WriteLine(numbers(n)arguments?) ' print statement 1395 Next n End Sub
+static void main() { 1396 var numbers name? = list("zero", "one", "two", "three", "four", "five", "six")value or expression?;1397 +foreach (var n item? in rangeInSteps(0, numbers.length() + 1, 2)source?) { 1398 System.out.println(numbers[n]arguments?); // print statement 1399 } // end foreach } // end main

● Using the Higher-order Function filter  to print the prime numbers less than a given limit:

+main 1400 print(primesFromList(range(2, 100))arguments?)1401 end main
+def main() -> None: 1402 print(primesFromList(range(2, 100))arguments?)1403 # end main
+static void main() { 1404 Console.WriteLine(primesFromList(range(2, 100))arguments?); // print statement 1405 } // end main
+Sub main() 1406 Console.WriteLine(primesFromList(range(2, 100))arguments?) ' print statement 1407 End Sub
+static void main() { 1408 System.out.println(primesFromList(range(2, 100))arguments?); // print statement 1409 } // end main

# Higher-order Functions (HoFs)

A higher-order Function (HoF) is one that takes in a reference to another function as a parameter. (Strictly speaking, a HoF may also be a function that returns another function, but Elan does not currently support that pattern.)

## Standard HoFs

The standard library contains several HoFs that are widely recognised and used within Functional Programming, namely:
filter , map  and reduce ,
and also provides:
sumBy , maxBy , minBy  and orderBy .

You cannot define your own Higher-order Functions.

## Library functions that process Lists

These dot methods may be called on any `ListlistListListList` or `StringstrstringStringString`. As Higher-order Functions they take either a `lambdalambdalambdalambdalambda` or a function reference as one of their arguments.

These are not yet fully documented but, for readers familiar with HoFs from another programming language, some examples are shown below.

### filter

You give a `ListlistListListList` to the Higher-order Function filter in order to return a new `ListlistListListList` containing a subset of items. The subset is chosen by a `lambdalambdalambdalambdalambda` that tests list item values and returns a Boolean to specify filtering in or out.

#### Example using filter

● Example from demo program pathfinder in which filter applies the `lambdalambdalambdalambdalambda` to the `nodesnodesnodesnodesnodes` (of Class `NodeNodeNodeNodeNode`) to find one that contains `ppppp` (of Class `PointPointPointPointPoint`):

+function getNodeFor name?(p as Point parameter definitions?) returns Node Type? 1410 variable matches name? set to this.nodes.filter(lambda n as Node => n.point.equals(p))value or expression?1411 return if_(matches.length() is 1, matches.head(), emptyNode())value or expression?1412 end function
+def getNodeFor name?(p: Point parameter definitions?) -> Node Type?: # function 1413 matches name? = self.nodes.filter(lambda n: Node: n.point.equals(p))value or expression? # variable definition 1414 return if_(matches.length() == 1, matches.head(), emptyNode())value or expression?1415 # end function
+static Node Type? getNodeFor name?(Point p parameter definitions?) { // function 1416 var matches name? = this.nodes.filter(Node n => n.point.equals(p))value or expression?;1417 return if_(matches.length() == 1, matches.head(), emptyNode())value or expression?;1418 } // end function
+Function getNodeFor name?(p As Point parameter definitions?) As Node Type? 1419 Dim matches name? = Me.nodes.filter(Function (n As Node) n.point.equals(p))value or expression? ' variable definition 1420 Return if_(matches.length() = 1, matches.head(), emptyNode())value or expression?1421 End Function
+static Node Type? getNodeFor name?(Point p parameter definitions?) { // function 1422 var matches name? = this.nodes.filter((Node n) -> n.point.equals(p))value or expression?;1423 return if_(matches.length() == 1, matches.head(), emptyNode())value or expression?;1424 } // end function

### map

The function map is used to apply a function to every item in a `ListlistListListList`, and return a new List. The function to be applied is usually specified as a `lambdalambdalambdalambdalambda` having a single argument of the type of the list's items, as in these examples:

#### Examples using map

● To cube each integer value in a list:

+main 1425 variable li name? set to [1, 2, 3, 4, 5]value or expression?1426 print(li.map(lambda n as Int => pow(n, 3))arguments?)1427 end main +def main() -> None: 1428 li name? = [1, 2, 3, 4, 5]value or expression? # variable definition 1429 print(li.map(lambda n: int: pow(n, 3))arguments?)1430 # end main +static void main() { 1431 var li name? = new [] {1, 2, 3, 4, 5}value or expression?;1432 Console.WriteLine(li.map(int n => pow(n, 3))arguments?); // print statement 1433 } // end main +Sub main() 1434 Dim li name? = {1, 2, 3, 4, 5}value or expression? ' variable definition 1435 Console.WriteLine(li.map(Function (n As Integer) pow(n, 3))arguments?) ' print statement 1436 End Sub +static void main() { 1437 var li name? = list(1, 2, 3, 4, 5)value or expression?;1438 System.out.println(li.map((int n) -> pow(n, 3))arguments?); // print statement 1439 } // end main | ⟶ | `[1, 8, 27, 125][1, 8, 27, 125]new [] {1, 8, 27, 125}{1, 8, 27, 125}list(1, 8, 27, 125)`

● To change each string in a list to upper case:

+main 1440 variable names name? set to ["Tom", "Dick", "Harriet"]value or expression?1441 print(names.map(lambda s as String => s.upperCase())arguments?)1442 end main +def main() -> None: 1443 names name? = ["Tom", "Dick", "Harriet"]value or expression? # variable definition 1444 print(names.map(lambda s: str: s.upperCase())arguments?)1445 # end main +static void main() { 1446 var names name? = new [] {"Tom", "Dick", "Harriet"}value or expression?;1447 Console.WriteLine(names.map(string s => s.upperCase())arguments?); // print statement 1448 } // end main +Sub main() 1449 Dim names name? = {"Tom", "Dick", "Harriet"}value or expression? ' variable definition 1450 Console.WriteLine(names.map(Function (s As String) s.upperCase())arguments?) ' print statement 1451 End Sub +static void main() { 1452 var names name? = list("Tom", "Dick", "Harriet")value or expression?;1453 System.out.println(names.map((String s) -> s.upperCase())arguments?); // print statement 1454 } // end main | ⟶ | [TOM, DICK, HARRIET]

● To reverse each string in the list of names using the function reverse:

+main 1455 print(names.map(lambda s as String => reverse(s))arguments?)1456 end main +def main() -> None: 1457 print(names.map(lambda s: str: reverse(s))arguments?)1458 # end main +static void main() { 1459 Console.WriteLine(names.map(string s => reverse(s))arguments?); // print statement 1460 } // end main +Sub main() 1461 Console.WriteLine(names.map(Function (s As String) reverse(s))arguments?) ' print statement 1462 End Sub +static void main() { 1463 System.out.println(names.map((String s) -> reverse(s))arguments?); // print statement 1464 } // end main | ⟶ | [moT, kciD, teirraH]

● And this example from demo program maze-generator:

variable n name? set to p.neighbouringPoints().map(lambda p as Point => getValue(p, g))value or expression?1465
n name? = p.neighbouringPoints().map(lambda p: Point: getValue(p, g))value or expression? # variable definition 1466
var n name? = p.neighbouringPoints().map(Point p => getValue(p, g))value or expression?;1467
Dim n name? = p.neighbouringPoints().map(Function (p As Point) getValue(p, g))value or expression? ' variable definition 1468
var n name? = p.neighbouringPoints().map((Point p) -> getValue(p, g))value or expression?;1469

### reduce

The function reduce is used to combine the items in a list in some way to produce a single result. This result may be of the same type as the items in the list, for example to:

- find the sum or sum-of-squares of a list of numeric values.
- concatenate, or combine in some other way, the items from a list of strings.

The result may, however, be of a different type than the items in the list, and may even be a data structure, for example to:

- generate a 3-tuple containing the sum, sum-of-squares, and count of numerical items,
- generate a dictionary of all the unique words in a list, with the number of times each word appears in the input list.

Method reduce requires two arguments:

1. the initial, or 'seed', value, of the type that you wish to be returned by the function specified in the second argument. For example, if you were finding the sum of a list of type `FloatfloatdoubleDoubledouble`, the initial seed value would typically be `0.00.00.00.00.0`. If you were creating a dictionary of words, the initial seed value would be an empty dictionary of the correct key and value types.
2. the function or `lambdalambdalambdalambdalambda` to be applied, which itself requires two arguments:
   1. the accumulating named value, which is therefore of the same type as the initial seed value, (This will be the return value of the function or `lambdalambdalambdalambdalambda`).
   2. the item to which the function is applied, which is therefore of the same type as the items in the input list.

In other words, the specified function or `lambdalambdalambdalambdalambda` is applied to each item of the input List in turn, in each case passing in the current value of the result. The function makes use of both to generate a new value for the result, replacing the current one for application to the next item. This is best understood by looking at the examples.

#### Examples using reduce

● To reduce the floating point values in a `ListlistListListList` to their sum:

+main 1470 variable n name? set to [0.1, 2, 2.5, 0.3, 5.75, 0.29]value or expression?1471 print(n.reduce(0.0, lambda sum as Float, m as Float => (sum + m).round(2))arguments?)1472 end main +def main() -> None: 1473 n name? = [0.1, 2, 2.5, 0.3, 5.75, 0.29]value or expression? # variable definition 1474 print(n.reduce(0.0, lambda sum: float, m: float: (sum + m).round(2))arguments?)1475 # end main +static void main() { 1476 var n name? = new [] {0.1, 2, 2.5, 0.3, 5.75, 0.29}value or expression?;1477 Console.WriteLine(n.reduce(0.0, double sum, double m => (sum + m).round(2))arguments?); // print statement 1478 } // end main +Sub main() 1479 Dim n name? = {0.1, 2, 2.5, 0.3, 5.75, 0.29}value or expression? ' variable definition 1480 Console.WriteLine(n.reduce(0.0, Function (sum As Double, m As Double) (sum + m).round(2))arguments?) ' print statement 1481 End Sub +static void main() { 1482 var n name? = list(0.1, 2, 2.5, 0.3, 5.75, 0.29)value or expression?;1483 System.out.println(n.reduce(0.0, (double sum, double m) -> (sum + m).round(2))arguments?); // print statement 1484 } // end main | ⟶ | `10.9410.9410.9410.9410.94`

##### Notes

- You usually need to round floating point values when outputting them.
- The inclusion of an integer in a `ListlistListListList` of floats is valid provided it is not the first value.

● To reverse the order of items in a `ListlistListListList`:

+main 1485 variable n name? set to [2, 3, 5, 7, 11, 13]value or expression?1486 variable nR name? set to new List<of Int>()value or expression?1487 variable eL name? set to new List<of Int>()value or expression?1488 print(n.reduce(eL, lambda nR as List<of Int>, m as Int => nR.withPrepend(m))arguments?)1489 end main +def main() -> None: 1490 n name? = [2, 3, 5, 7, 11, 13]value or expression? # variable definition 1491 nR name? = list[int]()value or expression? # variable definition 1492 eL name? = list[int]()value or expression? # variable definition 1493 print(n.reduce(eL, lambda nR: list[int], m: int: nR.withPrepend(m))arguments?)1494 # end main +static void main() { 1495 var n name? = new [] {2, 3, 5, 7, 11, 13}value or expression?;1496 var nR name? = new List<int>()value or expression?;1497 var eL name? = new List<int>()value or expression?;1498 Console.WriteLine(n.reduce(eL, List<int> nR, int m => nR.withPrepend(m))arguments?); // print statement 1499 } // end main +Sub main() 1500 Dim n name? = {2, 3, 5, 7, 11, 13}value or expression? ' variable definition 1501 Dim nR name? = New List(Of Integer)()value or expression? ' variable definition 1502 Dim eL name? = New List(Of Integer)()value or expression? ' variable definition 1503 Console.WriteLine(n.reduce(eL, Function (nR As List(Of Integer), m As Integer) nR.withPrepend(m))arguments?) ' print statement 1504 End Sub +static void main() { 1505 var n name? = list(2, 3, 5, 7, 11, 13)value or expression?;1506 var nR name? = new List<int>()value or expression?;1507 var eL name? = new List<int>()value or expression?;1508 System.out.println(n.reduce(eL, (List<int> nR, int m) -> nR.withPrepend(m))arguments?); // print statement 1509 } // end main | ⟶ | `[13, 11, 7, 5, 3, 2][13, 11, 7, 5, 3, 2]new [] {13, 11, 7, 5, 3, 2}{13, 11, 7, 5, 3, 2}list(13, 11, 7, 5, 3, 2)`

● To reverse the order of the words in a `StringstrstringStringString`, use reduce on a `ListlistListListList` of words (created by split and then reassembled by join):

+main 1510 variable s name? set to "'Twas brillig and the slithy toves"value or expression?1511 variable sR name? set to ""value or expression?1512 variable eL name? set to new List<of String>()value or expression?1513 assign sR variableName? to s.split(" ").reduce(eL, lambda sR as List<of String>, word as String => sR.withPrepend(word)).join(" ")value or expression?1514 print(sR arguments?)1515 end main +def main() -> None: 1516 s name? = "'Twas brillig and the slithy toves"value or expression? # variable definition 1517 sR name? = ""value or expression? # variable definition 1518 eL name? = list[str]()value or expression? # variable definition 1519 sR variableName? = s.split(" ").reduce(eL, lambda sR: list[str], word: str: sR.withPrepend(word)).join(" ")value or expression? # assignment 1520 print(sR arguments?)1521 # end main +static void main() { 1522 var s name? = "'Twas brillig and the slithy toves"value or expression?;1523 var sR name? = ""value or expression?;1524 var eL name? = new List<string>()value or expression?;1525 sR variableName? = s.split(" ").reduce(eL, List<string> sR, string word => sR.withPrepend(word)).join(" ")value or expression?; // assignment 1526 Console.WriteLine(sR arguments?); // print statement 1527 } // end main +Sub main() 1528 Dim s name? = "'Twas brillig and the slithy toves"value or expression? ' variable definition 1529 Dim sR name? = ""value or expression? ' variable definition 1530 Dim eL name? = New List(Of String)()value or expression? ' variable definition 1531 sR variableName? = s.split(" ").reduce(eL, Function (sR As List(Of String), word As String) sR.withPrepend(word)).join(" ")value or expression? ' assignment 1532 Console.WriteLine(sR arguments?) ' print statement 1533 End Sub +static void main() { 1534 var s name? = "'Twas brillig and the slithy toves"value or expression?;1535 var sR name? = ""value or expression?;1536 var eL name? = new List<String>()value or expression?;1537 sR variableName? = s.split(" ").reduce(eL, (List<String> sR, String word) -> sR.withPrepend(word)).join(" ")value or expression?; // assignment 1538 System.out.println(sR arguments?); // print statement 1539 } // end main | ⟶ | `"toves slithy the and brillig 'Twas""toves slithy the and brillig 'Twas""toves slithy the and brillig 'Twas""toves slithy the and brillig 'Twas""toves slithy the and brillig 'Twas"`

##### Note

- In these two examples on Lists, an empty List has to be defined for use as the first argument of reduce.

### maxBy and minBy

maxBy and minBy are dot methods on a `ListlistListListList`. They take a function as an argument, and return the list item corresponding to the maximum or minimum of the values returned by the function.

For simply finding the maximum or minimum value in a `ListlistListListList`, you can use max , min .

#### Examples using maxBy and minBy

● To find in a list the integer that has the highest last digit:

+main 1540 variable a name? set to [33, 4, 0, 92, 89, 55, 102]value or expression?1541 print(a.maxBy(lambda x as Int => x mod 10)arguments?)1542 end main +def main() -> None: 1543 a name? = [33, 4, 0, 92, 89, 55, 102]value or expression? # variable definition 1544 print(a.maxBy(lambda x: int: x % 10)arguments?)1545 # end main +static void main() { 1546 var a name? = new [] {33, 4, 0, 92, 89, 55, 102}value or expression?;1547 Console.WriteLine(a.maxBy(int x => x % 10)arguments?); // print statement 1548 } // end main +Sub main() 1549 Dim a name? = {33, 4, 0, 92, 89, 55, 102}value or expression? ' variable definition 1550 Console.WriteLine(a.maxBy(Function (x As Integer) x Mod 10)arguments?) ' print statement 1551 End Sub +static void main() { 1552 var a name? = list(33, 4, 0, 92, 89, 55, 102)value or expression?;1553 System.out.println(a.maxBy((int x) -> x % 10)arguments?); // print statement 1554 } // end main | ⟶ | `8989898989`

● To find in a list the the shortest string:

+main 1555 variable fruit name? set to ["apple", "orange", "pear"]value or expression?1556 print(fruit.minBy(lambda x as String => x.length())arguments?)1557 end main +def main() -> None: 1558 fruit name? = ["apple", "orange", "pear"]value or expression? # variable definition 1559 print(fruit.minBy(lambda x: str: x.length())arguments?)1560 # end main +static void main() { 1561 var fruit name? = new [] {"apple", "orange", "pear"}value or expression?;1562 Console.WriteLine(fruit.minBy(string x => x.length())arguments?); // print statement 1563 } // end main +Sub main() 1564 Dim fruit name? = {"apple", "orange", "pear"}value or expression? ' variable definition 1565 Console.WriteLine(fruit.minBy(Function (x As String) x.length())arguments?) ' print statement 1566 End Sub +static void main() { 1567 var fruit name? = list("apple", "orange", "pear")value or expression?;1568 System.out.println(fruit.minBy((String x) -> x.length())arguments?); // print statement 1569 } // end main | ⟶ | `pearpearpearpearpear`

### sumBy

sumBy calculates the numerical sum of the items generated by the specified lambda (or named function) which must return a floating point value. This does not mean that the list on which sumBy has to be of type `List<of Float>list[float]List<double>List(Of Double)List<double>`. However, the lambda must process each element in a way that returns a `FloatfloatdoubleDoubledouble`.

#### Examples using sumBy

This example is taken from the Best Fit demo (offered when the paradigm is set to functional) to calculate the various 'sigma' (sum of) terms needed to estimate the best fit line:

+function bestFitLine name?(points as List<of Point>parameter definitions?) returns (Float, Float)Type? 1570 let sumX name? be points.sumBy(lambda p as Point => p.x)value or expression?1571 let sumXsq name? be points.sumBy(lambda p as Point => p.x*p.x)value or expression?1572 let sumY name? be points.sumBy(lambda p as Point => p.y)value or expression?1573 let sumXY name? be points.sumBy(lambda p as Point => p.x*p.y)value or expression?1574 let n name? be points.length()value or expression?1575 let a name? be (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression?1576 let b name? be (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression?1577 return (a, b)value or expression?1578 end function
+def bestFitLine name?(points: list[Point]parameter definitions?) -> tuple[float, float]Type?: # function 1579 sumX name? = points.sumBy(lambda p: Point: p.x)value or expression? # let 1580 sumXsq name? = points.sumBy(lambda p: Point: p.x*p.x)value or expression? # let 1581 sumY name? = points.sumBy(lambda p: Point: p.y)value or expression? # let 1582 sumXY name? = points.sumBy(lambda p: Point: p.x*p.y)value or expression? # let 1583 n name? = points.length()value or expression? # let 1584 a name? = (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression? # let 1585 b name? = (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression? # let 1586 return (a, b)value or expression?1587 # end function
+static (double, double)Type? bestFitLine name?(List<Point> points parameter definitions?) { // function 1588 var sumX name? = points.sumBy(Point p => p.x)value or expression?; // let 1589 var sumXsq name? = points.sumBy(Point p => p.x*p.x)value or expression?; // let 1590 var sumY name? = points.sumBy(Point p => p.y)value or expression?; // let 1591 var sumXY name? = points.sumBy(Point p => p.x*p.y)value or expression?; // let 1592 var n name? = points.length()value or expression?; // let 1593 var a name? = (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression?; // let 1594 var b name? = (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression?; // let 1595 return (a, b)value or expression?;1596 } // end function
+Function bestFitLine name?(points As List(Of Point)parameter definitions?) As (Double, Double)Type? 1597 Dim sumX name? = points.sumBy(Function (p As Point) p.x)value or expression? ' let 1598 Dim sumXsq name? = points.sumBy(Function (p As Point) p.x*p.x)value or expression? ' let 1599 Dim sumY name? = points.sumBy(Function (p As Point) p.y)value or expression? ' let 1600 Dim sumXY name? = points.sumBy(Function (p As Point) p.x*p.y)value or expression? ' let 1601 Dim n name? = points.length()value or expression? ' let 1602 Dim a name? = (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression? ' let 1603 Dim b name? = (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression? ' let 1604 Return (a, b)value or expression?1605 End Function
+static (double, double)Type? bestFitLine name?(List<Point> points parameter definitions?) { // function 1606 var sumX name? = points.sumBy((Point p) -> p.x)value or expression?; // let 1607 var sumXsq name? = points.sumBy((Point p) -> p.x*p.x)value or expression?; // let 1608 var sumY name? = points.sumBy((Point p) -> p.y)value or expression?; // let 1609 var sumXY name? = points.sumBy((Point p) -> p.x*p.y)value or expression?; // let 1610 var n name? = points.length()value or expression?; // let 1611 var a name? = (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression?; // let 1612 var b name? = (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression?; // let 1613 return (a, b)value or expression?;1614 } // end function

### orderBy

orderBy takes a `lambdalambdalambdalambdalambda` that has two arguments of the same type as that of the `ListlistListListList` items to be re-ordered and compares them, returning a Boolean value that distinguishes between less than (or greater than) for numerics and before (or after) for strings.

#### Examples using orderBy

● To reorder integers in a `ListlistListListList`, using > for ascending (you would use < for descending):

variable numbers name? set to [27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23]value or expression?1615 numbers name? = [27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23]value or expression? # variable definition 1616 var numbers name? = new [] {27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23}value or expression?;1617 Dim numbers name? = {27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23}value or expression? ' variable definition 1618 var numbers name? = list(27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23)value or expression?;1619 | ⟶ | `[2, 3, 5, 7, 11, 13, 19, 23, 23, 27, 31, 37][2, 3, 5, 7, 11, 13, 19, 23, 23, 27, 31, 37]new [] {2, 3, 5, 7, 11, 13, 19, 23, 23, 27, 31, 37}{2, 3, 5, 7, 11, 13, 19, 23, 23, 27, 31, 37}list(2, 3, 5, 7, 11, 13, 19, 23, 23, 27, 31, 37)`

● To reorder strings in a `ListlistListListList`, using method isBefore for descending (you would use isAfter for ascending):

+main 1620 variable names name? set to ["Simon", "Pauline", "Jason", "Zelda", "Edith", "Lance", "Alice", "Paul"]value or expression?1621 print(names.orderBy(lambda x as String, y as String => x.isBefore(y))arguments?)1622 end main +def main() -> None: 1623 names name? = ["Simon", "Pauline", "Jason", "Zelda", "Edith", "Lance", "Alice", "Paul"]value or expression? # variable definition 1624 print(names.orderBy(lambda x: str, y: str: x.isBefore(y))arguments?)1625 # end main +static void main() { 1626 var names name? = new [] {"Simon", "Pauline", "Jason", "Zelda", "Edith", "Lance", "Alice", "Paul"}value or expression?;1627 Console.WriteLine(names.orderBy(string x, string y => x.isBefore(y))arguments?); // print statement 1628 } // end main +Sub main() 1629 Dim names name? = {"Simon", "Pauline", "Jason", "Zelda", "Edith", "Lance", "Alice", "Paul"}value or expression? ' variable definition 1630 Console.WriteLine(names.orderBy(Function (x As String, y As String) x.isBefore(y))arguments?) ' print statement 1631 End Sub +static void main() { 1632 var names name? = list("Simon", "Pauline", "Jason", "Zelda", "Edith", "Lance", "Alice", "Paul")value or expression?;1633 System.out.println(names.orderBy((String x, String y) -> x.isBefore(y))arguments?); // print statement 1634 } // end main | ⟶ | `["Zelda", "Simon", "Pauline", "Paul", "Lance", "Jason", "Edith", "Alice"]["Zelda", "Simon", "Pauline", "Paul", "Lance", "Jason", "Edith", "Alice"]new [] {"Zelda", "Simon", "Pauline", "Paul", "Lance", "Jason", "Edith", "Alice"}{"Zelda", "Simon", "Pauline", "Paul", "Lance", "Jason", "Edith", "Alice"}list("Zelda", "Simon", "Pauline", "Paul", "Lance", "Jason", "Edith", "Alice")`

## Passing a function as a reference

To use a Higher-order Function (HoF), you have to pass in a reference to a function. This can be either a `lambdalambdalambdalambdalambda` or the name of a function. It is also possible to use references to functions not in the context of HoFs.

On most occasions when you write the name of an existing function elsewhere in code your intent is to evaluate the function and, to do so, you write the name of the function followed by round brackets containing such arguments as are required by the function. When passing a function, its name is not followed by round brackets (or arguments), as in this example:

+class Pupil Name? inheritance?1635 property mathsPercent name? as Int Type?1636 +constructor(parameter definitions?) 1637 new code end constructor +function toString name?(parameter definitions?) returns String Type? 1638 return "undefined"value or expression?1639 end function end class
+class Pupil Name? inheritance?: # concrete class 1640 mathsPercent name?: int Type? # property 1641 +def __init__(self: Pupil) -> None: 1642 new code # end constructor +def toString name?(self: Pupil) -> str Type?: # function method 1643 return "undefined"value or expression?1644 # end function method # end class
+class Pupil Name? inheritance? {1645 public int Type? mathsPercent name? {get; private set;} // property 1646 +public Pupil(parameter definitions?) { 1647 new code } // end constructor +public string Type? toString name?(parameter definitions?) { // function method 1648 return "undefined"value or expression?;1649 } // end function method } // end class
+Class Pupil Name? inheritance?1650 Property mathsPercent name? As Integer Type?1651 +Sub New(parameter definitions?) 1652 new code End Sub +Function toString name?(parameter definitions?) As String Type? 1653 Return "undefined"value or expression?1654 End Function End Class
+class Pupil Name? inheritance? {1655 public int Type? mathsPercent name?; // property 1656 +public Pupil(parameter definitions?) { 1657 new code } // end constructor +public String Type? toString name?(parameter definitions?) { // function method 1658 return "undefined"value or expression?;1659 } // end function method } // end class

# System constants

System constants are unlike values that you define in your program constant , in that they are mutable named values, though it would be poor practice to change them.

## String constants

These constants are of use when the characters { } and " are required within a string.

name | type | value
--- | --- | ---
`openBraceopenBraceopenBraceopenBraceopenBrace` | `StringstrstringStringString` | {
`closeBracecloseBracecloseBracecloseBracecloseBrace` | `StringstrstringStringString` | }
`quotesquotesquotesquotesquotes` | `StringstrstringStringString` | "

## Maths constant

name | type | value
--- | --- | ---
`pipipipipi` | `FloatfloatdoubleDoubledouble` | 𝜋 = 3.141592653589793..

## Boolean constants

name | type | value
--- | --- | ---
`trueTruetrueTruetrue` | `BooleanboolboolBooleanboolean` | `trueTruetrueTruetrue` 
`falseFalsefalseFalsefalse` | `BooleanboolboolBooleanboolean` | `falseFalsefalseFalsefalse` 

## Colour constants

colour |  | decimal | decimal | hexadecimal
--- | --- | --- | --- | ---
name |  | integer | R G B | 0xrrggbb
`blackblackblackblackblack` | ◼ | 0 | 0 0 0 | `0x0000000x0000000x000000&H0000000x000000`
`whitewhitewhitewhitewhite` | ◼ | 16777215 | 255 255 255 | `0xffffff0xffffff0xffffff&Hffffff0xffffff`
`redredredredred` | ◼ | 16711680 | 255 0 0 | `0xff00000xff00000xff0000&Hff00000xff0000`
`greengreengreengreengreen` | ◼ | 32768 | 0 128 0 | `0x0080000x0080000x008000&H0080000x008000`
`blueblueblueblueblue` | ◼ | 255 | 0 0 255 | `0x0000ff0x0000ff0x0000ff&H0000ff0x0000ff`
`yellowyellowyellowyellowyellow` | ◼ | 16776960 | 255 255 0 | `0xffff000xffff000xffff00&Hffff000xffff00`
`brownbrownbrownbrownbrown` | ◼ | 10824234 | 165 42 42 | `0xa52a2a0xa52a2a0xa52a2a&Ha52a2a0xa52a2a`
`greygreygreygreygrey` | ◼ | 8421504 | 128 128 128 | `0x8080800x8080800x808080&H8080800x808080`
`transparenttransparenttransparenttransparenttransparent` | ◻ | -1 | n/a | n/a

A colour is specified as an `IntintintIntegerint` value using one of these methods:

- the limited colour names defined as library constants as in the above table.
- an integer in the decimal range 0 (`blackblackblackblackblack`) to 224-1 (`whitewhitewhitewhitewhite`).
- a six digit hexadecimal value in the range `0x0000000x0000000x000000&H0000000x000000` – `0xffffff0xffffff0xffffff&Hffffff0xffffff` using the same 'RGB' format as used in Html style, for example `0xff00000xff00000xff0000&Hff00000xff0000` for red.

`transparenttransparenttransparenttransparenttransparent` is used only for filling vector graphics  shapes.

Elan Library Reference go to the top 