Elan Library Reference
Links to documents: Elan Index and Symbols and Elan Language Reference

Value Types, with their methods

Integer

An integer or whole number, i.e. one that has no fractional component.

Type name

Int

Defining a literal integer

variable maxNumberOfAttempts set to 3

Default value

0

Dot methods on an Int

function
dot method
on
Type
argument
Types
return
Type
returns
asBinary Int (none) String string of binary digits equal in value to integer
asString Int (none) String string of decimal digits equal in value to integer

Notes

Float

A ‘floating point number’, i.e. a number that may have both integer and fractional parts.

Type name

Float

Defining literal floating point value

variable a set to 1.618
variable b set to 1.1e-10

Dot methods on a Float

function
dot method
on
Type
argument
Types
return
Type
returns
asString Float (none) String string representing the argument's floating point value
ceiling Float (none) Int the first integer larger than or equal to the argument's floating point value
floor Float (none) Int the first integer smaller than or equal to the argument's floating point value
round Float Int Float the value rounded to the number of decimal places specified in the argument

Notes

Boolean

A Boolean value is either true or false.

Type name

Boolean

Defining a literal Boolean

variable a set to true

true and false must be written in lower case

Default value

false

Dot method on a Boolean

function
dot method
on
Type
argument
Types
return
Type
returns
asString Boolean (none) String string "true" if true, "false" if false

String

A String represents ‘text’ i.e. a sequence of zero or more characters (see Character sets).

Type name

String

Defining a literal string value

variable a set to "Hello"

Strings are always delineated by double quotation marks.

Default value

"", known as ‘the empty string’.

Notes

There are no 'substring' methods in Elan because you can always use an index range to get a substring, e.g. s[3..7] gives a string containing the fourth character to the seventh character inclusive of s. Note that the upper bound of the range is exclusive. See Indexed Value.

There are, however, many dot methods that can be applied to strings, listed in the table below.

Dot methods on a String

function
dot method
on
Type
argument
Types
return
Type
returns
asString String (none) String the string itself
asList String (none) List<of String> a List of the individual characters
asUnicode String (none) Int the Unicode value of the first character of the string
(To convert a Unicode value into a string, use function unicode)
asRegExp String (none) RegExp 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
asSet String (none) Set a Setof the unique characters in the string
contains String (none) Boolean true if the string contains the substring specified as the argument
false otherwise
indexOf String String Int index of the first instance of the argument (substring) within the string
If it is not present, -1 is returned
isAfter String String Boolean true if alphabetic comparison finds the string comes strictly 'after' the argument string
false otherwise
isAfterOrSameAs String String Boolean true if alphabetic comparison finds the string comes 'after' or equals the argument string
false otherwise
isBefore String String Boolean true if alphabetic comparison finds the string comes strictly 'before' the argument string
false otherwise
isBeforeOrSameAs String String Boolean true if alphabetic comparison finds the string comes 'before' or equals the argument string
false otherwise
length String (none) Int the number of characters in the string
lowerCase String (none) String a new string with the original rendered in lower case
matchesRegExp String RegExp Boolean true if the string matches the regular expression
false otherwise
replace String String, String String a new string with all occurrences of the first argument string replaced by the second argument string
split String String List<of String> a List of the substrings found between occurrences of the argument string
trim String (none) String a new string with leading and trailing spaces removed
upperCase String (none) String a new string with the original rendered in upper case

Interpolated strings

Strings are automatically interpolated, that is you can insert the values of variables or simple expressions within a string by enclosing them in braces. For example (assuming that the variables a and b are already defined as integers):

print "{a} times {b} equals {a*b}"

prints the sentence with the values and calculated expression inserted.

If velocity and fuel are already defined as Float then:

set message to "LANDED SAFELY AT SPEED {(velocity*100).floor()} FUEL {fuel.floor()}"

updates variable message with calculated (and printable) integer values.

Special characters

You cannot include the characters ", {, or } directly within a literal string because of their special meanings. Instead, you use the constants quotes, openBrace and closeBrace respectively, e.g.

print "This is a double quotation mark: " + quotes

print "Here are the curly braces: {openBrace} and {closeBrace}"

Alternatively, you can insert their Unicode codepoint values (in decimal or hexadecimal) by means of function unicode:

print "Here are the curly braces: {unicode(123)} and {unicode(125)}"

print "This is an ASCII double quotation mark: " + unicode(0x22)

Character sets

Tuples

A tuple is a way of holding a small number of values of different Types together as a single reference. It may be considered a ‘lightweight’ alternative to defining a specific class for some purposes. Tuples are referred to as 2-tuples, 3-tuples, etc. according to the number of values they hold. Common uses include:

Using a tuple

You may pass a tuple into a function, or return one from a function, for example:

variable d set to distanceBetween(point1, tuple(12.34, 20.0))

An existing tuple (for example point1 below) may be ‘deconstructed’ into new variables or named values (where the number of variables/names must match the number of elements in the tuple):

