# Literals

This chapters covers in detail the literals objects used to manipulate numbers and strings. First the integer, relatif and real numbers are described. There is a broad range of methods for these three objects that support numerical computation. As a second step, string and character objects are described. Many examples show the various operations which can be used as automatic conversion between one type and another. Finally, the boolean object is described. These objects belongs to the class of literal objects, which are objects that have a string representation. A special literal object known as regular expression or regex is also described at the end of this chapter. Literal

## Integer number

The fundamental number representation is the `Integer`. The integer is a 64 bits signed 2's complement number. Even when running with a 32 bits machine, the 64 bits representation is used. If a larger representation is needed, the `Relatif` object might be more appropriate. The `Integer` object is a literal object that belongs to the number class. Integer Number

### Integer format

The default literal format for an integer is the decimal notation. The minus sign (without blank) indicates a negative number. Hexadecimal and binary notations can also be used with prefix `0x` and `0b`. The underscore character can be used to make the notation more readable.

const a 123 trans b -255 const h 0xff const b 0b1111_1111

Integer number are constructed from the literal notation or by using an explicit integer instance. The `Integer` class offers standard constructors. The default constructor creates an integer object and initialize it to 0. The other constructors take either an integer, a real number, a character or a string.Integer format

const a (Integer) const b (Integer 2000) const c (Integer "23")

When the hexadecimal or binary notation is used, care should be taken to avoid a negative integer. For example, `0x_8000_0000_0000_0000` is the smallest negative number. This number exhibits also the strange property to be equal to its negation since with 2's complement, there is no positive representation.

### Integer arithmetic

Standard arithmetic operators are available as built-in operators. The usual addition `+`, multiplication `*` and division `/` operate with two arguments. The subtraction `-` operates with one or two arguments.+-*/ Integer arithmetic

+ 3 4 - 3 4 - 3 * 3 4 / 4 2

As a built-in object, the `Integer` object offers various methods for built-in arithmetic which directly operates on the object. The following example illustrates these methods.

trans i 0 i:++ i:-- i:+ 4 i:= 4 i:- 1 i:* 2 i:/ 2 i:+= 1 i:-= 1 i:*= 2 i:/= 2

As a side effect, these methods allows a const symbol to be modified. Since the methods operates on an object, they do not modify the state of the symbol. Such methods are called mutable methods.

const i 0 i:= 1

### Integer comparison

The comparison operators works the same. The only difference is that they always return a `Boolean` result. The comparison operators are namely equal `==`, not equal `!=`, less than `<`, less equal `<=`, greater `>` and greater equal `>=`. These operators take two arguments.

== 0 1 != 0 1

Like the arithmetic methods, the comparison operators are supported as object methods. These methods return a `Boolean` object.

i:= 1 i:== 1 i:!= 0

### Integer calculus

Armed with all these functions, it is possible to develop a battery of functions operating with numbers. As another example, we revisit the Fibonacci sequence as demonstrated in the introduction chapter. Such example was terribly slow, because of the double recursion. Another method suggested by Springer and Friedman uses two functions to perform the same job. Fibonacci Integer calculus

const fib-it (gamma (n acc1 acc2) ( if (== n 1) acc2 (fib-it (- n 1) acc2 (+ acc1 acc2))))

const fiboi (gamma (n) ( if (== n 0) 0 (fib-it n 0 1)))

This later example is by far much faster, since it uses only one recursion. Although, it is no the fastest way to write it, it is still an elegant way to write complex functions.

### Other Integer methods

The `Integer` class offers other convenient methods. The `odd-p` and `even-p` are predicates. The `mod` take one argument and returns the modulo between the calling integer and the argument. The `abs` methods returns the absolute value of the calling integer. odd-p even-p abs

i:even-p i:odd-p i:mod 2 i:= -1 i:abs i:to-string

