Elan Library 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 meaningOfLife set to 42

Default value

0

Dot methods

MethodReturnsParametersDescription
Functions
asBinaryString
asStringString

Constraints

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

MethodReturnsParametersDescription
Functions
asStringString
ceilingIntreturns first integer larger than or equal to the floating-point number
floorIntreturns first integer smaller than or equal to the floating-point number
roundFloatplacesIntreturns the number rounded to the number of decimal places specified as the argument

Constraints

Since Elan compiles to JavaScript, the constraints on floating point numbers are those of JavaScript:

For greater detail, refer to the official JavaScript documentation.

  • A variable that has been defined as being of Type Float may not be passed as an argument into a method that requires an Int, nor as an index into an List, even if the variable contains no fractional part.
    It may, however, be converted into an Int before passing, using the functions floor() or ceiling():
    floor() returns the integer value left by removing any fractional part, and
    ceiling() returns the lowest integer greater than the Float value if does have a fractional part.
  • If you wish to define a variable to be of Type Float but initialise it with an integer value then add .0 on the end of the whole number, for example:
    variable a set to 3.0.
  • 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 lower case

    Default value

    false

    Dot methods

    MethodReturnsParametersDescription
    Functions
    asString String as

    String

    A String represents ‘text’ i.e. a sequence of zero or more characters.

    Type name

    String

    Defining a literal string value

    variable a set to "Hello"

    Strings are always delineated by double-quotes.

    Default value

    "", known as ‘the empty string’.

    Note

    Strings may be appended to using the plus operator, for example
    print "Hello" + " " + "World"

    A newline may be inserted within a string as \n, for example:
    print "Hello\nWorld"

    Dot methods

    MethodReturnsParametersDescription
    Functions
    asString String returns the string itself. (All types must have this method to be print-able.)
    asList List<of String> returns list of individual characters
    asUnicode Int returns the Unicode value of the first character of the string
    asRegExp RegExp returns the same string converted to RegExp (does not check whether the result would be a valid regular expression)
    asSet Set returns a set of the unique characters
    as
    Procedures
    as

    Interpolated string

    Elan strings are automatically interpolated. This means that you may insert the values of variables or simple expressions within a string by enclosing them in curly braces. For example (assuming that the variables a and b are already defined as integers) :
    print "{a} times {b} equals {a*b}"

    You cannot include the characters ", {, or } directly within a literal string because of their special meanings. Instead, you use the constants quotes, leftBrace and rightBrace respectively:
    print "This is double quote mark: " + quotes
    Alternatively, you can insert their Unicode codepoints by means of the unicode() standalone function:
    print "This is a double quote mark: " + unicode(34)

    or

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

    Dot methods on a String

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

    upperCase() returns String

    returns a new string based on the input with all alpha-characters in upper case.

    lowerCase() returns String

    returns a new string based on the input with all alpha-characters in lower case.

    contains(partString as String) returns Boolean

    takes a single parameter of Type String, and returns a Boolean value indicating whether or not that argument string is contained within the string on which contains was called. Usage:


    variable a set to "Hello World!"
    print a.contains("ello")

    prints true

    replace(match as String, replacement as String) returns String

    returns a new string where all occurrences of the match string are replaced with the replacement string.

    trim() returns String

    returns a new string based on the string on which the method is called, but with all leading and trailing spaces removed.

    indexOf(partString as String) returns Int

    The following methods are used for comparing strings alphabetically, for example in a sort routine:

    isBefore(otherString as String) returns Boolean
    isAfter(otherString as String) returns Boolean
    isBeforeOrSameAs(otherString as String) returns Boolean
    isAfterOrSameAs(otherString as String) returns Boolean
    asUnicode() returns Int

    returns the Unicode (integer) value for a character. If the string is more than one character long, the Unicode value returned is that for the first character in the string only. Note that the opposite method to create a single-character string from its numeric Unicode value is e.g. unicode(123) which returns "{".

    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:

    As in most languages, Elan tuples are immutable. Once defined they are effectively ‘read only’. You cannot alter any of the elements in a tuple nor (unlike a List for example) can you create a new tuple from an existing one with specified differences.

    You cannot deconstruct a tuple into a mixture of new and existing variables.

    tuples may be nested: you can define a tuple within a tuple.

    Standard data structures

    The four 'standard' data structures defined in the Elan library are summarised in the this table:

    All four are 'mutable' - meaning that their contents may be changes 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 datastructure, 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 - for example 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. The type for the members of the array must be one of: Int, Float, String, or Boolean. The size must also be specified when it is created, along with the value (of the specific member type) to which each member is initialised. It is not possible to append further items to an array, although it is possible to convert an array to a list using .asList() and then to extend or reduce that list.

    As in most languages, individual elements may be read 'by index'. However, to modify an element you must either call the put procedure-method, or use either withPut function-method.

    Array2D

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

    The type for the members is also specified when the array is defined and must be one of: Int, Float, String, or Boolean.

    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

    An List

  • While the members must all be of one type, that type is not limited to the simple value types: the member type may also be a user-defined type such as a class or record, or another list, or even an array.
  • The size may be dynamically extended. Indeed a list is either created empty to begin with, or initialised from a literal definition.
  • Dictionary

    A dictionary works like an array, but instead of requiring a numeric (integer) index, each entry has a 'key'. The type of the key - which must be one of Int, Float, String, or Boolean or a user-defined record type - is specified when the dictionary is created along with the type for the values, which may be any type.

    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 the procedural or functional programming paradigms.

    The five immutable data structures defined in the Elan library are summarised in the this table:

    More details on each type are given below:

    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:

    +main 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 end main

    Notes

    Available dot methods on a Set:

    print s.length()expression print s.contains(item)expression print s.add(item)expression print s.addFromList(list)expression print s.addFromList(array)expression print s.remove(item)expression print s.union(anotherSet)expression print s.difference(anotherSet)expression print s.intersection(anotherSet)expression print s.isDisjointFrom(anotherSet)expression print s.isSubsetOf(anotherSet)expression print s.isSupersetOf(anotherSet)expression print s.asList(anotherSet)expression print s.asImmutableList(anotherSet)expression print s.asString()expression

    Stack and queue

    StackQueue
    Create a new instancelet s be new Stack<of Int>()let q be new Queue<of Int>()
    Add an item (must be of correct Type)call s.push(item)call q.enqueue(item)
    Remove the next itemvariable item set to s.pop()variable item set to q.dequeue()
    View the next item to be removed
    without removing it
    variable item set to s.peek()variable item set to q.peek()
    Read the current lengths.length()q.length()

    Example use of a Stack:

    +main let skname be new Stack<of String>()expression print sk.length()expression call sk.pushprocedureName("apple"arguments) call sk.pushprocedureName("pear"arguments) print sk.length()expression print sk.peek()expression variable fruitname set to sk.pop()expression print fruitexpression set fruitvariableName to sk.pop()expression print fruitexpression print sk.length()expression end main

    Example use of a Queue:

    +main let quname be new Queue<of String>()expression print qu.length()expression call qu.enqueueprocedureName("apple"arguments) call qu.enqueueprocedureName("pear"arguments) print qu.length()expression print qu.peek()expression variable fruitname set to qu.dequeue()expression print fruitexpression set fruitvariableName to qu.dequeue()expression print fruitexpression print qu.length()expression end main

    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 way:

    ListImmutable<of String> for a ListImmutable of TypeString
    ListImmutable<of Int> for a ListImmutable of Type >Int
    ListImmutable<of ListImmutable<of Int>> for a ListImmutable of Lists of Type Int

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

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

    Dot methods on a ListImmutable

    The dot methods on a list are all functions.

    myList.contains(item) returns true or false
    myList.asList() returns a new List with the same contents as myList

    The following functions all return a new ListImmutable, copied from the ListImmutable on which the function was called, but with the differences specified by the function parameters:

    myList.withInsert(4, "cherry")
    myList.withPut(2, "grape")
    myList.withRemoveAt(3)
    myList.withRemoveFirst("apple")
    myList.withRemoveAll("apple")

    Try these examples:

    variable fruit set to empty ListImmutable<of String>
    print fruit
    set fruit to fruit + "apple"
    set fruit to fruit + "pear"
    print fruit
    set fruit to "orange" + "pear"
    print fruit[0]
    print fruit.length()
    print fruit[fruit.length() -1]
    variable head:tail set to fruit
    print head
    print tail

    DictionaryImmutable

    An immutable dictionary may be defined in a constant.

    Type name

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

    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

    Dot methods on an Immutable Dictionary

    See also Quick reference.

    hasKey
    withPutKey
    withRemoveAtKey

    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.

    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:

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

    Notes

    Turtle graphics

    Example code:

    +main 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 t.pauseprocedureName(500arguments) end for end main

    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

    Example:

    +main1 variable vgname? set to new List<of VectorGraphic>()expression?2 let circname? be new CircleVG(20, 20, 5, red, green, 2)expression?3 call vg.appendprocedureName?(circarguments?)4 call displayVectorGraphicsprocedureName?(vglistOfVGs?)5 end main

    Output:

    Notes

    +main1 variable vgname? set to new List<of VectorGraphic>()expression?2 let circname? be new CircleVG(50, 37, 30, green, black, 1)expression?3 call vg.appendprocedureName?(circarguments?)4 +while truecondition?5 call displayVectorGraphicsprocedureName?(vglistOfVGs?)6 call pauseprocedureName?(700arguments?)7 call circ.setFillColourprocedureName?(redarguments?)8 call displayVectorGraphicsprocedureName?(vglistOfVGs?)9 call pauseprocedureName?(700arguments?)10 call circ.setFillColourprocedureName?(greenarguments?)11 end while end main

    Notes:

    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 -1none

    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

    converts a Unicode value (expressed as an integer value in decimal or hexadecimal notation) into a single character string. 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).

    Standalone procedures

    All procedures are accessed via a call statement.

    pause

    pause
    is used to slow down the execution of a program e.g. for a game. The argument provided to pause is in milliseconds, so pause(100) delays execution for one tenth of a second.

    clearPrintedText

    clearPrintedText()

    clearKeyBuffer

    clearKeyBuffer()

    printLine

    printLine(arg as String) prints the argument followed by a new line. The primary purpose of this is so that you may choose to do all printing via methods rather than mixing them in with print statements. Note that the argument must be provided as a String.

    printNoLine

    printNoLine(arg as String) does not automatically add a newline at the end, so you may subsequently print something else on the same line (unless you choose to include a newline \n within the string). Note that the argument must be provided as a String.

    printTab

    printTab(tabPosition as Int, arg as String) helps in the layout of information printed to the console, in particular, when printing columns of data. printTab requires an additional argument specifying the tab position which is number of characters from the left of the display. For example: Note that the argument must be provided as a String.

    +main 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 end main

    Right-align numeric output using a lambda function:

    +main 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 end main

    System methods

    System methods appear to work like functions, because:

    clock

    clock Returns an integer that increments every millisecond. It is useful for measuring elapsed time by comparing the values returned by two such evaluations of the clock method.

    getKey

    getKey()

    getKeyWithModifier

    getKeyWithModifier()

    inputString

    inputString(prompt as string)

    inputStringWithLimits

    inputStringWithLimits(prompt as string, minLength as Int, maxLength as Int)

    inputStringFromOptions

    inputStringFromOptions(prompt as String, options as List)

    inputInt

    inputInt(prompt as string)

    inputIntBetween

    inputIntBetween(prompt as string, min as Int, max as Int)

    inputFloat

    inputFloat(prompt as string)

    inputFloatBetween

    inputFloatBetween(prompt as string, min as Float, max as Float)

    openFileForReading

    openFileForReading: see Reading textual data from a file

    random

    random and randomInt: see Generating random numbers

    waitForAnyKey

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

    variable source set to {11, 3, 7, 37, 17, 2, 19, 5, 23, 27, 31, 13}
    print source.sortBy(lambda x as Int, y as Int => if x > y then 1 else -1).asImmutableList()

    The following are not HoFs, but are included here because they are most likely to be used with one of the HoFs listed above.

    range

    range(first as Int, last as Int) as ListImmutable<of Int>

    returns a ListImmutable containing all the integer values between the two argument values.

    Dot methods that work on many different Types

    .asString()
    .length()
    .head() returns the first item in a List or a ListImmutable

    Empty method table template

    MethodReturnsParametersDescription
    Functions
    asString String as
    Procedures
    as
    Elan Library Reference go to the top