let x, y set to point1
variable x, y set to point1


or into existing variables of the correct Type:

variable a set to 3
variable b set to 4
set a, b to point1

The ‘discard’ symbol _ (underscore) may also be used when deconstructing a tuple when there is no need to capture specific elements:

variable x, _ set to point1

Notes

Standard data structures

Standard data structures
Array Array2D List Dictionary
SizeStaticStaticDynamicDynamic
Type form
(example)
Array<of String>
of Type Int, Float, String, or Boolean
Array2D<of String>
of Type Int, Float, String, or Boolean
List<of String>
of any Type including Array
– or List for 'jagged' data
Dictionary<of String, Int>
key must be Int, Float, String, Boolean, or anyrecord. Value Type may be anything
literal N/A, but can convert literal list:
["a","b","c"].asArray()
N/A ["a","b","c"] ["a":3, "b":5]
create new Array<of String>(10, "")
any initial value of correct Type
new Array2D<of String>(5,8, "")
defines 5 arrays each of 8 elements
any initial value of correct Type
new List<of Int>()
created empty
can be 'of' any Type
new Dictionary<of String, Int>()
Key Type must be simple value or a record
Value Type can be any
read by index a[3] a2[3, 4] li[2] d["b"]
read range a[2..5]
lower bound is inclusive
upper bound is exclusive
N/A li[2..5]
lower bound is inclusive
upper bound is exclusive
N/A
procedure methods to mutate contents see Procedure methods on an Array see Procedure methods on an Array2D see Procedure methods on a List see Procedure methods on a Dictionary
function methods see Function methods on an Array see Function methods on an Array2D see Function methods on a List see Function methods on a Dictionary

All four are 'mutable' – meaning that their contents may be changed directly by calling the various procedure dot methods that each Type defines. However, since procedure methods may be called only from within the main routine, or from within another procedure, it is also possible to make changes via function dot methods – which return a copy of the current data structure, with the specified changes – which is why all such methods have names starting with....

All four data structures contain values of a single Type – that Type either being specified explicitly as in of <procedure> Int – or implictly if the structure is created from its literal definition form. (Dictionary is defined by two types: one for the 'keys' and one for the 'values').

Array

An array is a simple data structure containing n elements of a single Type, indexed from 0 to n-1.

The array elements' Type must be one of Int, Float, String, or Boolean.

As in most languages, individual elements may be read by their index.

To modify an element you may either call the put procedure method, or use withPut function method.

Its size is specified when it is created, along with the single value to which each element is initialised.

It is not possible to append further elements to an array, but you can convert an array to a list using method asList and then extend or reduce the list.

Procedure methods on an Array

procedure
method
on
Type
argument
Types
action
put Array Int,
item of Array element's Type
puts the item at the (integer) index position in the array

Function methods on an Array

function
method
on
Type
argument
Types
return
Type
returns
withPut Array Int,
item of Array element's Type
Array a new Array with the item at the (integer) index position
asList Array (none) List the contents of the Array as a List
asString Array (none) String a String that is a comma+space-separated list of the Array'elements enclosed in square brackets
contains Array item of Array element's Type Boolean true if the Array contains the value
false otherwise
indexOf Array item of Array element's Type Int the index position of the first occurrence of the argument value in the array,
or -1 if no match is found
length Array (none) Int the number of elements in the array

Array2D

The Array2D Type defines a 2-dimensional array of fixed size. The two dimensions, which are specified when the array is created, may be of the same size (a 'square' array) or different (a 'rectangular' array). If you want to create a 'jagged' array, you should use a List of Lists.

The convention is to refer to the position of an element in such an array by two index values (x,y), where x is the column number and y is the row number of a rectangular grid.

The Type for the elements is also specified when the Array is defined and must be one of: Int, Float, String, or Boolean.

Procedure methods on an Array2D

procedure
method
on
Type
argument
Types
action
put Array2D Int, Int, item of Array2D element's Type puts the item at the (two integers) index position in the array

Function methods on an Array2D

function
dot method
on
Type
argument
Types
return
Type
returns
withPut Array2D Int, Int,
item of Array2D element's Type
Array2D a new Array2D with the item at the (two integers) index position in the array
asString Array2D (none) String a String that is a comma+space-separated list of the Array2D's columns each of which contains a comma+space-separated list of row values enclosed in square brackets, the whole enclosed in square brackets
columns Array2D (none) Int the number of columns in the array (the maximum x value)
contains Array2D item of Array2D element's Type Boolean true if the Array2D contains the item
false otherwise
indexOf Array2D item of Array2D element's Type Int, Int a Tuple containing the index pair of the first occurrence of the argument's value in the array by searching the colums, or (-1,-1) if no match is found
rows Array2D (none) Int the number of rows in the array (the maximum y value)

You can read individual elements with a double index, for example:

for col from 0 to 7 step 1
for row from 0 to 7 step 1
print board[col, row]
end for
end for

List