The `Integer` object is a literal object and a number object. As a literal object, the `to-string` and `to-literal` methods are provided to obtain a string representation for the integer object. Although the `to-string` method returns a string representation of the calling integer, the `to-literal` method returns a parsable string. Strictly speaking for an integer, there is no difference between a string representation and a literal representation. However, this is not true for other objects. Literal Number to-string to-literal

(axi) const i 0x123 (axi) println (i:to-string) 291 (axi) println (i:to-literal) 291

As a number object, the integer number can also be represented in hexadecimal format. The `to-hexa` and `to-hexa-strign` methods are designed to obtained such representation. In the first form, the `to-hexa` method return a literal hexadecimal string representation with the appropriate prefix while the second one does not. to-hexa to-hexa-string

(axi) const i 0x123 (axi) println (i:to-hexa) 0x123 (axi) println (i:to-hexa-string) 123

## Relatif number

A relatif or big number is an integer with infinite precision. The `Relatif` class is similar to the `Integer` class except that it works with infinitely long number. The relatif notation uses a `r` or `R` suffix to express a relatif number versus an integer one. The `Relatif` object is a literal object that belongs to the number class. The predicate associated with the `Relatif` object is `relatif-p`. Relatif relatif-p

const a 123R trans b -255R const c 0xffR const d 0b1111_1111R const e (Relatif) const f (Relatif 2000) const g (Relatif "23")

### Relatif operations

Most of the `Integer` class operations are supported by the `Relatif` object. The only difference is that there is no limitation on the number size. This naturally comes with a computational price. An amazing example is to compute the biggest know prime Mersenne number. The world record exponent is 6972593. The number is therefore:

const i 1R const m (- (i:shl 6972593) 1)

This number has 2098960 digits. You can use the `println` method if you wish, but you have been warned...

## Real number

The `real` class implements the representation for floating point number. The internal representation is machine dependent, and generally follows the double representation with 64 bits as specified by the IEEE 754-1985 standard for binary floating point arithmetic. All integer operations are supported for real numbers. The `Real` object is a literal object that belongs to the number class.Real Number

### Real format

The parser supports two types of literal representation for real number. The first representation is the dotted decimal notation. The second notation is the scientific notation.

const a 123.0 # a positive real const b -255.5 # a negative real const c 2.0e3 # year 2000.0

Real number are constructed from the literal notation or by using an explicit real instance. The `Real` class offers standard constructors. The default constructor creates a real number object and initialize it to 0.0. The other constructors takes either an integer, a real number, a character or a string.

### Real arithmetic

The real arithmetic is similar to the integer one. When an integer is added to a real number, that number is automatically converted to a real. Ultimately, a pure integer operation might generate a real result.

+ 1999.0 1 # 2000.0 + 1999.0 1.0 # 2000.0 - 2000.0 1 # 1999.0 - 2000.0 1.0 # 1999.0 * 1000 2.0 # 2000.0 * 1000.0 2.0 # 2000.0 / 2000.0 2 # 1000.0 / 2000.0 2.0 # 1000.0

Like the `Integer` object, the `Real` object has arithmetic built-in methods.

trans r 0.0 # 0.0 r:++ # 1.0 r:-- # 0.0 r:+ 4.0 # 4.0 r:= 4.0 # 4.0 r:- 1.0 # 3.0 r:* 2.0 # 8.0 r:/ 2.0 # 2.0 r:+= 1.0 # 5.0 r:-= 1.0 # 4.0 r:*= 2.0 # 8.0 r:/= 2.0 # 4.0

### Real comparison

The comparison operators works as the integer one. As for the other operators, an implicit conversion between an integer to a real is done automatically.

== 2000 2000 # true != 2000 1999 # true

Comparison methods are also available for the `Real` object. These methods take either an integer or a real as argument.

r:= 1.0 # 1.0 r:== 1.0 # true r:!= 0.0 # true

### A complex example

