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 hexname?(n as Intparameter definitions?) returns StringType?
195
variable hname? set to ""value or expression?196
+if (n < 1)condition? then
197
assign hvariableName? to "0"value or expression?198
else199
variable mname? set to nvalue or expression?200
+while m > 0condition?
201
assign hvariableName? to hexDigit(m mod 16) + hvalue or expression?202
assign mvariableName? to divAsInt(m, 16)value or expression?203
end while
end if
return hvalue or expression?204
end function
+def hexname?(n: intparameter definitions?) -> strType?:
# function205
hname? = ""value or expression? # variable definition206
+if (n < 1)condition?:
207
hvariableName? = "0"value or expression? # assignment208
else:209
mname? = nvalue or expression? # variable definition210
+while m > 0condition?:
211
hvariableName? = hexDigit(m % 16) + hvalue or expression? # assignment212
mvariableName? = divAsInt(m, 16)value or expression? # assignment213
# end while
# end if
return hvalue or expression?214
# end function
+static stringType? hexname?(int nparameter definitions?) {
// function215
var hname? = ""value or expression?;216
+if ((n < 1)condition?) {
217
hvariableName? = "0"value or expression?; // assignment218
} else {219
var mname? = nvalue or expression?;220
+while (m > 0condition?) {
221
hvariableName? = hexDigit(m % 16) + hvalue or expression?; // assignment222
mvariableName? = divAsInt(m, 16)value or expression?; // assignment223
} // end while
} // end if
return hvalue or expression?;224
} // end function
+Function hexname?(n As Integerparameter definitions?) As StringType?
225
Dim hname? = ""value or expression? ' variable definition226
+If (n < 1)condition? Then
227
hvariableName? = "0"value or expression? ' assignment228
Else229
Dim mname? = nvalue or expression? ' variable definition230
+While m > 0condition?
231
hvariableName? = hexDigit(m Mod 16) + hvalue or expression? ' assignment232
mvariableName? = divAsInt(m, 16)value or expression? ' assignment233
End While
End If
Return hvalue or expression?234
End Function
+static StringType? hexname?(int nparameter definitions?) {
// function235
var hname? = ""value or expression?;236
+if ((n < 1)condition?) {
237
hvariableName? = "0"value or expression?; // assignment238
} else {239
var mname? = nvalue or expression?;240
+while (m > 0condition?) {
241
hvariableName? = hexDigit(m % 16) + hvalue or expression?; // assignment242
mvariableName? = divAsInt(m, 16)value or expression?; // assignment243
} // end while
} // end if
return hvalue 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 nitem? in range(50, 73)source?
246
variable npname? set to pow(2, n).floor()value or expression?247
call printTabprocedureName?(n.toString().length(), $"{n}"arguments?)248
call printTabprocedureName?(30 - np.toString().length(), $"{np}\n"arguments?)249
end for
end main
+def main() -> None:
250
+for nitem? in range(50, 73)source?:
251
npname? = pow(2, n).floor()value or expression? # variable definition252
printTabprocedureName?(n.toString().length(), f"{n}"arguments?) # procedure call253
printTabprocedureName?(30 - np.toString().length(), f"{np}\n"arguments?) # procedure call254
# end for
# end main
+static void main() {
255
+foreach (var nitem? in range(50, 73)source?) {
256
var npname? = pow(2, n).floor()value or expression?;257
printTabprocedureName?(n.toString().length(), $"{n}"arguments?); // procedure call258
printTabprocedureName?(30 - np.toString().length(), $"{np}\n"arguments?); // procedure call259
} // end foreach
} // end main
+Sub main()
260
+For Each nitem? In range(50, 73)source?
261
Dim npname? = pow(2, n).floor()value or expression? ' variable definition262
printTabprocedureName?(n.toString().length(), $"{n}"arguments?) ' procedure call263
printTabprocedureName?(30 - np.toString().length(), $"{np}\n"arguments?) ' procedure call264
Next n
End Sub
+static void main() {
265
+foreach (var nitem? in range(50, 73)source?) {
266
var npname? = pow(2, n).floor()value or expression?;267
printTabprocedureName?(n.toString().length(), String.format("%", n)arguments?); // procedure call268
printTabprocedureName?(30 - np.toString().length(), String.format("%\n", np)arguments?); // procedure call269
} // 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 hoursWorkedname? set to 3.0value or expression?270
hoursWorkedname? = 3.0value or expression? # variable definition271
var hoursWorkedname? = 3.0value or expression?;272
Dim hoursWorkedname? = 3.0value or expression? ' variable definition273
var hoursWorkedname? = 3.0value 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 rname? set to 2.0value or expression?276
print($"area = {(pi*r*r).round(2)}"arguments?)277
end main
+def main() -> None:
278
rname? = 2.0value or expression? # variable definition279
print(f"area = {(pi*r*r).round(2)}"arguments?)280
# end main
+static void main() {
281
var rname? = 2.0value or expression?;282
Console.WriteLine($"area = {(pi*r*r).round(2)}"arguments?); // print statement283
} // end main
+Sub main()
284
Dim rname? = 2.0value or expression? ' variable definition285
Console.WriteLine($"area = {(pi*r*r).round(2)}"arguments?) ' print statement286
End Sub
+static void main() {
287
var rname? = 2.0value or expression?;288
System.out.println(String.format("area = %", (pi*r*r).round(2))arguments?); // print statement289
} // 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 dLname? set to new Dictionary<of String, Int>()value or expression?291
variable dLRefname? set to new AsRef<of Dictionary<of String, Int>>(dL)value or expression?292
call greekLettersprocedureName?(dLRefarguments?)293
assign dLvariableName? to dLRef.value()value or expression?294
print(dLarguments?)295
call printDprocedureName?(dLarguments?)296
print(getDItem(dL, "alpha")arguments?)297
end main
+def main() -> None:
298
dLname? = Dictionary[str, int]()value or expression? # variable definition299
dLRefname? = AsRef[Dictionary[str, int]](dL)value or expression? # variable definition300
greekLettersprocedureName?(dLRefarguments?) # procedure call301
dLvariableName? = dLRef.value()value or expression? # assignment302
print(dLarguments?)303
printDprocedureName?(dLarguments?) # procedure call304
print(getDItem(dL, "alpha")arguments?)305
# end main
+static void main() {
306
var dLname? = new Dictionary<string, int>()value or expression?;307
var dLRefname? = new AsRef<Dictionary<string, int>>(dL)value or expression?;308
greekLettersprocedureName?(dLRefarguments?); // procedure call309
dLvariableName? = dLRef.value()value or expression?; // assignment310
Console.WriteLine(dLarguments?); // print statement311
printDprocedureName?(dLarguments?); // procedure call312
Console.WriteLine(getDItem(dL, "alpha")arguments?); // print statement313
} // end main
+Sub main()
314
Dim dLname? = New Dictionary(Of String, Integer)()value or expression? ' variable definition315
Dim dLRefname? = New AsRef(Of Dictionary(Of String, Integer))(dL)value or expression? ' variable definition316
greekLettersprocedureName?(dLRefarguments?) ' procedure call317
dLvariableName? = dLRef.value()value or expression? ' assignment318
Console.WriteLine(dLarguments?) ' print statement319
printDprocedureName?(dLarguments?) ' procedure call320
Console.WriteLine(getDItem(dL, "alpha")arguments?) ' print statement321
End Sub
+static void main() {
322
var dLname? = new Dictionary<String, int>()value or expression?;323
var dLRefname? = new AsRef<Dictionary<String, int>>(dL)value or expression?;324
greekLettersprocedureName?(dLRefarguments?); // procedure call325
dLvariableName? = dLRef.value()value or expression?; // assignment326
System.out.println(dLarguments?); // print statement327
printDprocedureName?(dLarguments?); // procedure call328
System.out.println(getDItem(dL, "alpha")arguments?); // print statement329
} // 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 diname? set to createDictionary([("alpha", 1), ("beta", 2), ("gamma", 3)])value or expression?331
print(di["beta"]arguments?)332
end main
+def main() -> None:
333
diname? = createDictionary([("alpha", 1), ("beta", 2), ("gamma", 3)])value or expression? # variable definition334
print(di["beta"]arguments?)335
# end main
+static void main() {
336
var diname? = createDictionary(new [] {("alpha", 1), ("beta", 2), ("gamma", 3)})value or expression?;337
Console.WriteLine(di["beta"]arguments?); // print statement338
} // end main
+Sub main()
339
Dim diname? = createDictionary({("alpha", 1), ("beta", 2), ("gamma", 3)})value or expression? ' variable definition340
Console.WriteLine(di("beta")arguments?) ' print statement341
End Sub
+static void main() {
342
var diname? = createDictionary(list(("alpha", 1), ("beta", 2), ("gamma", 3)))value or expression?;343
System.out.println(di["beta"]arguments?); // print statement344
} // 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 stname? set to new HashSet<of Int>()value or expression?345
stname? = HashSet[int]()value or expression? # variable definition346
var stname? = new HashSet<int>()value or expression?;347
Dim stname? = New HashSet(Of Integer)()value or expression? ' variable definition348
var stname? = 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
StackStackStackStackStackandQueueQueueQueueQueueQueue 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 skname? set to new Stack<of String>()value or expression?351
print(sk.length()arguments?)352
assign skvariableName? to sk.push("apple")value or expression?353
assign skvariableName? to sk.push("banana")value or expression?354
assign skvariableName? to sk.push("cherry")value or expression?355
print(sk.length()arguments?)356
print(skarguments?)357
print(sk.peek()arguments?)358
print(sk.pop()arguments?)359
print(skarguments?)360
print(sk.pop().item_0arguments?)361
print(skarguments?)362
assign skvariableName? to sk.pop().item_1value or expression?363
print(skarguments?)364
end main
+def main() -> None:
365
skname? = Stack[str]()value or expression? # variable definition366
print(sk.length()arguments?)367
skvariableName? = sk.push("apple")value or expression? # assignment368
skvariableName? = sk.push("banana")value or expression? # assignment369
skvariableName? = sk.push("cherry")value or expression? # assignment370
print(sk.length()arguments?)371
print(skarguments?)372
print(sk.peek()arguments?)373
print(sk.pop()arguments?)374
print(skarguments?)375
print(sk.pop().item_0arguments?)376
print(skarguments?)377
skvariableName? = sk.pop().item_1value or expression? # assignment378
print(skarguments?)379
# end main
+static void main() {
380
var skname? = new Stack<string>()value or expression?;381
Console.WriteLine(sk.length()arguments?); // print statement382
skvariableName? = sk.push("apple")value or expression?; // assignment383
skvariableName? = sk.push("banana")value or expression?; // assignment384
skvariableName? = sk.push("cherry")value or expression?; // assignment385
Console.WriteLine(sk.length()arguments?); // print statement386
Console.WriteLine(skarguments?); // print statement387
Console.WriteLine(sk.peek()arguments?); // print statement388
Console.WriteLine(sk.pop()arguments?); // print statement389
Console.WriteLine(skarguments?); // print statement390
Console.WriteLine(sk.pop().item_0arguments?); // print statement391
Console.WriteLine(skarguments?); // print statement392
skvariableName? = sk.pop().item_1value or expression?; // assignment393
Console.WriteLine(skarguments?); // print statement394
} // end main
+Sub main()
395
Dim skname? = New Stack(Of String)()value or expression? ' variable definition396
Console.WriteLine(sk.length()arguments?) ' print statement397
skvariableName? = sk.push("apple")value or expression? ' assignment398
skvariableName? = sk.push("banana")value or expression? ' assignment399
skvariableName? = sk.push("cherry")value or expression? ' assignment400
Console.WriteLine(sk.length()arguments?) ' print statement401
Console.WriteLine(skarguments?) ' print statement402
Console.WriteLine(sk.peek()arguments?) ' print statement403
Console.WriteLine(sk.pop()arguments?) ' print statement404
Console.WriteLine(skarguments?) ' print statement405
Console.WriteLine(sk.pop().item_0arguments?) ' print statement406
Console.WriteLine(skarguments?) ' print statement407
skvariableName? = sk.pop().item_1value or expression? ' assignment408
Console.WriteLine(skarguments?) ' print statement409
End Sub
+static void main() {
410
var skname? = new Stack<String>()value or expression?;411
System.out.println(sk.length()arguments?); // print statement412
skvariableName? = sk.push("apple")value or expression?; // assignment413
skvariableName? = sk.push("banana")value or expression?; // assignment414
skvariableName? = sk.push("cherry")value or expression?; // assignment415
System.out.println(sk.length()arguments?); // print statement416
System.out.println(skarguments?); // print statement417
System.out.println(sk.peek()arguments?); // print statement418
System.out.println(sk.pop()arguments?); // print statement419
System.out.println(skarguments?); // print statement420
System.out.println(sk.pop().item_0arguments?); // print statement421
System.out.println(skarguments?); // print statement422
skvariableName? = sk.pop().item_1value or expression?; // assignment423
System.out.println(skarguments?); // print statement424
} // 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 quname? set to new Queue<of String>()value or expression?426
print(qu.length()arguments?)427
assign quvariableName? to qu.enqueue("apple")value or expression?428
assign quvariableName? to qu.enqueue("banana")value or expression?429
assign quvariableName? to qu.enqueue("cherry")value or expression?430
print(qu.length()arguments?)431
print(quarguments?)432
print(qu.peek()arguments?)433
print(qu.dequeue()arguments?)434
print(quarguments?)435
print(qu.dequeue().item_0arguments?)436
print(quarguments?)437
assign quvariableName? to qu.dequeue().item_1value or expression?438
print(quarguments?)439
end main
+def main() -> None:
440
quname? = Queue[str]()value or expression? # variable definition441
print(qu.length()arguments?)442
quvariableName? = qu.enqueue("apple")value or expression? # assignment443
quvariableName? = qu.enqueue("banana")value or expression? # assignment444
quvariableName? = qu.enqueue("cherry")value or expression? # assignment445
print(qu.length()arguments?)446
print(quarguments?)447
print(qu.peek()arguments?)448
print(qu.dequeue()arguments?)449
print(quarguments?)450
print(qu.dequeue().item_0arguments?)451
print(quarguments?)452
quvariableName? = qu.dequeue().item_1value or expression? # assignment453
print(quarguments?)454
# end main
+static void main() {
455
var quname? = new Queue<string>()value or expression?;456
Console.WriteLine(qu.length()arguments?); // print statement457
quvariableName? = qu.enqueue("apple")value or expression?; // assignment458
quvariableName? = qu.enqueue("banana")value or expression?; // assignment459
quvariableName? = qu.enqueue("cherry")value or expression?; // assignment460
Console.WriteLine(qu.length()arguments?); // print statement461
Console.WriteLine(quarguments?); // print statement462
Console.WriteLine(qu.peek()arguments?); // print statement463
Console.WriteLine(qu.dequeue()arguments?); // print statement464
Console.WriteLine(quarguments?); // print statement465
Console.WriteLine(qu.dequeue().item_0arguments?); // print statement466
Console.WriteLine(quarguments?); // print statement467
quvariableName? = qu.dequeue().item_1value or expression?; // assignment468
Console.WriteLine(quarguments?); // print statement469
} // end main
+Sub main()
470
Dim quname? = New Queue(Of String)()value or expression? ' variable definition471
Console.WriteLine(qu.length()arguments?) ' print statement472
quvariableName? = qu.enqueue("apple")value or expression? ' assignment473
quvariableName? = qu.enqueue("banana")value or expression? ' assignment474
quvariableName? = qu.enqueue("cherry")value or expression? ' assignment475
Console.WriteLine(qu.length()arguments?) ' print statement476
Console.WriteLine(quarguments?) ' print statement477
Console.WriteLine(qu.peek()arguments?) ' print statement478
Console.WriteLine(qu.dequeue()arguments?) ' print statement479
Console.WriteLine(quarguments?) ' print statement480
Console.WriteLine(qu.dequeue().item_0arguments?) ' print statement481
Console.WriteLine(quarguments?) ' print statement482
quvariableName? = qu.dequeue().item_1value or expression? ' assignment483
Console.WriteLine(quarguments?) ' print statement484
End Sub
+static void main() {
485
var quname? = new Queue<String>()value or expression?;486
System.out.println(qu.length()arguments?); // print statement487
quvariableName? = qu.enqueue("apple")value or expression?; // assignment488
quvariableName? = qu.enqueue("banana")value or expression?; // assignment489
quvariableName? = qu.enqueue("cherry")value or expression?; // assignment490
System.out.println(qu.length()arguments?); // print statement491
System.out.println(quarguments?); // print statement492
System.out.println(qu.peek()arguments?); // print statement493
System.out.println(qu.dequeue()arguments?); // print statement494
System.out.println(quarguments?); // print statement495
System.out.println(qu.dequeue().item_0arguments?); // print statement496
System.out.println(quarguments?); // print statement497
quvariableName? = qu.dequeue().item_1value or expression?; // assignment498
System.out.println(quarguments?); // print statement499
} // 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 tname? set to (3, "apple", true)value or expression?500
tname? = (3, "apple", True)value or expression? # variable definition501
var tname? = (3, "apple", true)value or expression?;502
Dim tname? = (3, "apple", True)value or expression? ' variable definition503
var tname? = (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 distanceBetweenname?(p1 as (Float, Float), p2 as (Float, Float)parameter definitions?) returns FloatType?
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 distanceBetweenname?(p1: tuple[float, float], p2: tuple[float, float]parameter definitions?) -> floatType?:
# function507
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 doubleType? distanceBetweenname?((double, double) p1, (double, double) p2parameter definitions?) {
// function509
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 distanceBetweenname?(p1 As (Double, Double), p2 As (Double, Double)parameter definitions?) As DoubleType?
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 doubleType? distanceBetweenname?((double, double) p1, (double, double) p2parameter definitions?) {
// function513
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 gridname? set to createBlockGraphics(white)value or expression?516
+while truecondition?
517
variable xname? set to randint(0, 39)value or expression?518
variable yname? set to randint(0, 29)value or expression?519
variable colourname? set to randint(0, white - 1)value or expression?520
assign grid[x][y]variableName? to colourvalue or expression?521
call displayBlocksprocedureName?(gridarguments?)522
end while
end main
+def main() -> None:
523
gridname? = createBlockGraphics(white)value or expression? # variable definition524
+while Truecondition?:
525
xname? = randint(0, 39)value or expression? # variable definition526
yname? = randint(0, 29)value or expression? # variable definition527
colourname? = randint(0, white - 1)value or expression? # variable definition528
grid[x][y]variableName? = colourvalue or expression? # assignment529
displayBlocksprocedureName?(gridarguments?) # procedure call530
# end while
# end main
+static void main() {
531
var gridname? = createBlockGraphics(white)value or expression?;532
+while (truecondition?) {
533
var xname? = randint(0, 39)value or expression?;534
var yname? = randint(0, 29)value or expression?;535
var colourname? = randint(0, white - 1)value or expression?;536
grid[x][y]variableName? = colourvalue or expression?; // assignment537
displayBlocksprocedureName?(gridarguments?); // procedure call538
} // end while
} // end main
+Sub main()
539
Dim gridname? = createBlockGraphics(white)value or expression? ' variable definition540
+While Truecondition?
541
Dim xname? = randint(0, 39)value or expression? ' variable definition542
Dim yname? = randint(0, 29)value or expression? ' variable definition543
Dim colourname? = randint(0, white - 1)value or expression? ' variable definition544
grid(x)(y)variableName? = colourvalue or expression? ' assignment545
displayBlocksprocedureName?(gridarguments?) ' procedure call546
End While
End Sub
+static void main() {
547
var gridname? = createBlockGraphics(white)value or expression?;548
+while (truecondition?) {
549
var xname? = randint(0, 39)value or expression?;550
var yname? = randint(0, 29)value or expression?;551
var colourname? = randint(0, white - 1)value or expression?;552
grid[x][y]variableName? = colourvalue or expression?; // assignment553
displayBlocksprocedureName?(gridarguments?); // procedure call554
} // 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 tname? set to new Turtle()value or expression?556
call t.placeAtprocedureName?(-75, 50arguments?)557
call t.showprocedureName?(arguments?)558
+for iitem? in range(1, 5)source?
559
call t.turnprocedureName?(90arguments?)560
call t.moveprocedureName?(80arguments?)561
call sleepprocedureName?(0.5arguments?)562
end for
end main
+def main() -> None:
563
tname? = Turtle()value or expression? # variable definition564
t.placeAtprocedureName?(-75, 50arguments?) # procedure call565
t.showprocedureName?(arguments?) # procedure call566
+for iitem? in range(1, 5)source?:
567
t.turnprocedureName?(90arguments?) # procedure call568
t.moveprocedureName?(80arguments?) # procedure call569
sleepprocedureName?(0.5arguments?) # procedure call570
# end for
# end main
+static void main() {
571
var tname? = new Turtle()value or expression?;572
t.placeAtprocedureName?(-75, 50arguments?); // procedure call573
t.showprocedureName?(arguments?); // procedure call574
+foreach (var iitem? in range(1, 5)source?) {
575
t.turnprocedureName?(90arguments?); // procedure call576
t.moveprocedureName?(80arguments?); // procedure call577
sleepprocedureName?(0.5arguments?); // procedure call578
} // end foreach
} // end main
+Sub main()
579
Dim tname? = New Turtle()value or expression? ' variable definition580
t.placeAtprocedureName?(-75, 50arguments?) ' procedure call581
t.showprocedureName?(arguments?) ' procedure call582
+For Each iitem? In range(1, 5)source?
583
t.turnprocedureName?(90arguments?) ' procedure call584
t.moveprocedureName?(80arguments?) ' procedure call585
sleepprocedureName?(0.5arguments?) ' procedure call586
Next i
End Sub
+static void main() {
587
var tname? = new Turtle()value or expression?;588
t.placeAtprocedureName?(-75, 50arguments?); // procedure call589
t.showprocedureName?(arguments?); // procedure call590
+foreach (var iitem? in range(1, 5)source?) {
591
t.turnprocedureName?(90arguments?); // procedure call592
t.moveprocedureName?(80arguments?); // procedure call593
sleepprocedureName?(0.5arguments?); // procedure call594
} // end foreach
} // end main

● To draw a fractal snowflake, using a procedure and recursion:
+main
595
variable tname? set to new Turtle()value or expression?596
call t.placeAtprocedureName?(-50, 30arguments?)597
call t.turnprocedureName?(90arguments?)598
call t.showprocedureName?(arguments?)599
+for iitem? in range(1, 4)source?
600
call drawSideprocedureName?(side, targuments?)601
call t.turnprocedureName?(120arguments?)602
end for
end main
+def main() -> None:
603
tname? = Turtle()value or expression? # variable definition604
t.placeAtprocedureName?(-50, 30arguments?) # procedure call605
t.turnprocedureName?(90arguments?) # procedure call606
t.showprocedureName?(arguments?) # procedure call607
+for iitem? in range(1, 4)source?:
608
drawSideprocedureName?(side, targuments?) # procedure call609
t.turnprocedureName?(120arguments?) # procedure call610
# end for
# end main
+static void main() {
611
var tname? = new Turtle()value or expression?;612
t.placeAtprocedureName?(-50, 30arguments?); // procedure call613
t.turnprocedureName?(90arguments?); // procedure call614
t.showprocedureName?(arguments?); // procedure call615
+foreach (var iitem? in range(1, 4)source?) {
616
drawSideprocedureName?(side, targuments?); // procedure call617
t.turnprocedureName?(120arguments?); // procedure call618
} // end foreach
} // end main
+Sub main()
619
Dim tname? = New Turtle()value or expression? ' variable definition620
t.placeAtprocedureName?(-50, 30arguments?) ' procedure call621
t.turnprocedureName?(90arguments?) ' procedure call622
t.showprocedureName?(arguments?) ' procedure call623
+For Each iitem? In range(1, 4)source?
624
drawSideprocedureName?(side, targuments?) ' procedure call625
t.turnprocedureName?(120arguments?) ' procedure call626
Next i
End Sub
+static void main() {
627
var tname? = new Turtle()value or expression?;628
t.placeAtprocedureName?(-50, 30arguments?); // procedure call629
t.turnprocedureName?(90arguments?); // procedure call630
t.showprocedureName?(arguments?); // procedure call631
+foreach (var iitem? in range(1, 4)source?) {
632
drawSideprocedureName?(side, targuments?); // procedure call633
t.turnprocedureName?(120arguments?); // procedure call634
} // 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 vgname? set to createVectorGraphics()value or expression?636
variable circname? set to new CircleVG()value or expression?637
call circ.setCentreXprocedureName?(20arguments?)638
call circ.setCentreYprocedureName?(20arguments?)639
call circ.setRadiusprocedureName?(5arguments?)640
call circ.setFillColourprocedureName?(greenarguments?)641
call circ.setStrokeColourprocedureName?(redarguments?)642
call circ.setStrokeWidthprocedureName?(2arguments?)643
call vg.appendprocedureName?(circarguments?)644
call displayVectorGraphicsprocedureName?(vgarguments?)645
end main
+def main() -> None:
646
vgname? = createVectorGraphics()value or expression? # variable definition647
circname? = CircleVG()value or expression? # variable definition648
circ.setCentreXprocedureName?(20arguments?) # procedure call649
circ.setCentreYprocedureName?(20arguments?) # procedure call650
circ.setRadiusprocedureName?(5arguments?) # procedure call651
circ.setFillColourprocedureName?(greenarguments?) # procedure call652
circ.setStrokeColourprocedureName?(redarguments?) # procedure call653
circ.setStrokeWidthprocedureName?(2arguments?) # procedure call654
vg.appendprocedureName?(circarguments?) # procedure call655
displayVectorGraphicsprocedureName?(vgarguments?) # procedure call656
# end main
+static void main() {
657
var vgname? = createVectorGraphics()value or expression?;658
var circname? = new CircleVG()value or expression?;659
circ.setCentreXprocedureName?(20arguments?); // procedure call660
circ.setCentreYprocedureName?(20arguments?); // procedure call661
circ.setRadiusprocedureName?(5arguments?); // procedure call662
circ.setFillColourprocedureName?(greenarguments?); // procedure call663
circ.setStrokeColourprocedureName?(redarguments?); // procedure call664
circ.setStrokeWidthprocedureName?(2arguments?); // procedure call665
vg.appendprocedureName?(circarguments?); // procedure call666
displayVectorGraphicsprocedureName?(vgarguments?); // procedure call667
} // end main
+Sub main()
668
Dim vgname? = createVectorGraphics()value or expression? ' variable definition669
Dim circname? = New CircleVG()value or expression? ' variable definition670
circ.setCentreXprocedureName?(20arguments?) ' procedure call671
circ.setCentreYprocedureName?(20arguments?) ' procedure call672
circ.setRadiusprocedureName?(5arguments?) ' procedure call673
circ.setFillColourprocedureName?(greenarguments?) ' procedure call674
circ.setStrokeColourprocedureName?(redarguments?) ' procedure call675
circ.setStrokeWidthprocedureName?(2arguments?) ' procedure call676
vg.appendprocedureName?(circarguments?) ' procedure call677
displayVectorGraphicsprocedureName?(vgarguments?) ' procedure call678
End Sub
+static void main() {
679
var vgname? = createVectorGraphics()value or expression?;680
var circname? = new CircleVG()value or expression?;681
circ.setCentreXprocedureName?(20arguments?); // procedure call682
circ.setCentreYprocedureName?(20arguments?); // procedure call683
circ.setRadiusprocedureName?(5arguments?); // procedure call684
circ.setFillColourprocedureName?(greenarguments?); // procedure call685
circ.setStrokeColourprocedureName?(redarguments?); // procedure call686
circ.setStrokeWidthprocedureName?(2arguments?); // procedure call687
vg.appendprocedureName?(circarguments?); // procedure call688
displayVectorGraphicsprocedureName?(vgarguments?); // procedure call689
} // end main

● To draw a circle that changes between red and green every second:
+main
690
variable vgname? set to new List<of VectorGraphic>()value or expression?691
variable circname? set to new CircleVG()value or expression?692
call circ.setCentreXprocedureName?(50arguments?)693
call circ.setCentreYprocedureName?(37.5arguments?)694
call circ.setRadiusprocedureName?(30arguments?)695
call circ.setFillColourprocedureName?(greenarguments?)696
call vg.appendprocedureName?(circarguments?)697
+while truecondition?
698
call displayVectorGraphicsprocedureName?(vgarguments?)699
call sleepprocedureName?(1arguments?)700
call circ.setFillColourprocedureName?(redarguments?)701
call displayVectorGraphicsprocedureName?(vgarguments?)702
call sleepprocedureName?(1arguments?)703
call circ.setFillColourprocedureName?(greenarguments?)704
end while
call displayVectorGraphicsprocedureName?(vgarguments?)705
end main
+def main() -> None:
706
vgname? = list[VectorGraphic]()value or expression? # variable definition707
circname? = CircleVG()value or expression? # variable definition708
circ.setCentreXprocedureName?(50arguments?) # procedure call709
circ.setCentreYprocedureName?(37.5arguments?) # procedure call710
circ.setRadiusprocedureName?(30arguments?) # procedure call711
circ.setFillColourprocedureName?(greenarguments?) # procedure call712
vg.appendprocedureName?(circarguments?) # procedure call713
+while Truecondition?:
714
displayVectorGraphicsprocedureName?(vgarguments?) # procedure call715
sleepprocedureName?(1arguments?) # procedure call716
circ.setFillColourprocedureName?(redarguments?) # procedure call717
displayVectorGraphicsprocedureName?(vgarguments?) # procedure call718
sleepprocedureName?(1arguments?) # procedure call719
circ.setFillColourprocedureName?(greenarguments?) # procedure call720
# end while
displayVectorGraphicsprocedureName?(vgarguments?) # procedure call721
# end main
+static void main() {
722
var vgname? = new List<VectorGraphic>()value or expression?;723
var circname? = new CircleVG()value or expression?;724
circ.setCentreXprocedureName?(50arguments?); // procedure call725
circ.setCentreYprocedureName?(37.5arguments?); // procedure call726
circ.setRadiusprocedureName?(30arguments?); // procedure call727
circ.setFillColourprocedureName?(greenarguments?); // procedure call728
vg.appendprocedureName?(circarguments?); // procedure call729
+while (truecondition?) {
730
displayVectorGraphicsprocedureName?(vgarguments?); // procedure call731
sleepprocedureName?(1arguments?); // procedure call732
circ.setFillColourprocedureName?(redarguments?); // procedure call733
displayVectorGraphicsprocedureName?(vgarguments?); // procedure call734
sleepprocedureName?(1arguments?); // procedure call735
circ.setFillColourprocedureName?(greenarguments?); // procedure call736
} // end while
displayVectorGraphicsprocedureName?(vgarguments?); // procedure call737
} // end main
+Sub main()
738
Dim vgname? = New List(Of VectorGraphic)()value or expression? ' variable definition739
Dim circname? = New CircleVG()value or expression? ' variable definition740
circ.setCentreXprocedureName?(50arguments?) ' procedure call741
circ.setCentreYprocedureName?(37.5arguments?) ' procedure call742
circ.setRadiusprocedureName?(30arguments?) ' procedure call743
circ.setFillColourprocedureName?(greenarguments?) ' procedure call744
vg.appendprocedureName?(circarguments?) ' procedure call745
+While Truecondition?
746
displayVectorGraphicsprocedureName?(vgarguments?) ' procedure call747
sleepprocedureName?(1arguments?) ' procedure call748
circ.setFillColourprocedureName?(redarguments?) ' procedure call749
displayVectorGraphicsprocedureName?(vgarguments?) ' procedure call750
sleepprocedureName?(1arguments?) ' procedure call751
circ.setFillColourprocedureName?(greenarguments?) ' procedure call752
End While
displayVectorGraphicsprocedureName?(vgarguments?) ' procedure call753
End Sub
+static void main() {
754
var vgname? = new List<VectorGraphic>()value or expression?;755
var circname? = new CircleVG()value or expression?;756
circ.setCentreXprocedureName?(50arguments?); // procedure call757
circ.setCentreYprocedureName?(37.5arguments?); // procedure call758
circ.setRadiusprocedureName?(30arguments?); // procedure call759
circ.setFillColourprocedureName?(greenarguments?); // procedure call760
vg.appendprocedureName?(circarguments?); // procedure call761
+while (truecondition?) {
762
displayVectorGraphicsprocedureName?(vgarguments?); // procedure call763
sleepprocedureName?(1arguments?); // procedure call764
circ.setFillColourprocedureName?(redarguments?); // procedure call765
displayVectorGraphicsprocedureName?(vgarguments?); // procedure call766
sleepprocedureName?(1arguments?); // procedure call767
circ.setFillColourprocedureName?(greenarguments?); // procedure call768
} // end while
displayVectorGraphicsprocedureName?(vgarguments?); // procedure call769
} // 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 movingCirclename? 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 rawname? set to (new RawVG()).withContent(movingCircle)value or expression?772
call displayVectorGraphicsprocedureName?([raw]arguments?)773
end main
+def main() -> None:
774
movingCirclename? = "<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 definition775
rawname? = (RawVG()).withContent(movingCircle)value or expression? # variable definition776
displayVectorGraphicsprocedureName?([raw]arguments?) # procedure call777
# end main
+static void main() {
778
var movingCirclename? = "<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 rawname? = (new RawVG()).withContent(movingCircle)value or expression?;780
displayVectorGraphicsprocedureName?(new [] {raw}arguments?); // procedure call781
} // end main
+Sub main()
782
Dim movingCirclename? = "<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 definition783
Dim rawname? = (New RawVG()).withContent(movingCircle)value or expression? ' variable definition784
displayVectorGraphicsprocedureName?({raw}arguments?) ' procedure call785
End Sub
+static void main() {
786
var movingCirclename? = "<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 rawname? = (new RawVG()).withContent(movingCircle)value or expression?;788
displayVectorGraphicsprocedureName?(list(raw)arguments?); // procedure call789
} // 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:
- Block graphics
- Vector or Turtle graphics
- 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 rndname? set to new Random()value or expression?791
call rnd.initialiseFromClockprocedureName?(arguments?)792
+for iitem? in range(1, 20)source?
793
print(randomThrow(rnd).item_0arguments?)794
assign rndvariableName? to randomThrow(rnd).item_1value or expression?795
end for
end main
+def main() -> None:
796
rndname? = Random()value or expression? # variable definition797
rnd.initialiseFromClockprocedureName?(arguments?) # procedure call798
+for iitem? in range(1, 20)source?:
799
print(randomThrow(rnd).item_0arguments?)800
rndvariableName? = randomThrow(rnd).item_1value or expression? # assignment801
# end for
# end main
+static void main() {
802
var rndname? = new Random()value or expression?;803
rnd.initialiseFromClockprocedureName?(arguments?); // procedure call804
+foreach (var iitem? in range(1, 20)source?) {
805
Console.WriteLine(randomThrow(rnd).item_0arguments?); // print statement806
rndvariableName? = randomThrow(rnd).item_1value or expression?; // assignment807
} // end foreach
} // end main
+Sub main()
808
Dim rndname? = New Random()value or expression? ' variable definition809
rnd.initialiseFromClockprocedureName?(arguments?) ' procedure call810
+For Each iitem? In range(1, 20)source?
811
Console.WriteLine(randomThrow(rnd).item_0arguments?) ' print statement812
rndvariableName? = randomThrow(rnd).item_1value or expression? ' assignment813
Next i
End Sub
+static void main() {
814
var rndname? = new Random()value or expression?;815
rnd.initialiseFromClockprocedureName?(arguments?); // procedure call816
+foreach (var iitem? in range(1, 20)source?) {
817
System.out.println(randomThrow(rnd).item_0arguments?); // print statement818
rndvariableName? = randomThrow(rnd).item_1value or expression?; // assignment819
} // end foreach
} // end main
This section covers a variety of input and output facilities:
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 key1name? set to getKey()value or expression?821
variable key2name? set to getNumericKey()value or expression?822
variable kmname? set to getKeyWithModifier()value or expression?823
variable keyCapname? set to km.item_0value or expression?824
variable keyModname? set to km.item_1value or expression?825
end main
+def main() -> None:
826
key1name? = getKey()value or expression? # variable definition827
key2name? = getNumericKey()value or expression? # variable definition828
kmname? = getKeyWithModifier()value or expression? # variable definition829
keyCapname? = km.item_0value or expression? # variable definition830
keyModname? = km.item_1value or expression? # variable definition831
# end main
+static void main() {
832
var key1name? = getKey()value or expression?;833
var key2name? = getNumericKey()value or expression?;834
var kmname? = getKeyWithModifier()value or expression?;835
var keyCapname? = km.item_0value or expression?;836
var keyModname? = km.item_1value or expression?;837
} // end main
+Sub main()
838
Dim key1name? = getKey()value or expression? ' variable definition839
Dim key2name? = getNumericKey()value or expression? ' variable definition840
Dim kmname? = getKeyWithModifier()value or expression? ' variable definition841
Dim keyCapname? = km.item_0value or expression? ' variable definition842
Dim keyModname? = km.item_1value or expression? ' variable definition843
End Sub
+static void main() {
844
var key1name? = getKey()value or expression?;845
var key2name? = getNumericKey()value or expression?;846
var kmname? = getKeyWithModifier()value or expression?;847
var keyCapname? = km.item_0value or expression?;848
var keyModname? = km.item_1value 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 pressAnyKeyToContinueprocedureName?(arguments?)851
print("OK, press A or B"arguments?)852
variable keyname? set to waitForKey()value or expression?853
print($"That was {key}"arguments?)854
end main
+def main() -> None:
855
pressAnyKeyToContinueprocedureName?(arguments?) # procedure call856
print("OK, press A or B"arguments?)857
keyname? = waitForKey()value or expression? # variable definition858
print(f"That was {key}"arguments?)859
# end main
+static void main() {
860
pressAnyKeyToContinueprocedureName?(arguments?); // procedure call861
Console.WriteLine("OK, press A or B"arguments?); // print statement862
var keyname? = waitForKey()value or expression?;863
Console.WriteLine($"That was {key}"arguments?); // print statement864
} // end main
+Sub main()
865
pressAnyKeyToContinueprocedureName?(arguments?) ' procedure call866
Console.WriteLine("OK, press A or B"arguments?) ' print statement867
Dim keyname? = waitForKey()value or expression? ' variable definition868
Console.WriteLine($"That was {key}"arguments?) ' print statement869
End Sub
+static void main() {
870
pressAnyKeyToContinueprocedureName?(arguments?); // procedure call871
System.out.println("OK, press A or B"arguments?); // print statement872
var keyname? = waitForKey()value or expression?;873
System.out.println(String.format("That was %", key)arguments?); // print statement874
} // end main
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 filename? set to createFileForWriting("myFile.txt")value or expression?876
call file.writeWholeFileprocedureName?("Text line 1\nText line 2"arguments?)877
end main
+def main() -> None:
878
filename? = createFileForWriting("myFile.txt")value or expression? # variable definition879
file.writeWholeFileprocedureName?("Text line 1\nText line 2"arguments?) # procedure call880
# end main
+static void main() {
881
var filename? = createFileForWriting("myFile.txt")value or expression?;882
file.writeWholeFileprocedureName?("Text line 1\nText line 2"arguments?); // procedure call883
} // end main
+Sub main()
884
Dim filename? = createFileForWriting("myFile.txt")value or expression? ' variable definition885
file.writeWholeFileprocedureName?("Text line 1\nText line 2"arguments?) ' procedure call886
End Sub
+static void main() {
887
var filename? = createFileForWriting("myFile.txt")value or expression?;888
file.writeWholeFileprocedureName?("Text line 1\nText line 2"arguments?); // procedure call889
} // 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 filename? set to openFileForReading()value or expression?891
variable textname? set to file.readWholeFile()value or expression?892
print(textarguments?)893
end main
+def main() -> None:
894
filename? = openFileForReading()value or expression? # variable definition895
textname? = file.readWholeFile()value or expression? # variable definition896
print(textarguments?)897
# end main
+static void main() {
898
var filename? = openFileForReading()value or expression?;899
var textname? = file.readWholeFile()value or expression?;900
Console.WriteLine(textarguments?); // print statement901
} // end main
+Sub main()
902
Dim filename? = openFileForReading()value or expression? ' variable definition903
Dim textname? = file.readWholeFile()value or expression? ' variable definition904
Console.WriteLine(textarguments?) ' print statement905
End Sub
+static void main() {
906
var filename? = openFileForReading()value or expression?;907
var textname? = file.readWholeFile()value or expression?;908
System.out.println(textarguments?); // print statement909
} // 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 displayHtmlprocedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?)910
displayHtmlprocedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?) # procedure call911
displayHtmlprocedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?); // procedure call912
displayHtmlprocedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?) ' procedure call913
displayHtmlprocedureName?("<h1 style='color: blue;'>A heading</h1><p>some text</p>"arguments?); // procedure call914
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 stylename? set to "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression?916
call displayHtmlprocedureName?($"{style}<h1>New heading</h1><p>some new text</p>"arguments?)917
end main
+def main() -> None:
918
stylename? = "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression? # variable definition919
displayHtmlprocedureName?(f"{style}<h1>New heading</h1><p>some new text</p>"arguments?) # procedure call920
# end main
+static void main() {
921
var stylename? = "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression?;922
displayHtmlprocedureName?($"{style}<h1>New heading</h1><p>some new text</p>"arguments?); // procedure call923
} // end main
+Sub main()
924
Dim stylename? = "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression? ' variable definition925
displayHtmlprocedureName?($"{style}<h1>New heading</h1><p>some new text</p>"arguments?) ' procedure call926
End Sub
+static void main() {
927
var stylename? = "<style> h1 { color: Red; font-size: 24pt; } p { font-family: Serif; } </style>"value or expression?;928
displayHtmlprocedureName?(String.format("%<h1>New heading</h1><p>some new text</p>", style)arguments?); // procedure call929
} // 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:
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 scalename? set to [262, 294, 330, 349, 392, 440, 494, 523]value or expression?981
variable scaleLname? set to scale.length()value or expression?982
variable quavername? set to 250value or expression?983
variable volumename? set to 1.5value or expression?984
+for iitem? in range(0, scaleL)source?
985
call toneprocedureName?(quaver, scale[i], volumearguments?)986
end for
call sleepprocedureName?(1arguments?)987
+for iitem? in range(0, scaleL)source?
988
call toneprocedureName?(quaver, scale[scaleL - 1 - i], volumearguments?)989
end for
end main
+def main() -> None:
990
scalename? = [262, 294, 330, 349, 392, 440, 494, 523]value or expression? # variable definition991
scaleLname? = scale.length()value or expression? # variable definition992
quavername? = 250value or expression? # variable definition993
volumename? = 1.5value or expression? # variable definition994
+for iitem? in range(0, scaleL)source?:
995
toneprocedureName?(quaver, scale[i], volumearguments?) # procedure call996
# end for
sleepprocedureName?(1arguments?) # procedure call997
+for iitem? in range(0, scaleL)source?:
998
toneprocedureName?(quaver, scale[scaleL - 1 - i], volumearguments?) # procedure call999
# end for
# end main
+static void main() {
1000
var scalename? = new [] {262, 294, 330, 349, 392, 440, 494, 523}value or expression?;1001
var scaleLname? = scale.length()value or expression?;1002
var quavername? = 250value or expression?;1003
var volumename? = 1.5value or expression?;1004
+foreach (var iitem? in range(0, scaleL)source?) {
1005
toneprocedureName?(quaver, scale[i], volumearguments?); // procedure call1006
} // end foreach
sleepprocedureName?(1arguments?); // procedure call1007
+foreach (var iitem? in range(0, scaleL)source?) {
1008
toneprocedureName?(quaver, scale[scaleL - 1 - i], volumearguments?); // procedure call1009
} // end foreach
} // end main
+Sub main()
1010
Dim scalename? = {262, 294, 330, 349, 392, 440, 494, 523}value or expression? ' variable definition1011
Dim scaleLname? = scale.length()value or expression? ' variable definition1012
Dim quavername? = 250value or expression? ' variable definition1013
Dim volumename? = 1.5value or expression? ' variable definition1014
+For Each iitem? In range(0, scaleL)source?
1015
toneprocedureName?(quaver, scale(i), volumearguments?) ' procedure call1016
Next i
sleepprocedureName?(1arguments?) ' procedure call1017
+For Each iitem? In range(0, scaleL)source?
1018
toneprocedureName?(quaver, scale(scaleL - 1 - i), volumearguments?) ' procedure call1019
Next i
End Sub
+static void main() {
1020
var scalename? = list(262, 294, 330, 349, 392, 440, 494, 523)value or expression?;1021
var scaleLname? = scale.length()value or expression?;1022
var quavername? = 250value or expression?;1023
var volumename? = 1.5value or expression?;1024
+foreach (var iitem? in range(0, scaleL)source?) {
1025
toneprocedureName?(quaver, scale[i], volumearguments?); // procedure call1026
} // end foreach
sleepprocedureName?(1arguments?); // procedure call1027
+foreach (var iitem? in range(0, scaleL)source?) {
1028
toneprocedureName?(quaver, scale[scaleL - 1 - i], volumearguments?); // procedure call1029
} // 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.
Notes
- 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.
- methods ceiling, floor, isInfinite, isNaN and round are designed for use on
FloatfloatdoubleDoubledouble values, but they can accept IntintintIntegerint values without raising an error.
- 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 |
- 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 aname? set to 3value or expression?1032
variable bname? set to 4value or expression?1033
print(a*barguments?)1034
print($"{a} times {b}) equals {a*b}"arguments?)1035
variable tname? set to (true, 42)value or expression?1036
print(t.item_0arguments?)1037
print(t.item_1arguments?)1038
end main
+def main() -> None:
1039
print("Hello"arguments?)1040
aname? = 3value or expression? # variable definition1041
bname? = 4value or expression? # variable definition1042
print(a*barguments?)1043
print(f"{a} times {b}) equals {a*b}"arguments?)1044
tname? = (True, 42)value or expression? # variable definition1045
print(t.item_0arguments?)1046
print(t.item_1arguments?)1047
# end main
+static void main() {
1048
Console.WriteLine("Hello"arguments?); // print statement1049
var aname? = 3value or expression?;1050
var bname? = 4value or expression?;1051
Console.WriteLine(a*barguments?); // print statement1052
Console.WriteLine($"{a} times {b}) equals {a*b}"arguments?); // print statement1053
var tname? = (true, 42)value or expression?;1054
Console.WriteLine(t.item_0arguments?); // print statement1055
Console.WriteLine(t.item_1arguments?); // print statement1056
} // end main
+Sub main()
1057
Console.WriteLine("Hello"arguments?) ' print statement1058
Dim aname? = 3value or expression? ' variable definition1059
Dim bname? = 4value or expression? ' variable definition1060
Console.WriteLine(a*barguments?) ' print statement1061
Console.WriteLine($"{a} times {b}) equals {a*b}"arguments?) ' print statement1062
Dim tname? = (True, 42)value or expression? ' variable definition1063
Console.WriteLine(t.item_0arguments?) ' print statement1064
Console.WriteLine(t.item_1arguments?) ' print statement1065
End Sub
+static void main() {
1066
System.out.println("Hello"arguments?); // print statement1067
var aname? = 3value or expression?;1068
var bname? = 4value or expression?;1069
System.out.println(a*barguments?); // print statement1070
System.out.println(String.format("% times %) equals %", a, b, a*b)arguments?); // print statement1071
var tname? = (true, 42)value or expression?;1072
System.out.println(t.item_0arguments?); // print statement1073
System.out.println(t.item_1arguments?); // print statement1074
} // 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 printTabprocedureName?(0, "Number"arguments?)1076
call printTabprocedureName?(10, "Square"arguments?)1077
call printTabprocedureName?(20, "Cube\n"arguments?)1078
+for iitem? in range(1, 11)source?
1079
call printTabprocedureName?(0, i.toString()arguments?)1080
call printTabprocedureName?(10, $"{pow(i, 2)}"arguments?)1081
call printTabprocedureName?(20, $"{pow(i, 3)}\n"arguments?)1082
end for
end main
+def main() -> None:
1083
printTabprocedureName?(0, "Number"arguments?) # procedure call1084
printTabprocedureName?(10, "Square"arguments?) # procedure call1085
printTabprocedureName?(20, "Cube\n"arguments?) # procedure call1086
+for iitem? in range(1, 11)source?:
1087
printTabprocedureName?(0, i.toString()arguments?) # procedure call1088
printTabprocedureName?(10, f"{pow(i, 2)}"arguments?) # procedure call1089
printTabprocedureName?(20, f"{pow(i, 3)}\n"arguments?) # procedure call1090
# end for
# end main
+static void main() {
1091
printTabprocedureName?(0, "Number"arguments?); // procedure call1092
printTabprocedureName?(10, "Square"arguments?); // procedure call1093
printTabprocedureName?(20, "Cube\n"arguments?); // procedure call1094
+foreach (var iitem? in range(1, 11)source?) {
1095
printTabprocedureName?(0, i.toString()arguments?); // procedure call1096
printTabprocedureName?(10, $"{pow(i, 2)}"arguments?); // procedure call1097
printTabprocedureName?(20, $"{pow(i, 3)}\n"arguments?); // procedure call1098
} // end foreach
} // end main
+Sub main()
1099
printTabprocedureName?(0, "Number"arguments?) ' procedure call1100
printTabprocedureName?(10, "Square"arguments?) ' procedure call1101
printTabprocedureName?(20, "Cube\n"arguments?) ' procedure call1102
+For Each iitem? In range(1, 11)source?
1103
printTabprocedureName?(0, i.toString()arguments?) ' procedure call1104
printTabprocedureName?(10, $"{pow(i, 2)}"arguments?) ' procedure call1105
printTabprocedureName?(20, $"{pow(i, 3)}\n"arguments?) ' procedure call1106
Next i
End Sub
+static void main() {
1107
printTabprocedureName?(0, "Number"arguments?); // procedure call1108
printTabprocedureName?(10, "Square"arguments?); // procedure call1109
printTabprocedureName?(20, "Cube\n"arguments?); // procedure call1110
+foreach (var iitem? in range(1, 11)source?) {
1111
printTabprocedureName?(0, i.toString()arguments?); // procedure call1112
printTabprocedureName?(10, String.format("%", pow(i, 2))arguments?); // procedure call1113
printTabprocedureName?(20, String.format("%\n", pow(i, 3))arguments?); // procedure call1114
} // 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:
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_parsetest_name?
1115
assert parseAsInt("31")actual (computed) value? is (true, 31)expected value? not run1116
assert parseAsInt("0")actual (computed) value? is (true, 0)expected value? not run1117
assert parseAsInt("thirty one")actual (computed) value? is (false, 0)expected value? not run1118
assert parseAsInt("3.1")actual (computed) value? is (false, 0)expected value? not run1119
assert parseAsFloat("31")actual (computed) value? is (true, 31)expected value? not run1120
assert parseAsFloat("0")actual (computed) value? is (true, 0)expected value? not run1121
assert parseAsFloat("3.1")actual (computed) value? is (true, 3.1)expected value? not run1122
end test
+class Test_parse(unittest.TestCase):
def test_parsetest_name?(self) -> None:
1123
self.assertEqual(parseAsInt("31")actual (computed) value?, (True, 31)expected value?) not run1124
self.assertEqual(parseAsInt("0")actual (computed) value?, (True, 0)expected value?) not run1125
self.assertEqual(parseAsInt("thirty one")actual (computed) value?, (False, 0)expected value?) not run1126
self.assertEqual(parseAsInt("3.1")actual (computed) value?, (False, 0)expected value?) not run1127
self.assertEqual(parseAsFloat("31")actual (computed) value?, (True, 31)expected value?) not run1128
self.assertEqual(parseAsFloat("0")actual (computed) value?, (True, 0)expected value?) not run1129
self.assertEqual(parseAsFloat("3.1")actual (computed) value?, (True, 3.1)expected value?) not run1130
# end test
+[TestClass] class Test_parse
[TestMethod] static void test_parsetest_name?() {
1131
Assert.AreEqual((true, 31)expected value?, parseAsInt("31")actual (computed) value?); not run1132
Assert.AreEqual((true, 0)expected value?, parseAsInt("0")actual (computed) value?); not run1133
Assert.AreEqual((false, 0)expected value?, parseAsInt("thirty one")actual (computed) value?); not run1134
Assert.AreEqual((false, 0)expected value?, parseAsInt("3.1")actual (computed) value?); not run1135
Assert.AreEqual((true, 31)expected value?, parseAsFloat("31")actual (computed) value?); not run1136
Assert.AreEqual((true, 0)expected value?, parseAsFloat("0")actual (computed) value?); not run1137
Assert.AreEqual((true, 3.1)expected value?, parseAsFloat("3.1")actual (computed) value?); not run1138
}} // end test
+<TestClass Class Test_parse
<TestMethod> Sub test_parsetest_name?()
1139
Assert.AreEqual((True, 31)expected value?, parseAsInt("31")actual (computed) value?) not run1140
Assert.AreEqual((True, 0)expected value?, parseAsInt("0")actual (computed) value?) not run1141
Assert.AreEqual((False, 0)expected value?, parseAsInt("thirty one")actual (computed) value?) not run1142
Assert.AreEqual((False, 0)expected value?, parseAsInt("3.1")actual (computed) value?) not run1143
Assert.AreEqual((True, 31)expected value?, parseAsFloat("31")actual (computed) value?) not run1144
Assert.AreEqual((True, 0)expected value?, parseAsFloat("0")actual (computed) value?) not run1145
Assert.AreEqual((True, 3.1)expected value?, parseAsFloat("3.1")actual (computed) value?) not run1146
End Sub
End Class
+class Test_parse {
@Test static void test_parsetest_name?() {
1147
assertEquals((true, 31)expected value?, parseAsInt("31")actual (computed) value?); not run1148
assertEquals((true, 0)expected value?, parseAsInt("0")actual (computed) value?); not run1149
assertEquals((false, 0)expected value?, parseAsInt("thirty one")actual (computed) value?); not run1150
assertEquals((false, 0)expected value?, parseAsInt("3.1")actual (computed) value?); not run1151
assertEquals((true, 31)expected value?, parseAsFloat("31")actual (computed) value?); not run1152
assertEquals((true, 0)expected value?, parseAsFloat("0")actual (computed) value?); not run1153
assertEquals((true, 3.1)expected value?, parseAsFloat("3.1")actual (computed) value?); not run1154
}} // 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_mathstest_name?
1155
assert piactual (computed) value? is 3.141592653589793expected value? not run1156
assert abs(-3.7)actual (computed) value? is 3.7expected value? not run1157
assert pow(2, 10)actual (computed) value? is 1024expected value? not run1158
assert sqrt(2).round(3)actual (computed) value? is 1.414expected value? not run1159
assert asin(0.5).round(3)actual (computed) value? is 0.524expected value? not run1160
assert acos(0.5).round(3)actual (computed) value? is 1.047expected value? not run1161
assert atan(1).round(2)actual (computed) value? is 0.79expected value? not run1162
assert sin(pi/6).round(2)actual (computed) value? is 0.5expected value? not run1163
assert cos(pi/4).round(3)actual (computed) value? is 0.707expected value? not run1164
assert tan(pi/4).round(2)actual (computed) value? is 1expected value? not run1165
assert exp(2).round(3)actual (computed) value? is 7.389expected value? not run1166
assert logE(7.389).round(2)actual (computed) value? is 2expected value? not run1167
assert log10(1000)actual (computed) value? is 3expected value? not run1168
assert log2(65536)actual (computed) value? is 16expected value? not run1169
assert log2(0x10000)actual (computed) value? is 16expected value? not run1170
end test
+class Test_maths(unittest.TestCase):
def test_mathstest_name?(self) -> None:
1171
self.assertEqual(piactual (computed) value?, 3.141592653589793expected value?) not run1172
self.assertEqual(abs(-3.7)actual (computed) value?, 3.7expected value?) not run1173
self.assertEqual(pow(2, 10)actual (computed) value?, 1024expected value?) not run1174
self.assertEqual(sqrt(2).round(3)actual (computed) value?, 1.414expected value?) not run1175
self.assertEqual(asin(0.5).round(3)actual (computed) value?, 0.524expected value?) not run1176
self.assertEqual(acos(0.5).round(3)actual (computed) value?, 1.047expected value?) not run1177
self.assertEqual(atan(1).round(2)actual (computed) value?, 0.79expected value?) not run1178
self.assertEqual(sin(pi/6).round(2)actual (computed) value?, 0.5expected value?) not run1179
self.assertEqual(cos(pi/4).round(3)actual (computed) value?, 0.707expected value?) not run1180
self.assertEqual(tan(pi/4).round(2)actual (computed) value?, 1expected value?) not run1181
self.assertEqual(exp(2).round(3)actual (computed) value?, 7.389expected value?) not run1182
self.assertEqual(logE(7.389).round(2)actual (computed) value?, 2expected value?) not run1183
self.assertEqual(log10(1000)actual (computed) value?, 3expected value?) not run1184
self.assertEqual(log2(65536)actual (computed) value?, 16expected value?) not run1185
self.assertEqual(log2(0x10000)actual (computed) value?, 16expected value?) not run1186
# end test
+[TestClass] class Test_maths
[TestMethod] static void test_mathstest_name?() {
1187
Assert.AreEqual(3.141592653589793expected value?, piactual (computed) value?); not run1188
Assert.AreEqual(3.7expected value?, abs(-3.7)actual (computed) value?); not run1189
Assert.AreEqual(1024expected value?, pow(2, 10)actual (computed) value?); not run1190
Assert.AreEqual(1.414expected value?, sqrt(2).round(3)actual (computed) value?); not run1191
Assert.AreEqual(0.524expected value?, asin(0.5).round(3)actual (computed) value?); not run1192
Assert.AreEqual(1.047expected value?, acos(0.5).round(3)actual (computed) value?); not run1193
Assert.AreEqual(0.79expected value?, atan(1).round(2)actual (computed) value?); not run1194
Assert.AreEqual(0.5expected value?, sin(pi/6).round(2)actual (computed) value?); not run1195
Assert.AreEqual(0.707expected value?, cos(pi/4).round(3)actual (computed) value?); not run1196
Assert.AreEqual(1expected value?, tan(pi/4).round(2)actual (computed) value?); not run1197
Assert.AreEqual(7.389expected value?, exp(2).round(3)actual (computed) value?); not run1198
Assert.AreEqual(2expected value?, logE(7.389).round(2)actual (computed) value?); not run1199
Assert.AreEqual(3expected value?, log10(1000)actual (computed) value?); not run1200
Assert.AreEqual(16expected value?, log2(65536)actual (computed) value?); not run1201
Assert.AreEqual(16expected value?, log2(0x10000)actual (computed) value?); not run1202
}} // end test
+<TestClass Class Test_maths
<TestMethod> Sub test_mathstest_name?()
1203
Assert.AreEqual(3.141592653589793expected value?, piactual (computed) value?) not run1204
Assert.AreEqual(3.7expected value?, abs(-3.7)actual (computed) value?) not run1205
Assert.AreEqual(1024expected value?, pow(2, 10)actual (computed) value?) not run1206
Assert.AreEqual(1.414expected value?, sqrt(2).round(3)actual (computed) value?) not run1207
Assert.AreEqual(0.524expected value?, asin(0.5).round(3)actual (computed) value?) not run1208
Assert.AreEqual(1.047expected value?, acos(0.5).round(3)actual (computed) value?) not run1209
Assert.AreEqual(0.79expected value?, atan(1).round(2)actual (computed) value?) not run1210
Assert.AreEqual(0.5expected value?, sin(pi/6).round(2)actual (computed) value?) not run1211
Assert.AreEqual(0.707expected value?, cos(pi/4).round(3)actual (computed) value?) not run1212
Assert.AreEqual(1expected value?, tan(pi/4).round(2)actual (computed) value?) not run1213
Assert.AreEqual(7.389expected value?, exp(2).round(3)actual (computed) value?) not run1214
Assert.AreEqual(2expected value?, logE(7.389).round(2)actual (computed) value?) not run1215
Assert.AreEqual(3expected value?, log10(1000)actual (computed) value?) not run1216
Assert.AreEqual(16expected value?, log2(65536)actual (computed) value?) not run1217
Assert.AreEqual(16expected value?, log2(&H10000)actual (computed) value?) not run1218
End Sub
End Class
+class Test_maths {
@Test static void test_mathstest_name?() {
1219
assertEquals(3.141592653589793expected value?, piactual (computed) value?); not run1220
assertEquals(3.7expected value?, abs(-3.7)actual (computed) value?); not run1221
assertEquals(1024expected value?, pow(2, 10)actual (computed) value?); not run1222
assertEquals(1.414expected value?, sqrt(2).round(3)actual (computed) value?); not run1223
assertEquals(0.524expected value?, asin(0.5).round(3)actual (computed) value?); not run1224
assertEquals(1.047expected value?, acos(0.5).round(3)actual (computed) value?); not run1225
assertEquals(0.79expected value?, atan(1).round(2)actual (computed) value?); not run1226
assertEquals(0.5expected value?, sin(pi/6).round(2)actual (computed) value?); not run1227
assertEquals(0.707expected value?, cos(pi/4).round(3)actual (computed) value?); not run1228
assertEquals(1expected value?, tan(pi/4).round(2)actual (computed) value?); not run1229
assertEquals(7.389expected value?, exp(2).round(3)actual (computed) value?); not run1230
assertEquals(2expected value?, logE(7.389).round(2)actual (computed) value?); not run1231
assertEquals(3expected value?, log10(1000)actual (computed) value?); not run1232
assertEquals(16expected value?, log2(65536)actual (computed) value?); not run1233
assertEquals(16expected value?, log2(0x10000)actual (computed) value?); not run1234
}} // 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_bitwisetest_name?
1235
variable aname? set to 13value or expression?1236
assert aactual (computed) value? is 0xdexpected value? not run1237
assert aactual (computed) value? is 0b1101expected value? not run1238
assert a.asBinary()actual (computed) value? is "1101"expected value? not run1239
variable bname? set to 30value or expression?1240
assert bactual (computed) value? is 0b11110expected value? not run1241
assert bitAnd(a, b)actual (computed) value? is 0b1100expected value? not run1242
variable aobname? set to bitOr(a, b)value or expression?1243
assert aobactual (computed) value? is 0b11111expected value? not run1244
variable axbname? set to bitXor(a, b)value or expression?1245
assert axbactual (computed) value? is 0b10011expected value? not run1246
variable notaname? set to bitNot(a)value or expression?1247
assert notaactual (computed) value? is -14expected value? not run1248
variable aLname? set to bitShiftL(a, 2)value or expression?1249
assert aLactual (computed) value? is 0b110100expected value? not run1250
assert bitShiftR(a, 2)actual (computed) value? is 0b11expected value? not run1251
end test
+class Test_bitwise(unittest.TestCase):
def test_bitwisetest_name?(self) -> None:
1252
aname? = 13value or expression? # variable definition1253
self.assertEqual(aactual (computed) value?, 0xdexpected value?) not run1254
self.assertEqual(aactual (computed) value?, 0b1101expected value?) not run1255
self.assertEqual(a.asBinary()actual (computed) value?, "1101"expected value?) not run1256
bname? = 30value or expression? # variable definition1257
self.assertEqual(bactual (computed) value?, 0b11110expected value?) not run1258
self.assertEqual(bitAnd(a, b)actual (computed) value?, 0b1100expected value?) not run1259
aobname? = bitOr(a, b)value or expression? # variable definition1260
self.assertEqual(aobactual (computed) value?, 0b11111expected value?) not run1261
axbname? = bitXor(a, b)value or expression? # variable definition1262
self.assertEqual(axbactual (computed) value?, 0b10011expected value?) not run1263
notaname? = bitNot(a)value or expression? # variable definition1264
self.assertEqual(notaactual (computed) value?, -14expected value?) not run1265
aLname? = bitShiftL(a, 2)value or expression? # variable definition1266
self.assertEqual(aLactual (computed) value?, 0b110100expected value?) not run1267
self.assertEqual(bitShiftR(a, 2)actual (computed) value?, 0b11expected value?) not run1268
# end test
+[TestClass] class Test_bitwise
[TestMethod] static void test_bitwisetest_name?() {
1269
var aname? = 13value or expression?;1270
Assert.AreEqual(0xdexpected value?, aactual (computed) value?); not run1271
Assert.AreEqual(0b1101expected value?, aactual (computed) value?); not run1272
Assert.AreEqual("1101"expected value?, a.asBinary()actual (computed) value?); not run1273
var bname? = 30value or expression?;1274
Assert.AreEqual(0b11110expected value?, bactual (computed) value?); not run1275
Assert.AreEqual(0b1100expected value?, bitAnd(a, b)actual (computed) value?); not run1276
var aobname? = bitOr(a, b)value or expression?;1277
Assert.AreEqual(0b11111expected value?, aobactual (computed) value?); not run1278
var axbname? = bitXor(a, b)value or expression?;1279
Assert.AreEqual(0b10011expected value?, axbactual (computed) value?); not run1280
var notaname? = bitNot(a)value or expression?;1281
Assert.AreEqual(-14expected value?, notaactual (computed) value?); not run1282
var aLname? = bitShiftL(a, 2)value or expression?;1283
Assert.AreEqual(0b110100expected value?, aLactual (computed) value?); not run1284
Assert.AreEqual(0b11expected value?, bitShiftR(a, 2)actual (computed) value?); not run1285
}} // end test
+<TestClass Class Test_bitwise
<TestMethod> Sub test_bitwisetest_name?()
1286
Dim aname? = 13value or expression? ' variable definition1287
Assert.AreEqual(&Hdexpected value?, aactual (computed) value?) not run1288
Assert.AreEqual(&B1101expected value?, aactual (computed) value?) not run1289
Assert.AreEqual("1101"expected value?, a.asBinary()actual (computed) value?) not run1290
Dim bname? = 30value or expression? ' variable definition1291
Assert.AreEqual(&B11110expected value?, bactual (computed) value?) not run1292
Assert.AreEqual(&B1100expected value?, bitAnd(a, b)actual (computed) value?) not run1293
Dim aobname? = bitOr(a, b)value or expression? ' variable definition1294
Assert.AreEqual(&B11111expected value?, aobactual (computed) value?) not run1295
Dim axbname? = bitXor(a, b)value or expression? ' variable definition1296
Assert.AreEqual(&B10011expected value?, axbactual (computed) value?) not run1297
Dim notaname? = bitNot(a)value or expression? ' variable definition1298
Assert.AreEqual(-14expected value?, notaactual (computed) value?) not run1299
Dim aLname? = bitShiftL(a, 2)value or expression? ' variable definition1300
Assert.AreEqual(&B110100expected value?, aLactual (computed) value?) not run1301
Assert.AreEqual(&B11expected value?, bitShiftR(a, 2)actual (computed) value?) not run1302
End Sub
End Class
+class Test_bitwise {
@Test static void test_bitwisetest_name?() {
1303
var aname? = 13value or expression?;1304
assertEquals(0xdexpected value?, aactual (computed) value?); not run1305
assertEquals(0b1101expected value?, aactual (computed) value?); not run1306
assertEquals("1101"expected value?, a.asBinary()actual (computed) value?); not run1307
var bname? = 30value or expression?;1308
assertEquals(0b11110expected value?, bactual (computed) value?); not run1309
assertEquals(0b1100expected value?, bitAnd(a, b)actual (computed) value?); not run1310
var aobname? = bitOr(a, b)value or expression?;1311
assertEquals(0b11111expected value?, aobactual (computed) value?); not run1312
var axbname? = bitXor(a, b)value or expression?;1313
assertEquals(0b10011expected value?, axbactual (computed) value?); not run1314
var notaname? = bitNot(a)value or expression?;1315
assertEquals(-14expected value?, notaactual (computed) value?); not run1316
var aLname? = bitShiftL(a, 2)value or expression?;1317
assertEquals(0b110100expected value?, aLactual (computed) value?); not run1318
assertEquals(0b11expected value?, bitShiftR(a, 2)actual (computed) value?); not run1319
}} // 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
1111111111111111111111111111001011111111111111111111111111110010111111111111111111111111111100101111111111111111111111111111001011111111111111111111111111110010which is the value -14-14-14-14-14in 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_matchesRegExptest_name?
1320
variable s1name? set to "hello"value or expression?1321
variable s2name? set to "World"value or expression?1322
variable rname? set to /^[a-z]*$/value or expression?1323
assert s1.matchesRegExp(r)actual (computed) value? is trueexpected value? not run1324
assert s2.matchesRegExp(r)actual (computed) value? is falseexpected value? not run1325
end test
+class Test_matchesRegExp(unittest.TestCase):
def test_matchesRegExptest_name?(self) -> None:
1326
s1name? = "hello"value or expression? # variable definition1327
s2name? = "World"value or expression? # variable definition1328
rname? = /^[a-z]*$/value or expression? # variable definition1329
self.assertEqual(s1.matchesRegExp(r)actual (computed) value?, Trueexpected value?) not run1330
self.assertEqual(s2.matchesRegExp(r)actual (computed) value?, Falseexpected value?) not run1331
# end test
+[TestClass] class Test_matchesRegExp
[TestMethod] static void test_matchesRegExptest_name?() {
1332
var s1name? = "hello"value or expression?;1333
var s2name? = "World"value or expression?;1334
var rname? = /^[a-z]*$/value or expression?;1335
Assert.AreEqual(trueexpected value?, s1.matchesRegExp(r)actual (computed) value?); not run1336
Assert.AreEqual(falseexpected value?, s2.matchesRegExp(r)actual (computed) value?); not run1337
}} // end test
+<TestClass Class Test_matchesRegExp
<TestMethod> Sub test_matchesRegExptest_name?()
1338
Dim s1name? = "hello"value or expression? ' variable definition1339
Dim s2name? = "World"value or expression? ' variable definition1340
Dim rname? = /^(a-z)*$/value or expression? ' variable definition1341
Assert.AreEqual(Trueexpected value?, s1.matchesRegExp(r)actual (computed) value?) not run1342
Assert.AreEqual(Falseexpected value?, s2.matchesRegExp(r)actual (computed) value?) not run1343
End Sub
End Class
+class Test_matchesRegExp {
@Test static void test_matchesRegExptest_name?() {
1344
var s1name? = "hello"value or expression?;1345
var s2name? = "World"value or expression?;1346
var rname? = /^[a-z]*$/value or expression?;1347
assertEquals(trueexpected value?, s1.matchesRegExp(r)actual (computed) value?); not run1348
assertEquals(falseexpected value?, s2.matchesRegExp(r)actual (computed) value?); not run1349
}} // end test
You can convert a valid string without /..//..//..//..//../ delimiters to a RegExpRegExpRegExpRegExpRegExp using function asRegExp:
+test test_matchesRegExptest_name?
1350
variable s1name? set to "hello"value or expression?1351
variable s2name? set to "World"value or expression?1352
variable rname? set to "^[a-z]*$".asRegExp()value or expression?1353
assert s1.matchesRegExp(r)actual (computed) value? is trueexpected value? not run1354
assert s2.matchesRegExp(r)actual (computed) value? is falseexpected value? not run1355
end test
+class Test_matchesRegExp(unittest.TestCase):
def test_matchesRegExptest_name?(self) -> None:
1356
s1name? = "hello"value or expression? # variable definition1357
s2name? = "World"value or expression? # variable definition1358
rname? = "^[a-z]*$".asRegExp()value or expression? # variable definition1359
self.assertEqual(s1.matchesRegExp(r)actual (computed) value?, Trueexpected value?) not run1360
self.assertEqual(s2.matchesRegExp(r)actual (computed) value?, Falseexpected value?) not run1361
# end test
+[TestClass] class Test_matchesRegExp
[TestMethod] static void test_matchesRegExptest_name?() {
1362
var s1name? = "hello"value or expression?;1363
var s2name? = "World"value or expression?;1364
var rname? = "^[a-z]*$".asRegExp()value or expression?;1365
Assert.AreEqual(trueexpected value?, s1.matchesRegExp(r)actual (computed) value?); not run1366
Assert.AreEqual(falseexpected value?, s2.matchesRegExp(r)actual (computed) value?); not run1367
}} // end test
+<TestClass Class Test_matchesRegExp
<TestMethod> Sub test_matchesRegExptest_name?()
1368
Dim s1name? = "hello"value or expression? ' variable definition1369
Dim s2name? = "World"value or expression? ' variable definition1370
Dim rname? = "^(a-z)*$".asRegExp()value or expression? ' variable definition1371
Assert.AreEqual(Trueexpected value?, s1.matchesRegExp(r)actual (computed) value?) not run1372
Assert.AreEqual(Falseexpected value?, s2.matchesRegExp(r)actual (computed) value?) not run1373
End Sub
End Class
+class Test_matchesRegExp {
@Test static void test_matchesRegExptest_name?() {
1374
var s1name? = "hello"value or expression?;1375
var s2name? = "World"value or expression?;1376
var rname? = "^[a-z]*$".asRegExp()value or expression?;1377
assertEquals(trueexpected value?, s1.matchesRegExp(r)actual (computed) value?); not run1378
assertEquals(falseexpected value?, s2.matchesRegExp(r)actual (computed) value?); not run1379
}} // 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
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 numbersname? set to ["zero", "one", "two", "three", "four", "five", "six"]value or expression?1381
+for nitem? in rangeInSteps(0, numbers.length() + 1, 2)source?
1382
print(numbers[n]arguments?)1383
end for
end main
+def main() -> None:
1384
numbersname? = ["zero", "one", "two", "three", "four", "five", "six"]value or expression? # variable definition1385
+for nitem? in rangeInSteps(0, numbers.length() + 1, 2)source?:
1386
print(numbers[n]arguments?)1387
# end for
# end main
+static void main() {
1388
var numbersname? = new [] {"zero", "one", "two", "three", "four", "five", "six"}value or expression?;1389
+foreach (var nitem? in rangeInSteps(0, numbers.length() + 1, 2)source?) {
1390
Console.WriteLine(numbers[n]arguments?); // print statement1391
} // end foreach
} // end main
+Sub main()
1392
Dim numbersname? = {"zero", "one", "two", "three", "four", "five", "six"}value or expression? ' variable definition1393
+For Each nitem? In rangeInSteps(0, numbers.length() + 1, 2)source?
1394
Console.WriteLine(numbers(n)arguments?) ' print statement1395
Next n
End Sub
+static void main() {
1396
var numbersname? = list("zero", "one", "two", "three", "four", "five", "six")value or expression?;1397
+foreach (var nitem? in rangeInSteps(0, numbers.length() + 1, 2)source?) {
1398
System.out.println(numbers[n]arguments?); // print statement1399
} // 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 statement1405
} // end main
+Sub main()
1406
Console.WriteLine(primesFromList(range(2, 100))arguments?) ' print statement1407
End Sub
+static void main() {
1408
System.out.println(primesFromList(range(2, 100))arguments?); // print statement1409
} // 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 getNodeForname?(p as Pointparameter definitions?) returns NodeType?
1410
variable matchesname? 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 getNodeForname?(p: Pointparameter definitions?) -> NodeType?:
# function1413
matchesname? = self.nodes.filter(lambda n: Node: n.point.equals(p))value or expression? # variable definition1414
return if_(matches.length() == 1, matches.head(), emptyNode())value or expression?1415
# end function
+static NodeType? getNodeForname?(Point pparameter definitions?) {
// function1416
var matchesname? = 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 getNodeForname?(p As Pointparameter definitions?) As NodeType?
1419
Dim matchesname? = Me.nodes.filter(Function (n As Node) n.point.equals(p))value or expression? ' variable definition1420
Return if_(matches.length() = 1, matches.head(), emptyNode())value or expression?1421
End Function
+static NodeType? getNodeForname?(Point pparameter definitions?) {
// function1422
var matchesname? = 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 liname? 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
liname? = [1, 2, 3, 4, 5]value or expression? # variable definition1429
print(li.map(lambda n: int: pow(n, 3))arguments?)1430
# end main
+static void main() {
1431
var liname? = new [] {1, 2, 3, 4, 5}value or expression?;1432
Console.WriteLine(li.map(int n => pow(n, 3))arguments?); // print statement1433
} // end main
+Sub main()
1434
Dim liname? = {1, 2, 3, 4, 5}value or expression? ' variable definition1435
Console.WriteLine(li.map(Function (n As Integer) pow(n, 3))arguments?) ' print statement1436
End Sub
+static void main() {
1437
var liname? = list(1, 2, 3, 4, 5)value or expression?;1438
System.out.println(li.map((int n) -> pow(n, 3))arguments?); // print statement1439
} // 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 namesname? 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
namesname? = ["Tom", "Dick", "Harriet"]value or expression? # variable definition1444
print(names.map(lambda s: str: s.upperCase())arguments?)1445
# end main
+static void main() {
1446
var namesname? = new [] {"Tom", "Dick", "Harriet"}value or expression?;1447
Console.WriteLine(names.map(string s => s.upperCase())arguments?); // print statement1448
} // end main
+Sub main()
1449
Dim namesname? = {"Tom", "Dick", "Harriet"}value or expression? ' variable definition1450
Console.WriteLine(names.map(Function (s As String) s.upperCase())arguments?) ' print statement1451
End Sub
+static void main() {
1452
var namesname? = list("Tom", "Dick", "Harriet")value or expression?;1453
System.out.println(names.map((String s) -> s.upperCase())arguments?); // print statement1454
} // 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 statement1460
} // end main
+Sub main()
1461
Console.WriteLine(names.map(Function (s As String) reverse(s))arguments?) ' print statement1462
End Sub
+static void main() {
1463
System.out.println(names.map((String s) -> reverse(s))arguments?); // print statement1464
} // end main
|
⟶ | [moT, kciD, teirraH] |
● And this example from demo program maze-generator:
variable nname? set to p.neighbouringPoints().map(lambda p as Point => getValue(p, g))value or expression?1465
nname? = p.neighbouringPoints().map(lambda p: Point: getValue(p, g))value or expression? # variable definition1466
var nname? = p.neighbouringPoints().map(Point p => getValue(p, g))value or expression?;1467
Dim nname? = p.neighbouringPoints().map(Function (p As Point) getValue(p, g))value or expression? ' variable definition1468
var nname? = 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:
- 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.
- the function or
lambdalambdalambdalambdalambda to be applied, which itself requires two arguments:
- 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).
- 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 nname? 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
nname? = [0.1, 2, 2.5, 0.3, 5.75, 0.29]value or expression? # variable definition1474
print(n.reduce(0.0, lambda sum: float, m: float: (sum + m).round(2))arguments?)1475
# end main
+static void main() {
1476
var nname? = 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 statement1478
} // end main
+Sub main()
1479
Dim nname? = {0.1, 2, 2.5, 0.3, 5.75, 0.29}value or expression? ' variable definition1480
Console.WriteLine(n.reduce(0.0, Function (sum As Double, m As Double) (sum + m).round(2))arguments?) ' print statement1481
End Sub
+static void main() {
1482
var nname? = 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 statement1484
} // 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 nname? set to [2, 3, 5, 7, 11, 13]value or expression?1486
variable nRname? set to new List<of Int>()value or expression?1487
variable eLname? 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
nname? = [2, 3, 5, 7, 11, 13]value or expression? # variable definition1491
nRname? = list[int]()value or expression? # variable definition1492
eLname? = list[int]()value or expression? # variable definition1493
print(n.reduce(eL, lambda nR: list[int], m: int: nR.withPrepend(m))arguments?)1494
# end main
+static void main() {
1495
var nname? = new [] {2, 3, 5, 7, 11, 13}value or expression?;1496
var nRname? = new List<int>()value or expression?;1497
var eLname? = new List<int>()value or expression?;1498
Console.WriteLine(n.reduce(eL, List<int> nR, int m => nR.withPrepend(m))arguments?); // print statement1499
} // end main
+Sub main()
1500
Dim nname? = {2, 3, 5, 7, 11, 13}value or expression? ' variable definition1501
Dim nRname? = New List(Of Integer)()value or expression? ' variable definition1502
Dim eLname? = New List(Of Integer)()value or expression? ' variable definition1503
Console.WriteLine(n.reduce(eL, Function (nR As List(Of Integer), m As Integer) nR.withPrepend(m))arguments?) ' print statement1504
End Sub
+static void main() {
1505
var nname? = list(2, 3, 5, 7, 11, 13)value or expression?;1506
var nRname? = new List<int>()value or expression?;1507
var eLname? = new List<int>()value or expression?;1508
System.out.println(n.reduce(eL, (List<int> nR, int m) -> nR.withPrepend(m))arguments?); // print statement1509
} // 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 sname? set to "'Twas brillig and the slithy toves"value or expression?1511
variable sRname? set to ""value or expression?1512
variable eLname? set to new List<of String>()value or expression?1513
assign sRvariableName? to s.split(" ").reduce(eL, lambda sR as List<of String>, word as String => sR.withPrepend(word)).join(" ")value or expression?1514
print(sRarguments?)1515
end main
+def main() -> None:
1516
sname? = "'Twas brillig and the slithy toves"value or expression? # variable definition1517
sRname? = ""value or expression? # variable definition1518
eLname? = list[str]()value or expression? # variable definition1519
sRvariableName? = s.split(" ").reduce(eL, lambda sR: list[str], word: str: sR.withPrepend(word)).join(" ")value or expression? # assignment1520
print(sRarguments?)1521
# end main
+static void main() {
1522
var sname? = "'Twas brillig and the slithy toves"value or expression?;1523
var sRname? = ""value or expression?;1524
var eLname? = new List<string>()value or expression?;1525
sRvariableName? = s.split(" ").reduce(eL, List<string> sR, string word => sR.withPrepend(word)).join(" ")value or expression?; // assignment1526
Console.WriteLine(sRarguments?); // print statement1527
} // end main
+Sub main()
1528
Dim sname? = "'Twas brillig and the slithy toves"value or expression? ' variable definition1529
Dim sRname? = ""value or expression? ' variable definition1530
Dim eLname? = New List(Of String)()value or expression? ' variable definition1531
sRvariableName? = s.split(" ").reduce(eL, Function (sR As List(Of String), word As String) sR.withPrepend(word)).join(" ")value or expression? ' assignment1532
Console.WriteLine(sRarguments?) ' print statement1533
End Sub
+static void main() {
1534
var sname? = "'Twas brillig and the slithy toves"value or expression?;1535
var sRname? = ""value or expression?;1536
var eLname? = new List<String>()value or expression?;1537
sRvariableName? = s.split(" ").reduce(eL, (List<String> sR, String word) -> sR.withPrepend(word)).join(" ")value or expression?; // assignment1538
System.out.println(sRarguments?); // print statement1539
} // 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 aname? 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
aname? = [33, 4, 0, 92, 89, 55, 102]value or expression? # variable definition1544
print(a.maxBy(lambda x: int: x % 10)arguments?)1545
# end main
+static void main() {
1546
var aname? = new [] {33, 4, 0, 92, 89, 55, 102}value or expression?;1547
Console.WriteLine(a.maxBy(int x => x % 10)arguments?); // print statement1548
} // end main
+Sub main()
1549
Dim aname? = {33, 4, 0, 92, 89, 55, 102}value or expression? ' variable definition1550
Console.WriteLine(a.maxBy(Function (x As Integer) x Mod 10)arguments?) ' print statement1551
End Sub
+static void main() {
1552
var aname? = list(33, 4, 0, 92, 89, 55, 102)value or expression?;1553
System.out.println(a.maxBy((int x) -> x % 10)arguments?); // print statement1554
} // end main
|
⟶ |
8989898989 |
● To find in a list the the shortest string:
+main
1555
variable fruitname? 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
fruitname? = ["apple", "orange", "pear"]value or expression? # variable definition1559
print(fruit.minBy(lambda x: str: x.length())arguments?)1560
# end main
+static void main() {
1561
var fruitname? = new [] {"apple", "orange", "pear"}value or expression?;1562
Console.WriteLine(fruit.minBy(string x => x.length())arguments?); // print statement1563
} // end main
+Sub main()
1564
Dim fruitname? = {"apple", "orange", "pear"}value or expression? ' variable definition1565
Console.WriteLine(fruit.minBy(Function (x As String) x.length())arguments?) ' print statement1566
End Sub
+static void main() {
1567
var fruitname? = list("apple", "orange", "pear")value or expression?;1568
System.out.println(fruit.minBy((String x) -> x.length())arguments?); // print statement1569
} // 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 bestFitLinename?(points as List<of Point>parameter definitions?) returns (Float, Float)Type?
1570
let sumXname? be points.sumBy(lambda p as Point => p.x)value or expression?1571
let sumXsqname? be points.sumBy(lambda p as Point => p.x*p.x)value or expression?1572
let sumYname? be points.sumBy(lambda p as Point => p.y)value or expression?1573
let sumXYname? be points.sumBy(lambda p as Point => p.x*p.y)value or expression?1574
let nname? be points.length()value or expression?1575
let aname? be (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression?1576
let bname? be (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression?1577
return (a, b)value or expression?1578
end function
+def bestFitLinename?(points: list[Point]parameter definitions?) -> tuple[float, float]Type?:
# function1579
sumXname? = points.sumBy(lambda p: Point: p.x)value or expression? # let1580
sumXsqname? = points.sumBy(lambda p: Point: p.x*p.x)value or expression? # let1581
sumYname? = points.sumBy(lambda p: Point: p.y)value or expression? # let1582
sumXYname? = points.sumBy(lambda p: Point: p.x*p.y)value or expression? # let1583
nname? = points.length()value or expression? # let1584
aname? = (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression? # let1585
bname? = (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression? # let1586
return (a, b)value or expression?1587
# end function
+static (double, double)Type? bestFitLinename?(List<Point> pointsparameter definitions?) {
// function1588
var sumXname? = points.sumBy(Point p => p.x)value or expression?; // let1589
var sumXsqname? = points.sumBy(Point p => p.x*p.x)value or expression?; // let1590
var sumYname? = points.sumBy(Point p => p.y)value or expression?; // let1591
var sumXYname? = points.sumBy(Point p => p.x*p.y)value or expression?; // let1592
var nname? = points.length()value or expression?; // let1593
var aname? = (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression?; // let1594
var bname? = (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression?; // let1595
return (a, b)value or expression?;1596
} // end function
+Function bestFitLinename?(points As List(Of Point)parameter definitions?) As (Double, Double)Type?
1597
Dim sumXname? = points.sumBy(Function (p As Point) p.x)value or expression? ' let1598
Dim sumXsqname? = points.sumBy(Function (p As Point) p.x*p.x)value or expression? ' let1599
Dim sumYname? = points.sumBy(Function (p As Point) p.y)value or expression? ' let1600
Dim sumXYname? = points.sumBy(Function (p As Point) p.x*p.y)value or expression? ' let1601
Dim nname? = points.length()value or expression? ' let1602
Dim aname? = (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression? ' let1603
Dim bname? = (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression? ' let1604
Return (a, b)value or expression?1605
End Function
+static (double, double)Type? bestFitLinename?(List<Point> pointsparameter definitions?) {
// function1606
var sumXname? = points.sumBy((Point p) -> p.x)value or expression?; // let1607
var sumXsqname? = points.sumBy((Point p) -> p.x*p.x)value or expression?; // let1608
var sumYname? = points.sumBy((Point p) -> p.y)value or expression?; // let1609
var sumXYname? = points.sumBy((Point p) -> p.x*p.y)value or expression?; // let1610
var nname? = points.length()value or expression?; // let1611
var aname? = (sumY*sumXsq - sumX*sumXY)/(n*sumXsq - sumX*sumX)value or expression?; // let1612
var bname? = (n*sumXY - sumX*sumY)/(n*sumXsq - sumX*sumX)value or expression?; // let1613
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 numbersname? set to [27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23]value or expression?1615
numbersname? = [27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23]value or expression? # variable definition1616
var numbersname? = new [] {27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23}value or expression?;1617
Dim numbersname? = {27, 2, 3, 5, 7, 31, 37, 11, 23, 13, 19, 23}value or expression? ' variable definition1618
var numbersname? = 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 namesname? 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
namesname? = ["Simon", "Pauline", "Jason", "Zelda", "Edith", "Lance", "Alice", "Paul"]value or expression? # variable definition1624
print(names.orderBy(lambda x: str, y: str: x.isBefore(y))arguments?)1625
# end main
+static void main() {
1626
var namesname? = 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 statement1628
} // end main
+Sub main()
1629
Dim namesname? = {"Simon", "Pauline", "Jason", "Zelda", "Edith", "Lance", "Alice", "Paul"}value or expression? ' variable definition1630
Console.WriteLine(names.orderBy(Function (x As String, y As String) x.isBefore(y))arguments?) ' print statement1631
End Sub
+static void main() {
1632
var namesname? = 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 statement1634
} // 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 PupilName? inheritance?1635
property mathsPercentname? as IntType?1636
+constructor(parameter definitions?)
1637
new code
end constructor
+function toStringname?(parameter definitions?) returns StringType?
1638
return "undefined"value or expression?1639
end function
end class
+class PupilName? inheritance?: # concrete class1640
mathsPercentname?: intType? # property1641
+def __init__(self: Pupil) -> None:
1642
new code
# end constructor
+def toStringname?(self: Pupil) -> strType?:
# function method1643
return "undefined"value or expression?1644
# end function method
# end class
+class PupilName? inheritance? {1645
public intType? mathsPercentname? {get; private set;} // property1646
+public Pupil(parameter definitions?) {
1647
new code
} // end constructor
+public stringType? toStringname?(parameter definitions?) {
// function method1648
return "undefined"value or expression?;1649
} // end function method
} // end class
+Class PupilName? inheritance?1650
Property mathsPercentname? As IntegerType?1651
+Sub New(parameter definitions?)
1652
new code
End Sub
+Function toStringname?(parameter definitions?) As StringType?
1653
Return "undefined"value or expression?1654
End Function
End Class
+class PupilName? inheritance? {1655
public intType? mathsPercentname?; // property1656
+public Pupil(parameter definitions?) {
1657
new code
} // end constructor
+public StringType? toStringname?(parameter definitions?) {
// function method1658
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
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