A List is similar to an Array in that its n elements are all of one Type and are indexed from 0 to n-1, but is more flexible because:

Procedure methods on a List

procedure
method
on
Type
argument
Types
action
append List item of List element's Type the item is added to the end of the List.
appendList List List the argument List is added to the end of the List.
insert List Int,
item of List element'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 List item of List element's Type the item is is added to the start of the List.
prependList List List the argument List is added to the start of the List.
put List Int,
item of List element's Type
replace the item at the given index with the argument item.
removeAll List
removeAt List Int delete the item at the argument index.
removeFirst List

Function methods on a List

function
dot method
on
Type
argument
Types
return
Type
returns
asArray List (none) Array a new Array containing the same elements.
asListImmutable List whose elements are of an immutable Type (none) ListImmutable a new ListImmutable containingthe same elements.
asSet List (none) Set a new Set containing all the unique elements in the List.
asString List (none) String a string representation of the List.
contains List List element's Type Boolean true if the List contains the specified element
false otherwise.
filter List
head List (none) List element's Type the first element of the List.
indexOf List List element's Type Int index of the first occurrence of the argument value in the List,
or -1 if no match is found.
join List<of String>
String String a single String that joins all the elements in the list,
with the specified String (which can be empty) inserted between the elements.
length List (none) Int the number of elements in the List
map List
maxBy List
minBy List
reduce List
sortBy List
withAppend List
withAppendList List
withInsert List
withPrepend List
withPrependList List
withPut List
withRemoveAll List
withRemoveAt List
withRemoveFirst List

Dictionary

A Aictionary works like an Array, but instead of requiring a numeric (integer) index, each entry has a 'key'. Each key is associated with a value, so the Dictionary is a set of key:value pairs The key's Type must be one of Int, Float, String or Boolean, or it may be a user-defined record. The values may be of any Type, and the Types of both key and value are fixed when the Dictionary is created.

Procedure methods on a Dictionary

procedure
method
on
Type
argument
Types
action
put Dictionary
removeAt Dictionary

Function methods on a Dictionary

function
dot method
on
Type
argument
Types
return
Type
returns
asString Dictionary (none) String a string representation of the dictionary (automatically called when printing)
keys Dictionary (none)
values Dictionary (none)

Immutable data structures

In constrast to the standard data structures, immutable data structures cannot be modified directly – and hence define no procedure dot methods. Instead, changes are made by using function dot methods that copy the existing data structure, but with specified differences. Immutable data structures are intended specifically to facilitate the Functional Programming paradigm, but some are also useful within other programming paradigms.

The five immutable data structures defined in the Elan library are summarised in this table. More details on each Type are given below the table.