One of the most interesting point with functional programming language is the ability to create complex function. For example let's assume we wish to compute the value at a point `x` of the Legendre polynomial of order n. One of the solution is to encode the function given its order. Another solution is to compute the function and then compute the value.Legendre polynomial

# legendre polynomial order 0 and 1 const lp-0 (gamma (x) 1) const lp-1 (gamma (x) x)

# legendre polynomial of order n const lp-n (gamma (n) ( if (> n 1) { const lp-n-1 (lp-n (- n 1)) const lp-n-2 (lp-n (- n 2)) gamma (x) (n lp-n-1 lp-n-2) (/ (- (* (* (- (* 2 n) 1) x) (lp-n-1 x)) (* (- n 1) (lp-n-2 x))) n) } (if (== n 1) lp-1 lp-0) ))

# generate order 2 polynomial const lp-2 (lp-n 2)

# print lp-2 (2) println "lp2 (2) = " (lp-2 2)

Note that the computation can be done either with integer or real numbers. With integers, you might get some strange results anyway, but it will work. Note also how the closed variable mechanism is used. The recursion capture each level of the polynomial until it is constructed. Note also that we have here a double recursion.

### Other real methods

The real numbers are delivered with a battery of functions. These include the trigonometric functions, the logarithm and couple others. Hyperbolic functions like `sinh`, `cosh`, `tanh`, `asinh`, `acosh` and `atanh` are also supported. The square root `sqrt` method return the square root of the calling real. The `floor` and `ceiling` returns respectively the floor and the ceiling of the calling real.Real functions floor ceiling abs log exp sin cos tan asin

const r0 0.0 # 0.0 const r1 1.0 # 1.0 const r2 2.0 # 2.0 const rn -2.0 # -2.0 const rq (r2:sqrt) # 1.414213 const pi 3.1415926 # 3.141592

rq:floor # 1.0 rq:ceiling # 2.0 rn:abs # 2.0 r1:log # 0.0 r0:exp # 1.0 r0:sin # 0.0 r0:cos # 1.0 r0:tan # 0.0 r0:asin # 0.0 pi:floor # 3.0 pi:ceiling # 4.0

### Accuracy and formatting

Real numbers are not necessarily accurate, nor precise. The accuracy and precision are highly dependent on the hardware as well as the nature of the operation being performed. In any case, never assume that a real value is an exact one. Most of the time, a real comparison will fail, even if the numbers are very close together. When comparing real numbers, it is preferable to use the `?=` operator. Such operator result is bounded by the internal precision representation and will generally return the desired value. The real precision is an interpreter value which is set with the `set-absolute-precision` method while the `get-absolute-precision` returns the interpreter precision. There is also a `set-relative-precision` and `get-relative-precision` methods used for the definition of relative precision. By default, the absolute precision is set to 0.00001 and the relative precision is set to 1.0E-8. Accuracy set-absolute-precision set-relative-precision

interp:set-absolute-precision 0.0001 const r 2.0 const s (r:sqrt) # 1.4142135 (s:?= 1.4142) # true

Real number formatting is another story. The `format` method takes a precision argument which indicates the number of digits to print for the decimal part. Note that the format command might round the result as indicated in the example below.format

const pi 3.1415926535 pi:format 3 # 3.142

If additional formatting is needed, the `String` `fill-left` and `fill-right` methods can be used.fill-left

const pi 3.1415926535 # 3.1415926535 const val (pi:format 4) # 3.1416 println (val:fill-left '0' 9) # 0003.1416

### Number object

The `Integer`, `Relatif` and `Real` objects are all derived from the `Number` object which is a `Literal` object. As such, the predicate `number-p` is the right mechanism to test an object for a number. The class also provides the basic mechanism to format the number as a string. For integer and relatif, the hexadecimal representation can be obtained by the `to-hexa` and `to-hexa-string` methods. For integer and real numbers, the `format` method adjusts the final representation with the precision argument as indicated before. It is worth to note that a formatted integer gets automatically converted into a real representation. Number