Immutable data structures
ListImmutable DictionaryImmutable Set Stack Queue
SizeDynamicDynamicDynamicDynamicDynamic
Type ListImmutable<of String>
element Type must be immutable
DictionaryImmutable<of String, Int>
Key Type must be Int, Float, String, Boolean or any record
Value Type may be any immutable Type
Set<of String>
element Type must be immutable
Stack<of String>
element Type must be immutable
Queue<of String>
element Type must be immutable
literal {a","b","c"} {"a":3, "b":5} None, but can convert literal list:
["a","b","c"].asSet()
None None
create new ListImmutable<ofString>()
created empty
must be 'of' an immutable Type
new DictionaryImmutable<of String, Int>()
created empty
Key and Value Types must be immutable
new Set<of String>()
created empty
must be 'of' an immutable Type
new Stack<of String>() new Queue<of String>()
read by Key lim[2] di["b"] N/A N/A N/A
read range lim[2..5]
upper bound exclusive
N/A N/A N/A N/A function methods see Function methods on a ListImmutable see Function methods on a DictionaryImmutable see Function methods on a Set see Function methods on a Stack see Function methods on a Queue

ListImmutable

A ListImmutable is like a List but is immutable (like a String) You can still insert, delete, or change elements in a ListImmutable, but the methods for these operations do not modify the input ListImmutable: they return a new ListImmutable based on the input ListImmutable but with the specified differences.

Type name

The Type is specified in the following ways:

Creating a ListImmutable

A ListImmutable may be defined in ‘literal’ form, delimited by curly braces, and with all the required elements separated by commas. The elements may be literal values but must all be of the same Type, for example:

variable fruit set to {"apple", "orange", "pear"}

Function methods on a ListImmutable

function
dot method
argument
Types
return
Type
returns
contains item of List element's Type Boolean true if the List contains the item
false otherwise
head (none) item of List element's Type the first item in the List
asList (none) ListImmutable copy of the List
asString (none) String a String that is a comma+space-separated list of the List's elements enclosed in braces
length (none) Int the number of elements in the List
withInsert Int, item of List element's Type ListImmutable copy of the List with the item inserted at specified position
withPut Int, item of List element's Type ListImmutable copy of the List with the item replacing what was at specified position
withRemoveAt Int ListImmutable copy of the List with the item at specified position removed
withRemoveFirst item of List element's Type ListImmutable copy of the List with the first occurrence of the item removed
withRemoveAll item of List element's Type ListImmutable copy of the List with all occurrences of the item removed

Try these examples:

# reusing variable fruit for each new ListImmutablecomment variable fruitname set to empty ListImmutable<of String>expression print fruitexpression set fruitvariableName to fruit.withAppend("apple")expression set fruitvariableName to fruit.withAppend("pear")expression print fruitexpression print fruit[1]expression print fruit.length()expression print fruit[fruit.length() - 2]expression print fruit.contains("banana")expression

DictionaryImmutable

An immutable dictionary may be defined in a constant.

Type name

In the following example, the keys are of Type String, and the values associated with the keys are of Type Int:

DictionaryImmutable<of String, Int>

Defining a literal DictionaryImmutable

A literal DictionaryImmutable is defined as a comma-separated list of ‘key:value pairs’ (key,colon.value) surrounded by curly braces:

variable scrabbleValues set to {"a":1, "b":3, "c":3, "d":2}

Using an Immutable Dictionary

Try these examples:

variable immD set to new DictionaryImmutable<of String,Int>()
print immD
set immD to immD.withPutKey("a", 3)
print immD["a"]
set immD to immD.withRemoveAtKey("a")
print immD

Function methods on a DictionaryImmutable

function
dot method
on
Type
argument
Types
return
Type
returns
hasKey DictionaryImmutable
withPutKey DictionaryImmutable
withRemoveAtKey DictionaryImmutable
asString DictionaryImmutable (none) String a string representation of the immutable dictionary (automatically called when printing)

Set

A set is a standard data structure that works somewhat like a ListImmutable with the important difference that in a set a given element may appear only once. If an item being added to a Set is identical to an existing item in the Set then the Set remains the same length as before.

This enables a set to work like a mathematical set so that it is possible to perform standard set operations such as union or intersection. For the same reason, a Set is an immutable data structure: there are no methods modify the set on which they are called, but several of them (including add, remove) return a new set that is based on the original set or sets, with specified differences.

Example of use:

variable stname set to new Set<of Int>()expression set stvariableName to st.addFromList([3, 5, 7])expression print st.length()expression set stvariableName to st.add(7)expression print st.length()expression set stvariableName to st.remove(3)expression print st.length()expression set stvariableName to st.remove(3)expression print st.length()expression print stexpression

Notes

Function methods on a Set

function
dot method
on
Type
argument
Types
return
Type
returns
add Set item of Set element's Type Set copy of the Set extended with the item provided it differs from all the Set's current elements
addFromList Set List Set copy of the Set extended with those items from the List that are not already in the Set
asList Set (none) List a List containing the Set's elements
asString Set (none) String a String that is a comma+space-separated list of the Set's elements enclosed in braces
contains Set item of Set element's Type Boolean true if the Set contains the item
false otherwise
difference Set Set Set a Set containing those elements of the Set that do not occur in the argument Set
intersection Set Set Set a Set containing those elements common to both the Set and the argument Set
isDisjointFrom Set Set Boolean true if the Set has no items in common with the argument Set
false otherwise
isSubsetOf Set Set Boolean true if all the Set's items are also in the argument Set
false otherwise
isSupersetOf Set Set Boolean true if the Set contains all the items that are in the argument Set
false otherwise
length Set (none) Int the number of elements in the Set
remove Set item of Set element's Type Set copy of the Set with the argument item removed (if present)
union Set Set Set a Set containing all the unique elements of the Set and the argument Set (i.e. no duplicates)

Stack and Queue

Function methods on a Stack

function
dot method
on
Type
argument
Types
return
Types
returns
push Stack item of Stack element's Type Stack the Stack with the element added to the top of the Stack
pop Stack (none) Stack element Type,
Stack
the topmost element of the Stack, and the Stack with the element removed
peek Stack (none) Stack element Type the topmost element of the Stack (without altering the Stack)
length Stack (none) Int the number of elements in the Stack
asString Stack (none) String a string representation of the stack (automatically called when printing)

Function methods on a Queue

function
dot method
on
Type
argument
Types
return
Types
returns
enqueue Queue item of Queue element's Type Queue the Queue with the element add to the end of the Queue
dequeue Queue (none) Queue element Type,
Queue
the next element of the Queue, and the Queue with the element removed
peek Queue (none) Queue element type the next element of the Queue (without altering the Queue)
length Queue (none) Int the number of elements in the Queue
asString Queue (none) String a string representation of the queue (automatically called when printing)

Example use of a Stack:

variable stname set to new Stack<of String>()expression print st.length()expression set stvariableName to st.push("apple")expression set stvariableName to st.push("Pear")expression print st.length()expression print st.peek()expression variable fruitname set to ""expression set fruit, stvariableName to st.pop()expression print fruitexpression set fruit, stvariableName to st.pop()expression print fruitexpression print st.length()expression

Example use of a Queue:

variable quname set to new Queue<of String>()expression print qu.length()expression set quvariableName to qu.enqueue("apple")expression set quvariableName to qu.enqueue("Pear")expression print qu.length()expression print qu.peek()expression variable fruitname set to ""expression set fruit, quvariableName to qu.dequeue()expression print fruitexpression set fruit, quvariableName to qu.dequeue()expression print fruitexpression print qu.length()expression

Common dot methods

Dot methods that work on more than one fundamental Type

Although all applicable methods are described under each Type, this table lists those which are applicable to several Types.

Typemethod
asList asString contains head indexOf length peek
Int
Float
Boolean
String
Array
Array2D
List
Dictionarysee notessee notes
ListImmutable
DictionaryImmutablesee notessee notes
Set
Stack
Queue

Notes

Input/output

Reading Text Files

The TextFileReader class is used to read textual data from a file. An instance is created by the standalone system method openFileForReading, on which the dot methods the following methods may be invoked:

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

let filename be openFileForReading()expression let textname be file.readWholeFile()expression call file.closeprocedureName(arguments) print textexpression

or to read a file line by line:

+main let filename be openFileForReading()expression variable linesname set to empty List<of String>expression +while not file.endOfFile()condition let linename be file.readLine()expression call lines.appendprocedureName(linearguments) end while call file.closeprocedureName(arguments)

Notes

Writing text files

The TextFileWriter class is used to write textual data to a file. An instance is created by the standalone system method createFileForWriting, on which the dot methods the following methods may be invoked:

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

let fname be createFileForWriting("myFile.txt")expression call f.writeWholeFileprocedureName("this is\nmyText"arguments)

or to write a file line by line:

+main let filename be createFileForWriting("squares.txt")expression +for ivariableName from 1expression to 100expression step 1expression call file.writeLineprocedureName("{i} {i*i}"arguments) end for call file.saveAndCloseprocedureName(arguments) end main

Notes

+try call file.saveAndCloseprocedureName(arguments) +catch exception in evariableName print "File save cancelled"expression end try

or you could make the code offer the user options: to save again, or to continue without saving.

Display Html

If you attempt to embed Html 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 on the Display. The following code:

call displayHtmlprocedureName("<h1 style='color: blue;'>A heading</h1><p>some text</p>"html)

will produce:

This Html forms another 'layer' of the Display. Any plain text that you print (using print or any of the print... procedures) will be overlaid on top of this.

You can programmatically clear just the Html display using the procedure clearDisplay.

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 quotes within braces as an interolated field.

Using an embedded stylesheet

You can also specify a style tag at the start of your Html string, to apply to the whole Html being displayed:

let stylename be "<style> h1 {openBrace} color: DarkRed; font-size: 24pt; {closeBrace} p {openBrace} font-family: Serif;{closeBrace} </style>"expression call displayHtmlprocedureName("{style}<h1>New heading</h1><p>some new text</p>"arguments)

producing this result:

Handling images

Printing an image on the Display

An image that can be accessed via a URL may be printed on the display using the image keyword followed by the URL. Here, the URL is not bounded by quotes:

print expression

As soon as you leave the field the text will change to show a thumbnail copy of the image:

print expression

If you edit the field again, the keyword and URL will be shown.

Acknowledgement: The idea of displaying an image value as a thumbnail within the code was inspired by a similar feature in the language Strype. We are grateful to Prof. Michael Kölling and the team at King's College, London responsible for Strype, who showed us this feature in confidence before its release, but nonetheless generously allowed us to mimic it in Elan.

When the code is run the image will be printed on the Display, but still thumbnail sized. You can specify dimensions by using a with clause like this:

print expression

The with clause also permits you to specify a title for the image, which shows up as a tooltip on the image. It is good practice to do this for meeting accessibility guidelines.The with clause also offers position properties x and y. These are ignored when printing an image, but are useful in the context of drawing Vector Graphics.

An image specified in this way may also be assigned to a named value, or defined inline as an argument to a method, for example:

let sharkname be expression

The Type of a named value that holds an image is ImageVG – the 'VG' indicating that this type is compatible with vector graphics, so an image may be added to a List<of VectorGraphic> or displayed directly by:

call displayVectorGraphicsprocedureName(listOfVGs)

In this usage the position may be controlled by specifying the x and y coordinates for the top-left corner.

It is also possible to instantiate an ImageVG explicitly, but in this case you must provide the URL as a String, either as a literal (by surrounding it with quotes) or as a named value, for example:

let urlname be "https://upload.wikimedia.org/wikipedia/commons/0/08/Corl0207_%2828225976491%29.jpg"expression let img1name be new ImageVG(url)expression print img1expression

Block graphics

Block graphics provides a simple way to create low resolution graphics, ideal for simple but engaging games for example. The graphics are 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:

variable blocksname set to new Array2D<of Int>(40, 30, white)expression +while truecondition let xname be randomInt(0, 39)expression let yname be randomInt(0, 29)expression let colourname be randomInt(0, white - 1)expression call blocks.putprocedureName(x, y, colourarguments) call displayBlocksprocedureName(blocksarguments) end while

Notes

Turtle graphics

Turtle graphics are implemented in Elan with output to the Display pane on the screen (i.e. the ‘paper’ on which the Turtle draws). The area is 100 turtle units wide by 75 turtle units high.

Example:

let tname be new Turtle()expression call t.placeAtprocedureName(10, 10arguments) call t.showprocedureName(arguments) +for ivariableName from 1expression to 4expression step 1expression call t.turnprocedureName(90arguments) call t.moveprocedureName(40arguments) call pauseprocedureName(500arguments) end for

Output:

Notes

Here is a more sophisticated example, using a procedure and recursion, that produces a fractal snowflake:

+main variable tname set to new Turtle()expression call t.placeAtprocedureName(20, 20arguments) call t.turnprocedureName(90arguments) call t.showprocedureName(arguments) +for ivariableName from 1expression to 3expression step 1expression call drawSideprocedureName(side, targuments) call t.turnprocedureName(120arguments) end for end main
+procedure drawSidename(length as Float, t as Turtleparameter definitions) +if (length > 1)condition then let thirdname be length/3expression call drawSideprocedureName(third, targuments) call t.turnprocedureName(-60arguments) call drawSideprocedureName(third, targuments) call t.turnprocedureName(120arguments) call drawSideprocedureName(third, targuments) call t.turnprocedureName(-60arguments) call drawSideprocedureName(third, targuments) else if call t.moveprocedureName(lengtharguments) end if end procedure +constant sidename set to 60literal value or data structure

Vector graphics

Vector graphics are displayed using SVG (Scalable Vector Graphics) that are a part of the Html specification. The names of the shapes broadly correspond to the names of SVG tags:

The properties of the Elan VG shapes match the names of the attributes used in the SVG tags, except that the stroke-width attribute is changed to strokeWidth to make it a valid Identifier.

The ‘canvas’ on which vector graphics are drawn (the Display pane in the user interface) is 100 units wide, by 75 units high. All numeric values specified for attributes of vector graphic shapes may be integer or floating point.

Example:

variable vgname set to new List<of VectorGraphic>()expression let circname be new CircleVG() with
centreX set to 20,
centreY set to 20,
radius set to 5,
fillColour set to red,
strokeColour set to green,
strokeWidth set to 2
expression
call vg.appendprocedureName(circarguments) call displayVectorGraphicsprocedureName(vgarguments)

Output:

This example creates a circle that changes between red and green every second:

variable vgname set to new List<of VectorGraphic>()expression let circname be new CircleVG() with
centreX set to 50,
centreY set to 37,
radius set to 30,
fillColour set to green
expression
call vg.appendprocedureName(circarguments) +while truecondition call displayVectorGraphicsprocedureName(vgarguments) call pauseprocedureName(700arguments) call circ.setFillColourprocedureName(redarguments) call displayVectorGraphicsprocedureName(vgarguments) call pauseprocedureName(700arguments) call circ.setFillColourprocedureName(greenarguments) end while

Notes

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 overwite) is:

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

so some care is needed to manage the layout in the Display.

Other Types

Func

A function may be passed as an argument into another function (or a procedure), or returned as the result of calling another function<. This pattern is known as ‘Higher order Function’ (HoF), and is a key idea in the functional programming paradigm. To define a function> that takes in another function as a parameter, or returns a function, you need to specify the Type of the function, just as you would specify the Type of every parameter and the return Type for the function.

Type name

The Type of any function< starts with the word Func followed by angle brackets defining the Type of each parameter, and the return Type for that function, following this syntax:

Func<of String, String, Int => Boolean>

This example defines the Type for a function that defines three parameters of Type String, String, and Int respectively, and returns a Boolean value. This Type would match that of a function definition that started:

+function charactersMatchAtname(a as String, b as String, position as Intparameter definitions) returns BooleanType

Constants

nameTypevalue
openBraceString {
closeBraceString }
quotesString "

Colours

colourdecimaldecimal
hexadecimal
nameinteger   R    G    B 0xrrggbb
black0   0    0    00x000000
white16777215 255  255  2550xffffff
red16711680 255    0    00xff0000
green32768  0  128    00x008000
blue255   0    0  2550x0000ff
yellow16776960 255  255    00xffff00
brown10824234 165   42   420xa52a2a
grey8421504 128  128  1280x808080
transparent-1N/AN/A

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

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 declaration (variable) or assignment (set), either on their own or within a more complex expression. All standalone library functions require at least one argument to be passed in brackets, corresponding to the parameters defined for that function.