## Character

The `Character` object is another built-in object. A character is internally represented by a quad by using a 31 bit representation as specified by the Unicode standard and ISO 10646. Character

### Character format

The standard quote notation is used to represent a character. In that respect, there is hare a substantial difference with other functional language where the quote protect a form.

const LA01 'a' # the character a const ND10 '0' # the digit 0

All characters from the Unicode codeset are supported by the engine. The characters are constructed from the literal notation or by using an explicit character instance. The `Character` class offers standard constructors. The default constructor creates a null character. The other constructors take either an integer, a character or a string. The string can be either a single quoted character or the literal notation based on the `U+` notation in hexadecimal. For example, `U+40` is the @ character while `U+3A3` is the sigma capital letter Σ.

const nilc (Character) # null character const a (Character 'a') # a const 0 (Character 48) # 0 const mul (Character "*") # * const div (Character "U+40") # @

### Character arithmetic

A character is like an integer, except that it operates in the range 0 to 0x7FFFFFFF. The character arithmetic is simpler compared to the integer one and no overflow or underflow checking is done. Note that the arithmetic operations take an integer as an argument.

+ 'a' 1 # 'b' - '9' 1 # '8'

Several `Character` object methods are also provided for arithmetic operations in a way similar to the `Integer` class.

trans c 'a' # 'a' c:++ # 'b' trans c '9' # '9' c:-- # '8' c:+ 1 # '9' c:- 9 # '0'

### Character comparison

Comparison operators are also working with the `Character` object. The standard operators are namely equal `==`, not equal `!=`, less than `<`, less equal `<=`, greater `>` and greater equal `>=`. These operators take two arguments.

== 'a' 'b' # false != '0' '1' # true

### Other character methods

The `Character` object comes with additional methods. These are mostly conversion methods and predicates. The `to-string` method returns a string representation of the calling character. The `to-integer` method returns an integer representation the calling character. The predicates are `alpha-p`, `digit-p`, `blank-p`, `eol-p`, `eos-p` and `nil-p`. alpha-p digit-p blank-p eol-p eos-p nil-p

const LA01 'a' # 'a' const ND10 '0' # '0' LA01:to-string # "a" LA01:to-integer # 97 LA01:alpha-p # true ND10:digit-p # true

## String

The `String` object is one of the most important built-in object in the engine. Internally, a string is a vector of Unicode characters. Because a string operates with Unicode characters, care should be taken when using composing characters. String

### String format

The standard double quote notation is used to represent literally a string. Standard escape sequences are also accepted to construct a string.

const hello "hello"

Any literal object can be used to construct a string. This means that integer, real, boolean or character objects are all valid to construct strings. The default constructor creates a null string. The string constructor can also takes a string.

const nils (String) # "" const one (String 1) # "1" const a (String 'a') # "a" const b (String true) # "true"

### String operations

The `String` object provides numerous methods and operators. The most common ones are illustrated in the example below. The `length` methods returns the total number of characters in the string object. It is worth to note that this number is not necessarily the number of printed characters since some characters might be combining characters used, for example, as diacritics. The `non-combining-length` method might be more adapted to get the number of printable characters. length Combining character

const h "hello" h:length # 5 h:get 0 # 'h' h:== "world" # false h:!= "world" # true h:+= " world" # "hello world"

The `sub-left` and `sub-right` methods return a sub-string, given the position index. For `sub-left`, the index is the terminating index, while `sub-right` is the starting index, counting from 0. sub-left sub-right

# example of sub-left method const msg "hello world" msg:sub-left 5 # "hello" msg:sub-right 6 # "world"

The `strip`, `strip-left` and `strip-right` are methods used to strip blanks and tabs. The `strip` method combines both `strip-left` and `strip-right`. strip strip-left strip-right

# example of strip method const str " hello world " println (str:strip) # "hello world"