unicode

Function unicode converts a Unicode value (expressed as an integer value in decimal or hexadecimal notation) into a string of a single character. For example:

+function heartsname(parameter definitions) returns StringType return unicode(0x2665)expression end function

parseAsInt and parseAsFloat

parseAsInt attempts to parse the input String as an Int and returns a 2-tuple, the first value of which is Boolean, with true indicating whether or not the parse has succeeded, and the second value being the resulting Int. parseAsFloat does the equivalent for floating point. Operation is illustrated with by these tests:

+test optional description assert parseAsInt("31")computed value is tuple(true, 31)expected value pass assert parseAsInt("0")computed value is tuple(true, 0)expected value pass assert parseAsInt("thirty one")computed value is tuple(false, 0)expected value pass assert parseAsInt("3.1")computed value is tuple(false, 0)expected value pass assert parseAsFloat("31")computed value is tuple(true, 31)expected value pass assert parseAsFloat("0")computed value is tuple(true, 0)expected value pass assert parseAsFloat("3.1")computed value is tuple(true, 3.1)expected value pass end test

Notes

floor, ceiling, round, isNaN, and IsInfinite

All of these functions are called as 'dot methods' on a numeric value of type Float or Int). NaN is short for 'Not A (Real) Number' Their use is illustrated with the following tests:

+test optional description let nname be 3.14159expression assert n.floor()computed value is 3expected value pass assert n.ceiling()computed value is 4expected value pass assert n.round(3)computed value is 3.142expected value pass assert sqrt(-1).isNaN()computed value is trueexpected value pass let xname be 1/0expression assert x.isInfinite()computed value is trueexpected value pass end test

Maths functions and constants

functionargument
Type
input
unit
returnsoutput
unit
pi(none)𝜋 = 3.141592653589793..
absFloatabsolute value of the input
acosFloatarccosine of the inputradians
asinFloatarcsine of the inputradians
atanFloatarctangent of the inputradians
acosDegFloatarccosine of the inputdegrees
asinDegFloatarcsine of the inputdegrees
atanDegFloatarctangent of the inputdegrees
cosFloatradianscosine of the input
cosDegFloatdegreescosine of the input
expFloat𝑒𝑥 where 𝑥 is the argument and
𝑒 is Euler's number 2.718281828459045..
the base of natural logarithms
logEFloatnatural logarithm of the input
log10Floatbase-10 logarithm of the input
log2Floatbase-2 logarithm of the input
sinFloatradianssine of the input
sinDegFloatdegreessine of the input
sqrtFloatpositive square root of the input
tanFloatradianstangent of the input
tanDegFloatdegreestangent of the input
degToRadFloatdegreesconverts input from degrees to radiansradians
radToDegFloatradiansconverts input from radians to degreesdegrees

Examples of some maths functions being tested:

+test optional description assert picomputed value is 3.141592653589793expected value pass assert abs(-3.7)computed value is 3.7expected value pass assert asin(0.5).round(3)computed value is 0.524expected value pass assert acos(0.5).round(3)computed value is 1.047expected value pass assert atan(1).round(2)computed value is 0.79expected value pass assert sin(pi/6).round(2)computed value is 0.5expected value pass assert cos(pi/4).round(3)computed value is 0.707expected value pass assert tan(pi/4).round(2)computed value is 1expected value pass assert exp(2).round(3)computed value is 7.389expected value pass assert logE(7.389).round(2)computed value is 2expected value pass assert log10(1000)computed value is 3expected value pass assert log2(65536)computed value is 16expected value pass assert log2(0x10000)computed value is 16expected value pass assert sqrt(2).round(3)computed value is 1.414expected value pass end test

Regular expressions

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 String using dot syntax and requires a RegExp parameter specified as a literal or as variable. It returns a Boolean. For example:

+test optional description let s1name be "hello"expression let s2name be "World"expression let rname be /^[a-z]*$/expression assert s1.matchesRegExp(r)computed value is trueexpected value pass assert s2.matchesRegExp(r)computed value is falseexpected value pass end test

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

+test optional description let s1name be "hello"expression let s2name be "World"expression let rname be "^[a-z]*$".asRegExp()expression assert s1.matchesRegExp(r)computed value is trueexpected value pass assert s2.matchesRegExp(r)computed value is falseexpected value pass end test

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

Bitwise functions

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

Examples of the bitwise functions being tested:

+test bitwiseoptional description variable aname set to 13expression assert acomputed value is 0xdexpected value pass assert acomputed value is 0b1101expected value pass assert a.asBinary()computed value is "1101"expected value pass variable bname set to 30expression assert bcomputed value is 0b11110expected value pass assert bitAnd(a, b)computed value is 0b1100expected value pass variable aobname set to bitOr(a, b)expression assert aobcomputed value is 0b11111expected value pass variable axbname set to bitXor(a, b)expression assert axbcomputed value is 0b10011expected value pass variable notaname set to bitNot(a)expression assert notacomputed value is -14expected value pass variable aLname set to bitShiftL(a, 2)expression assert aLcomputed value is 0b110100expected value pass assert bitShiftR(a, 2)computed value is 0b11expected value pass end test

The result of bitNot(a) being -14 , when a is 13, 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 00000000000000000000000000001101, and applying bitAnd gives 11111111111111111111111111110010 which is the value -14 in signed two’s complement format, the left-most bit being the sign (0 positive, 1 negative).