The `split` method returns a vector of strings by splitting the string according to a break sequence. By default, the break sequence is the blank, tab and newline characters. The break sequence can be one or more characters passed as one single argument to the method. split

# example of split method const str "hello:world" const vec (str:split ":" # "hello" "world") println (vec:length) # 2

The `fill-left` and `fill-right` methods can be used to fill a string with a character up to a certain length. If the string is longer than the length, nothing happens. fill-left fill-right

# example of fill-left method const pi 3.1415926535 # 3.1415926535 const val (pi:format 4) # 3.1416 val:fill-left '0' 9 # 0003.1416

### Conversion methods

The case conversion methods are the standard `to-upper` and `to-lower` methods. The method operates with the internal Unicode database. As a result, the conversion might change the string length. Other conversion methods related to the Unicode representation are also available. These are rather technical, but can be used to put the string in a normal form which might be suitable for comparison. Such conversion always uses the Unicode database normal form representation. to-upper to-lower

# example of case conversion const str "hello world" println (str:to-upper) # HELLO WORLD

### String hash value

The `hashid` method is a method that computes the hash value of a string. The value depends on the target machine and will change between a 32 bits and a 64 bits machine. Example example 0203.als illustrates the computation of a hash value for our favorite test string. Hash code (String)

# test our favorite string const hello "hello world" hello:hashid # 1054055120

The algorithm used by the engine is shown as an example below. As a side note, it is recommended to print the shift amount in the program. One may notice, that the value remains bounded by 24. Since we are xoring the final value, it does illustrate that the algorithm is design for a 32 bits machine. With a 64 bits machine the algorithm is slightly modified to use the extra space. This also means that the hashid value is not portable across platforms.

# compute string hashid const hashid (s) { const len (s:length) trans cnt 0 trans val 0 trans sht 17 do { # compute the hash value trans i (Integer (s:get cnt)) val:= (val:xor (i:shl sht)) # adjust shift index if (< (sht:-= 7) 0) (sht:+= 24) } (< (cnt:++) len) eval val }

## Regular expression

A regular expression or regex is a special literal object designed to describe a character string in a compact form with regular patterns. A regular expression provides a convenient way to perform pattern matching and filed extraction within a character string.

### Regex syntax

A regular expression is defined with a special `Regex` object. A regular expression can be built implicitly or explicitly with the use of the `Regex` object. The regex syntax uses the `[` and `]` characters as block delimiters. When used in a source file, the parser automatically recognizes a regex and built the object accordingly. The following example shows two equivalent methods for the same regex expression.

# syntax built-in regex (== [$d+] 2000) # true # explicit built-in regex (== (Regex "$d+") 2000) # true

In its first form, the `[` and `]` characters are used as syntax delimiters. The lexical analyzer automatically recognizes this token as a regex and built the equivalent `Regex` object. The second form is the explicit construction of the `Regex` object. Note also that the `[` and `]` characters are also used as regex block delimiters.

### Regex characters and meta-characters

Any character, except the one used as operators can be used in a regex. The `$` character is used as a meta-character -- or control character -- to represent a particular set of characters. For example, `[hello world]` is a regex which match only the `"hello world"` string. The `[$d+]` regex matches one or more digits. The following meta characters are built-in in the regex engine.

### Regular expression meta-characters

Character | Description
--- | ---
$a | matches any letter or digit
$b | matches any blank characters
$c | matches any combining alphanumeric
$d | matches any digit
$e | matches eol, cr and eos
$l | matches any lower case letter
$n | matches eol or cr
$s | matches any letter
$u | matches any upper case letter
$v | matches any valid afnix constituent
$w | matches any word constituent
$x | matches any hexadecimal characters

The uppercase version is the complement of the corresponding lowercase character set.

A character which follows a `$` character and that is not a meta character is treated as a normal character. For example `$[` is the `[` character. A quoted string can be used to define character matching which could otherwise be interpreted as control characters or operator. A quoted string also interprets standard escaped sequences but not meta characters.