Sequence

The sequence is used to create a List containing a sequence of integer values as defined by the two (integer) parameters: start and end (both being inclusive values), for example:

Standalone procedures

All procedures are accessed via a call statement.

procedureinput
argument
Types
output
argument
Types
action
pause Int (none) pauses the execution of a program for the given number of milliseconds,
e.g. for a game pause(100) delays execution for one tenth of a second.
clearPrintedText (none) (none) clears the IDE's Display panel.
clearKeyBuffer (none) (none) clears the IDE's keyboard input.
printLine String (none) prints the string to the Display followed by a newline.
This method offers the means to do all printing via methods
rather than coding a mixture of call and print statements.
printNoLine String (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 Int, String (none) prints the string to the Display starting at the tab position given (from 0).

Method printTab helps in the layout of information printed to the Display, in particular, when printing columns of data. For example:

call printTabprocedureName(0, "Number"position, text) call printTabprocedureName(10, "Square"position, text) call printTabprocedureName(20, "Cube\n"position, text) +for ivariableName from 1expression to 10expression step 1expression call printTabprocedureName(0, i.asString()position, text) call printTabprocedureName(10, "{i^2}"position, text) call printTabprocedureName(20, "{i^3}\n"position, text) end for

Right-align numeric output using a lambda function:

variable tabname set to 10expression variable iname set to 0expression +for ivariableName from 1expression to (tab - 1)expression step 1expression variable jname set to 9^iexpression variable fname set to lambda j as Int => j.asString().length()expression call printTabprocedureName(tab - f(j), "{j}\n"arguments) end for

System methods

System methods appear to work like functions, because:

They are not, however, pure functions because:

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

System methods are all defined within the Elan standard library: you cannot write a system method yourself.

System methods are commonly associated with Input/output, but note that:

The reason those are system methods is that they have a dependency on variable data that is not passed into them as arguments.


system
method
argument
Types
return
Types
action
clock (none) Int returns the current value (in milliseconds) of a system clock.
Useful for measuring elapsed time by comparing the values returned by two calls.
getKey (none) String returns the character of the keyboard key pressed.
getKeyWithModifier (none) 2-tuple:
(String, String)
returns both the character of the keyboard key pressed
and the modifier key's name if also pressed.
inputString String String prints the string as a prompt, and returns the typed input when Enter is pressed.
inputStringWithLimits String, Int, Int String 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 String, List<of String> String 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 String Int 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 String, Int, Int Int 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 String Float 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 String, Int, Int Float 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.
openFileForReading (none) TextFileReader see Input/output
random (none) Float returns a random number in the range [0..1]
randomInt Int, Int Int returns a random number in the (inclusive) range between the two arguments.
waitForAnyKey

Library functions that process Lists

max and min

Both these functions may be applied to an ListImmutable<of Float> and return the maximum or minimum value found therein.

variable a set to {33, 4, 0,99, 82, 55}
print "Max: {a.max()} Min: {a.min()}"

Higher order functions (HoFs)

These dot methods are called on any List, ListImmutable or String. As ‘higher order functions’ they take either a lambda or a function reference as one of their arguments: see Passing a function as a reference.

Important: Several of these methods return a ListImmutable but this may be converted to an array using .asList() at the end of the expression.

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

filter

Usage:


let matches be rules.filter(lambda r as Rule =>
  (r.currentState is currentState) and (r.currentSymbol is tape[headPosition]))

map

Usage:

let next be cellRange.map(lambda n as Int => nextCellValue(cells, n))

reduce

Usage:


let d2 be possibleAnswers.reduce(d,
  lambda dd as Dictionary<of String, Int>, possAnswer as String =>
  incrementCount(dd, possAnswer, attempt))

maxBy and minBy

Alternative implementations of max and min:

variable a set to {33, 4, 0,99, 82, 55}
print a.maxBy(lambda x as Int => x mod 10)

sortBy

sortBy takes a lambda that takes two arguments (of the same Type as that of the ListImmutable being sorted) and compares them, returning an integer with one of the values -1, 0, or +1, to indicate whether the first argument should be placed respectively before, adjacent to or after the second argument in the sorted result, where ‘adjacent to’ means it does not matter whether before or after):

let numbersname be [27, 2, 3, 5, 7, 31, 37, 11, 13, 17, 19, 23]expression let sortedname be numbers.sortBy(lambda x as Int, y as Int => if x > y then 1
else
if x < y then -1
else
0)
expression
print sortedexpression

And similarly for string comparisons using methods isBefore and isAfter: let namesname be ["Simon", "Pauline", "Jason", "Zelda", "Edith", "Lance", "Alice", "Paul"]expression let sortedname be names.sortBy(lambda x as String, y as String => if x.isAfter(y) then 1
else
if x.isBefore(y) then -1
else
0)
expression
print sortedexpression


Elan Library Reference go to the top