(== [$d+] 2000) # true (== ["$d+"] 2000) # false

Combining alphanumerical characters can generate surprising result when used with Unicode string. Combining alphanumeric characters are alphanumeric characters and non spacing combining mark as defined by the Unicode consortium. In practice, the combining marks are the diacritics used with regular letter, such like the accents found in the western languages. Because the writing system uses a canonical decomposition for representing the Unicode string, it turns out that the printed string is generally represented with more bytes, making the string length longer than it appears.

### Regex character set

A character set is defined with the `<` and `>` characters. Any enclosed character defines a character set. Note that meta characters are also interpreted inside a character set. For example, `<$d+->` represents any digit or a plus or minus. If the first character is the `^` character in the character set, the character set is complemented with regards to its definition.

### Regex blocks and operators

The `[` and `]` characters are the regex sub-expressions delimiters. When used at the top level of a regex definition, they can identify an implicit object. Their use at the top level for explicit construction is optional. The following example is strictly equivalent.

# simple real number check const real-1 (Regex "$d*.$d+") # another way with [] characters const real-2 (Regex "[$d*.$d+]")

Sub-expressions can be nested -- that's their role -- and combined with operators. There is no limit in the nesting level.

# pair of digit testing (== [$d$d[$d$d]+] 2000) # true (== [$d$d[$d$d]+] 20000) # false

The following unary operators can be used with single character, control characters and sub-expressions.

### Regular expression operators

Operator | Description
--- | ---
* | match 0 or more times
+ | match 1 or more times
? | match 0 or 1 time
| | alternation

Alternation is an operator which work with a secondary expression. Care should be taken when writing the right sub-expression. For example the following regex `[$d|hello]` is equivalent to `[[$d|h]ello]`. In other word, the minimal first sub-expression is used when compiling the regex.

### Grouping

Groups of sub-expressions are created with the `(` and `)` characters. When a group is matched, the resulting sub-string is placed on a stack and can be used later. In this respect, the regex engine can be used to extract sub-strings. The following example extracts the month, day and year from a particular date format: `[($d$d):($d$d):($d$d$d$d)]`. This regex assumes a date in the form mm:dd:yyyy.

if (== (const re [($d$d):($d$d)]) "12:31") { trans hr (re:get 0) trans mn (re:get 1) }

Grouping is the mechanism to retrieve sub-strings when a match is successful. If the regex is bound to a symbol, the `get` method can be used to get the sub-string by index.

### Regex object

Although a regex can be built implicitly, the `Regex` object can also be used to build a new regex. The argument is a string which is compiled during the object construction. A `Regex` object is a literal object. This means that the `to-string` method is available and that a call to the `println` special form will work directly.

const re (Regex "$d+") println re # $d+ println re:to-string # [$d+]

### Regex operators

The `==` and `!=` operators are the primary operators to perform a regex match. The `==` operator returns `true` if the regex matches the string argument from the beginning to the end of string. Such operator implies the begin and end of string anchoring. The `<` operator returns true if the regex matches the string or a sub-string or the string argument.

### Regex methods

The primary regex method is the `get` method which returns by index the sub-string when a group has been matched. The `length` method returns the number of group match.

if (== (const re [($d$d):($d$d)]) "12:31") { re:length # 2 re:get 0 # 12 re:get 1 # 31 }

The `match` method returns the first string which is matched by the regex.

const regex [$d+] regex:match "Happy new year 2000" # 2000

The `replace` method any occurrence of the matching string with the string argument.

const regex [$d+] regex:replace "Hello year 2000" "3000" # hello year 3000

### Argument conversion

The use of the `Regex` operators implies that the arguments are evaluated as literal object. For this reason, an implicit string conversion is made during such operator call. For example, passing the integer `12` or the string `"12"` is strictly equivalent. Care should be taken when using this implicit conversion with real numbers.