man(1) CTR man page man(1)

NAME

ctr - run a Citrine program

SYNOPSIS

ctr [OPTION]... [PROGRAM]

DESCRIPTION

Citrine is general purpose programming language for UNIX-like operating systems.
 
 
-t translate a program instead of running it (followed by dictionary file to use).
 
 
-g generate a new dictionary file from a pair of dictionary.h Citrine source headers.
 
 

REFERENCE MANUAL

Citrine has 5 literals:
 
- Nil
 
- Booleans (True, False)
 
- Numbers (1, -2, 3.5)
 
- Strings 'All Strings are UTF8!'
 
- Code Blocks { parameters code }
 
 
The following messages are part of the Core API of the Citrine Programming Language:
 
 
Nil

Nil represents 'nothing' or NULL in other languages.
Any object property that has not been assigned a value
will contain Nil. Unlike some other programming languages
Citrine has no concept of 'undefined' or isset, Nil is actually the
same as 'undefined' or not set.

Literal:

Nil
 
[Nil] Nil?

Nil always answers this message with a boolean object 'True'.
 
[Nil] string

Returns the string representation of Nil: 'Nil'.
 
[Nil] number

Returns the numerical representation of Nil: 0.
 
[Nil] boolean

Returns the boolean representation of Nil: False.
 
Object

This is the base object, the parent of all other objects.
It contains essential object oriented programming features.
 
[Object] type

Returns a string representation of the type of object.
 
[Object] string

Returns a string representation of a generic object.
This string representation will be:

[Object]
 
[Object] number

Returns a numerical representation of the object. This basic behavior, part
of any object will just return 1. Other objects typically override this
behavior with more useful implementations.
 
[Object] boolean

Returns a boolean representation of the object. This basic behavior, part
of any object will just return True. Other objects typically override this
behavior with more useful implementations.
 
[Object] equals: [other]

Tests whether the current instance is the same as
the argument. You also use the message '=' for this
however, often that message will be overridden by a
derived object (Number will use = to compare the numeric values
for instance).

Usage:

object equals: other
 
[Object] myself

Returns the object itself.
 
[Object] do

Activates 'chain mode'. If chain mode is active, all messages will
return the recipient object regardless of their return signature.
The 'do' message tells the object to always return itself and disgard
the original return value until the message 'done' has been received.

Usage:

a := List ← 'hello' ; 'world' ; True ; Nil ; 666.
a do pop shift prepend: 'hi', append: 999, done.
 
[Object] done

Deactivates 'chain mode'.
 
[Object] copy

Contrary to other languages, all objects, even booleans, numbers and
strings are assigned and passed by reference. To create a shallow copy
of a number, string or boolean send the message 'copy'.

Usage:

a := 5.
b := a copy.
b add: 1.

 
[Object] case: [Object] do: [Block].

This message makes the recipient compare itself to the specified object.
If the recipient considers itself to be equal, it will carry out the
instructions in the associated block of code. The recipient will send
the message '=' to itself with the other object as an argument. This leaves
it up to the recipient to determine whether the objects are considered
equal. If the recipient decides the objects are not equal, the associated
code block will be ignored. Note that this allows you to implement a
so-called switch-statement like those found in other languages. Because
of the generic implementation, you can use the case statements on almost
any object. Case-do statements may provide a readable alternative to a
long list of if-else messages.

The example program below will print the text 'It's a Merlot!'.

Usage:

wine
case: 'cabernet' do: { ✎ write: 'it\'s a Cabernet!'. },
case: 'syrah' do: { ✎ write: 'it\'s a Syrah!'. },
case: 'merlot' do: { ✎ write: 'it\'s a Merlot!'. },
case: 'malbec' do: { ✎ write: 'it\'s a Malbec!'. }.
 
[Object] message: [String] arguments: [List]

Sends a custom or 'dynamic' message to an object. This takes a string containing
the message to be send to the object and an array listing the arguments at the
correct indexes. If the array fails to provide the correct indexes this will
generate an out-of-bounds error coming from the Array object. If something other
than an List is provided an error will be thrown as well.

Usage:

☞ str := 'write:'.
✎ message: 'write:' arguments: (List ← 'Hello World').

This will print the string 'Hello world' on the screen using a dynamically
crafted message.
 
[Object] on: [String] do: [Block]

Makes the object respond to a new kind of message.
Use the semicolons to indicate the positions of the arguments to be
passed.

Usage:

object on: 'greet' do: { ... }.
object on: 'between:and:' do: { ... }.

 
[Object] respond: [String]

Variations:

[Object] respond: [String] with: [String]
[Object] respond: [String] with: [String] and: [String]

Default respond-to implemention, does nothing.
You can override this behaviour to implement generic behaviour.
Listening to these messages allows users to send any message to an
object. For instance an object can respond to any message it does not
understand by echoing the message.
 
[Object] Nil?

Default Nil? implementation.

Always returns boolean object False.
 
[Object] learn: [String] means: [String].

Teaches any object to repsond to the first specified message just like
it would upon receiving the second. This allows you to map existing
responses to new messages. You can use this to translate messages into your native
language. After mapping, sending the alias message will be just as fast
as sending the original message. You can use this to create programs
in your native language without sacrficing performance. Of course the mapping itself
has a cost, but the mapped calls will be 'toll-free'.

Usage:

Boolean learn: 'yes:' means: 'true:'.

 
Boolean

Literal:

True
False
 
[Boolean] = [other]

Tests whether the other object (as a boolean) has the
same value (boolean state True or False) as the current one.

Usage:

(True = False) false: { ✎ write: 'This is not True!'. }.
 
[Boolean] != [other]

Tests whether the other object (as a boolean) has the
same value (boolean state True or False) as the current one.

Usage:

(True != False) true: { ✎ write: 'This is not True!'. }.
 
[Boolean] string

Returns a string representation of a boolean value, i.e. 'True' or 'False'.
 
[Boolean] break

Breaks out of the current block and bubbles up to the parent block if
the value of the receiver equals boolean True.

Usage:

{ :iteration
(iteration > 10) break.
} * 20.
 
[Boolean] continue

Skips the remainder of the current block in a loop, continues to the next
iteration.

Usage:

(iteration > 10) continue.
 
[Boolean] true: [block]

Executes a block of code if the value of the boolean
object is True.

Usage:

(some expression) true: { ... }.
 
[Boolean] false: [block]

Executes a block of code if the value of the boolean
object is True.

Usage:

(some expression) false: { ... }.
 
 
 
[Boolean] not

Returns the opposite of the current value.

Usage:
True := False not.

 
[Boolean] either: [this] or: [that]

Returns argument #1 if boolean value is True and argument #2 otherwise.
 
[Boolean] and: [other]

Returns True if both the object value is True and the
argument is True as well.

Usage:

a and: b

 
[Boolean] nor: [other]

Returns True if the object value is False and the
argument is False as well.

Usage:

a nor: b

 
[Boolean] or: [other]

Returns True if either the object value is True or the
argument is True or both are True.

Usage:

a or: b
 
[Boolean] ? [other]

Returns True if either the object value is True or the
argument is True but not both.

Usage:

a ? b
 
[Boolean] number

Returns 0 if boolean is False and 1 otherwise.
 
Number

Literal:

0
1
-8
2.5

Represents a number object in Citrine.
 
 
 
[Number] > [other]

Returns True if the number is higher than other number.
 
[Number] ≥ [other]

Returns True if the number is higher than or equal to other number.
 
[Number] < [other]

Returns True if the number is less than other number.
 
[Number] ≤ [other]

Returns True if the number is less than or equal to other number.
 
[Number] = [other]

Returns True if the number equals the other number.
 
[Number] ≠ [other]

Returns True if the number does not equal the other number.
 
[Number] between: [Number] and: [Number]

Returns a random number between the specified boundaries,
including the upper and lower boundary of the number. So,
asking for a number between 0 and 10 may result in numbers like
0 and 10 as well. Only rounded numbers are returned and the
boundaries will be rounded as well. So a random number between
0.5 and 1 will always result in 1. Negative numbers are allowed
as well.

Usage:

☞ x := Number between 0 and: 10.
 
[Number] odd?

Returns True if the number is odd and False otherwise.
 
[Number] even?

Returns True if the number is even and False otherwise.
 
[Number] + [Number]

Adds the other number to the current one. Returns a new
number object.
 
[Number] add: [Number]

Increases the number ITSELF by the specified amount, this message will change the
value of the number object itself instead of returning a new number.
 
[Number] - [Number]

Subtracts the other number from the current one. Returns a new
number object.
 
[Number] subtract: [number]

Decreases the number ITSELF by the specified amount, this message will change the
value of the number object itself instead of returning a new number.
 
[Number] * [Number or Block]

Multiplies the number by the specified multiplier. Returns a new
number object.
 
[Block] * [Number]

Runs the block of code a 'Number' of times.
This is the most basic form of a loop.
The example runs the block 7 times. The current iteration
number is passed to the block as a parameter (i in this example).

Usage:

{ :i ✎ write: i. } * 7.

 
[Number] multiply by: [Number]

Multiplies the number ITSELF by multiplier, this message will change the
value of the number object itself instead of returning a new number.
Use this message to apply the operation to the object itself instead
of creating and returning a new object.

Usage:

x := 5.
x multiply by: 2.
 
[Number] / [Number]

Divides the number by the specified divider. Returns a new
number object.
 
[Number] devide by: [Number]

Divides the number ITSELF by divider, this message will change the
value of the number object itself instead of returning a new number.
Use this message to apply the operation to the object itself instead
of generating a new object.

Usage:

x := 10.
x divide by: 2.

 
[Number] modulo: [modulo]

Returns the modulo of the number. This message will return a new
object representing the modulo of the recipient.

Usage:

x := 11 modulo: 3.

Use this message to apply the operation of division to the
object itself instead of generating a new one.
 
[Number] power: [power]

Returns a new object representing the
number to the specified power.
The example above will raise 2 to the power of 8 resulting in
a new Number object: 256.

Usage:

x := 2 power: 8.
 
[Number] positive?

Returns a boolean indicating wether the number is positive.
This message will return a boolean object 'True' if the recipient is
positive and 'False' otherwise.
The example above will print the message because hope is higher than 0.

Usage:

hope := 0.1.
( hope positive? ) true: {
✎ write: 'Still a little hope for humanity'.
}.
 
[Number] negative?

Returns a boolean indicating wether the number is negative.
This message will return a boolean object 'True' if the recipient is
negative and 'False' otherwise. It's the eaxct opposite of the 'positive'
message.
The example above will print the message because the value of the variable
hope is less than 0.

Usage:

hope := -1.
(hope negative?) ifTrue: { Pen write: 'No hope left'. }.

 
[Number] floor

Gives the largest integer less than the recipient.
The example above applies the floor function to the recipient (4.5)
returning a new number object (4).

Usage:

x := 4.5
y := x floor.
 
[Number] qualify: 'meters'.

Qualifies a number. Alias for: [Number] [String].
See the [Number] [String] message signature for more details.
 
[Number] [String]

Qualifies a number. By sending an arbitrary (undocumented) unary message to
a Number object your message will be set as the qualification property of the number
and passed around along with the number value itself.

Usage:

Number learn: 'plus:' means: '+'.
Number on: '+' do: { :x
☞ rate := 1.
☞ currency := x qualification.
(currency = 'euros') true: {
rate := 2.
}.
↲ (⛏ plus: (x * rate)).
}.
☞ money := 3 dollars + 2 euros.
 
[Number] qualification.

Returns the qualification of a number object. For instance, as a
number (let's say 99) has been qualified as the number of bottles using
a message like: '99 bottles' this message will return the descriptive string
'bottles'. For usage examples, please consult the [Number] [String] message
signature.
 
 
[Number] ceil

Rounds up the recipient number and returns the next higher integer number
as a result.
The example above applies the ceiling function to the recipient (4.5)
returning a new number object (5).

Usage:

x := 4.5.
y = x ceil.
 
[Number] round

Returns the rounded number.
 
[Number] absolute

Returns the absolute (unsigned, positive) value of the number.
The example above strips the sign off the value -7 resulting
in 7.

Usage:

x := -7.
y := x absolute.
 
[Number] square root

Returns the square root of the recipient.
The example above takes the square root of 49, resulting in the
number 7.

Usage:

☞ x := 49.
☞ y := x square root.
 
[Number] byte

Converts a number to a single byte.
 
[Number] string

Wrapper for cast function.
 
[Number] boolean

Casts a number to a boolean object.
 
String

Literal:

'Hello World, this is a String.'

A sequence of bytes or characters. In Citrine, strings are UTF-8 aware.
You may only use single quotes. To escape a character use the
backslash '\' character. Use the special characters ↵ and ⇿ to
insert a newline or tab respectively.

Strings in Citrine represent a series of bytes. Strings can be
interpreted as real bytes or as text depending on the messages
send. For instance, the message 'bytes' returns the number of bytes
in a string, while the message 'length' returns the number of
characters (as defined as separate UTF-8 code points) in a string.
 
 
 
[String] bytes

Returns the number of bytes in a string, as opposed to
length which returns the number of UTF-8 code points (symbols or characters).
 
[String] = [other]

Returns True if the other string is the same (in bytes).
 
[String] ≠ [other]

Returns True if the other string is not the same (in bytes).
 
[String] length

Returns the length of the string in symbols.
This message is UTF-8 unicode aware. A 4 byte character will be counted as ONE.
 
[String] + [other]

Appends other string to self and returns the resulting
string as a new object.
 
[String] append: [String].

Appends the specified string to itself. This is different from the '+'
message, the '+' message adds the specified string while creating a new string.
Appends on the other hand modifies the original string.

Usage:

x := 'Hello '.
x append: 'World'.
✎ write: x.

 
[String] from: [start] length: [length]

Returns a portion of a string defined by from
and length values.
This message is UTF-8 unicode aware.

Usage:

'hello' from: 2 length: 3.
 
[String] offset: [Number]

Returns a string without the first X characters.
 
[String] character: [Number]

Returns the character at the specified position (UTF8 aware).

Usage:

('hello' character: 2).

 
[String] byte: [Number]

Returns the byte at the specified position (in bytes).

Usage:
('abc' byte: 1).
 
[String] find: [subject]

Returns the index (character number, not the byte!) of the
needle in the haystack.

Usage:

'find the needle' find: 'needle'.

 
[String] uppercase

Returns a new uppercased version of the string.
Note that this is just basic ASCII case functionality, this should only
be used for internal keys and as a basic utility function. This function
DOES NOT WORK WITH UTF8 characters !
 
[String] lowercase

Returns a new lowercased version of the string.
Note that this is just basic ASCII case functionality, this should only
be used for internal keys and as a basic utility function. This function
DOES NOT WORK WITH UTF8 characters !
 
[String] last: [subject]

Returns the index (character number, not the byte!) of the
needle in the haystack.

Usage:

'find the needle' last: 'needle'.
 
[String] [key]: [value]

Replaces the character sequence 'key' with the contents of value.
The example will produce the string '$ 10'.

Usage:

'$ money' money: 10.
 
[String] replace: [string] with: [other]

Replaces needle with replacement in original string and returns
the result as a new string object.

Usage:

'LiLo BootLoader' replace: 'L' with: 'l'.
 
[String] pattern: [String] process: [Block] options: [String].

Matches the POSIX regular expression in the first argument against
the string and executes the specified block on every match passing
an array containing the matches.

The options parameter can be used to pass specific flags to the
regular expression engine. As of the moment of writing this functionality
has not been implemented yet. The only flag you can set at this moment is
the 'ignore' flag, just a test flag. This flag does not execute the block.

Usage:

'hello world' pattern: '([hl])' process: { :arr
✎ write: (arr join: '|'), end.
} options: ''.

On every match the block gets executed and the matches are
passed to the block as arguments. You can also use this feature to replace
parts of the string, simply return the replacement string in your block.
 
[String] pattern: [String] process: [Block].

Same as pattern:process:options: but without the options, no flags will
be send to the regex engine.
 
[String] contains: [String]

Returns True if the other string is a substring.
 
[String] matches: [String].

Tests the pattern against the string and returns True if there is a match
and False otherwise.
In the example: match will be True because there is a space in 'Hello World'.

Usage:

☞ match := 'Hello World' matches: '[:space:]'.

 
[String] remove surrounding spaces

Trims a string. Removes surrounding white space characters
from string and returns the result as a new string object.
The example above will strip all white space characters from the
recipient on both sides of the text.

Usage:

' hello ' remove surrounding spaces.

 
[String] number

Converts string to a number.
 
[String] boolean

Converts string to boolean
 
[String] split: [String]

Converts a string to an array by splitting the string using
the specified delimiter (also a string).
 
[String] characters.

Splits the string in UTF-8 characters and returns
those as an array.

Usage:

a := 'abc' characters.
a count.
 
[String] list

Returns an array of bytes representing the string.
 
[String] append byte: [Number].

Appends a raw byte to a string.
 
[String] compare: [String]

Compares a string using the UTF-8 compatible strcmp function.

Usage:

word compare: other.
 
[String] < [String]

Returns True if the first String comes before the latter
alphabetically. The actual comparison is based on the UTF-8 compatible
function strcmp.
 
[String] ≤ [String]

Returns True if the first String comes before or at the same
position as the latter alphabetically. The actual comparison is based on the UTF-8 compatible
function strcmp.
 
[String] > [String]

Returns True if the first String comes after the latter
alphabetically. The actual comparison is based on the UTF-8 compatible
function strcmp.
 
[String] ≥ [String]

Returns True if the first String comes after or at the same position as the latter
alphabetically. The actual comparison is based on the UTF-8 compatible
function strcmp.
 
 
[String] hash: [String]

Returns the hash of the recipient String using the specified key.
The default hash in Citrine is the SipHash which is also used internally.
SipHash can protect against hash flooding attacks.
 
Block

Literal:

{ parameters (if any) here... code here... }

each parameter has to be prefixed with
a colon (:).

Usage:

{ ✎ write: 'a simple code block'. } run.
{ :param ✎ write: param. } apply: 'write this!'.
{ :a :b ↲ a + b. } apply: 1 and: 2.
{ :a :b :c ↲ a + b + c. } apply: 1 and: 2 and: 3.

 
[Block] apply: [object]

Runs a block of code using the specified object as a parameter.
If you run a block using the messages 'run' or 'apply:', me/my will
refer to the block itself instead of the containing object.
 
[Block] while: [block]

Runs a block of code, depending on the outcome runs the other block
as long as the result of the first one equals boolean True.
Example: Here we increment variable x by one until it reaches 6.
While the number x is lower than 6 we keep incrementing it.
Don't forget to use the return ↲ symbol in the first block.

Usage:

☞ x := 0.
{ x add: 1. } while: { ↲ (x < 6). }.
 
[Block] run

Sending the unary message 'run' to a block will cause it to execute.
The run message takes no arguments, if you want to use the block as a function
and send arguments, consider using the applyTo-family of messages instead.
This message just simply runs the block of code without any arguments.
In the example we will run the code inside the block and display
the greeting.

Usage:

{ ✎ write: 'Hello World'. } run.

 
[Block] set: [name] value: [object]

Sets a variable in a block of code. This how you can get closure-like
functionality.
In the example we assign a block to a variable named 'shout'.
We assign the string 'hello' to the variable 'message' inside the block.
When we invoke the block 'shout' by sending the run message without any
arguments it will display the string: 'hello!!!'.
Similarly, you could use this technique to create a block that returns a
block that applies a formula (for instance simple multiplication) and then set the
multiplier to use in the formula. This way, you could create a block
building 'formula blocks'. This is how you implement use closures
in Citrine.

Usage:

shout := { ✎ write: (my message + '!!!'). }.
shout set: 'message' value: 'hello'.
shout run.

 
[Block] error: [object].

Sets error flag on a block of code.
This will throw an error / exception.
You can attach an object to the error, for instance
an error message.

Usage:

{
thisBlock error: 'oops!'.
} catch: { :errorMessage
✎ write: errorMessage.
}, run.
 
[Block] catch: [otherBlock]

Associates an error clause to a block.
If an error (exception) occurs within the block this block will be
executed.

Usage:

{
☞ z := 4 / 0.
} catch: { :e
✎ write: e, end.
}, run.
 
[Block] string

Returns a string representation of the Block. This basic behavior, part
of any object will just return [Block]. Other objects typically override this
behavior with more useful implementations.
 
[List] new

Creates a new list or array. List is an alias for array.
An array is a collection of items. To create a new array,
send the 'new' message to the array. To add an element send
the 'push:' message to an array with the element to add as
an argument. Instead of using the push-message you can also
use the • message. This message is suitable for vertically
written arrays because they look similar to lists seen in
regular documents. Besides 'push:' and • you can also use
the ; message to push an new element on top of the array.
The arrow message is the same as 'new' plus 'push:', just a
shorter notation. The ; message is very suitable for
horizontally written arrays. Finally, the last example
depicts a notation using just ascii characters.

Usage:

☞ meals :=
List new
• 'hamburger'
• 'pizza'
• 'haggis'.

☞ todo := List ← 'dishes' ; 'cleaning'.

 
[List] new

Creates a new array.
An array is a collection of items. To create a new array,
send the 'new' message to the array. To add an element send
the 'push:' message to an array with the element to add as
an argument. Instead of using the push-message you can also
use the • message. This message is suitable for vertically
written arrays because they look similar to lists seen in
regular documents. Besides 'push:' and • you can also use
the ; message to push an new element on top of the array.
The arrow message is the same as 'new' plus 'push:', just a
shorter notation. The ; message is very suitable for
horizontally written arrays. Finally, the last example
depicts a notation using just ascii characters.

Usage:

☞ meals :=
List new
• 'hamburger'
• 'pizza'
• 'haggis'.

☞ todo := List ← 'dishes' ; 'cleaning'.

 
[List] type

Returns the string description for this object type.

 
[List] append: [Element]

Adds an element to the end of the list.
You can also use add: to do this or one of the symbolic
representations: • and ;. Depending on the context, one might be
more readable than the other.

Usage:

numbers := List new.
numbers append: 3.
numbers add: 3.
numbers ; 3.
numbers • 3.

 
[List] minimum

Returns the minimum value in a list.
In the example this message will return the number 2.

Usage:

a := List ← 8 ; 4 ; 2 ; 16.
m := a minimum.

 
[List] maximum

Returns the maximum value in a list.
In the example this will yield the number 16.

Usage:

a := List ← 8 ; 4 ; 2 ; 16.
m := a maximum.

 
[List] map: [Block].

Iterates over the array. Passing each element as a key-value pair to the
specified block.
The map message will pass the following arguments to the block, the key,
the value and a reference to the array itself. The last argument might seem
redundant but allows for a more functional programming style. Instead of map,
you can also use each:.

Usage:

files map: showName.
files map: {
:key :filename :files
✎ write: filename.
}.

files each: {
:key :filename :files
✎ write: filename.
}.
 
[List] ← [Element1] ; [Element2] ; ...

Creates a new instance of a list and initializes this
array with a first element, useful for literal-like List
notations. In the example we create a new list consisting
of the numbers 1, 2 and 3.

Usage:

a := List ← 1 ; 2 ; 3.

 
[List] prepend: [Element].

Adds the specified element to the beginning of the array.
At the end of the example code, the list will consist of the
numbers: 3 and 1 (in that order).

Usage:

a := List new.
a append: 1.
a prepend: 3.
 
[List] join: [String].

Joins the elements of a list together in a string
separated by a specified glue string. The example
code results in the string: '1,2,3'.

Usage:

collection := List new.
collection append: 1, append: 2, append 3.
collection join: ','.
 
[List] position: [Number]

Returns the element in the list at the specified position.
Note that the first position of the list is index 0.
If you attempt to retrieve an element of the list
using a an index that is something other than a number
a catchable error will be triggered. An error will
also be triggered if your position is out of bounds
(i.e. outside the list). Instead of the message
'position:' you can also send the message '?'.

Usage:

☞ fruits := List ← 'apples' ; 'oranges' ; 'bananas'.
☞ oranges := fruits position: 1.
☞ oranges := fruits ? 1.
 
[List] first.

Returns the first element of the list.
If the list is empty, Nil will be returned.
 
[List] last.

Returns the last element of the list.
If the list is empty, Nil will be returned.
 
[List] second last.

Returns the second last element of the list.
If the list is empty, Nil will be returned.
 
[List] put: [Object] at: [Number]

Puts an object (which can be anything) in the list
at the specified position.
The list will be automatically expanded if the position number
is higher than the maximum of the list.

Usage:

☞ fruits := List new.
☞ fruits put: 'apples' at: 5.
 
[List] pop

Pops off the last element of the array.
 
[List] - [Number]

Deletes the element specified by the index number and
shrinks the list accordingly. If the position number does not exist,
the list will remain the same. This operation changes the list itself.
The example will remove element 1 (2) from the list.

Usage:

☞ x := List ← 1 ; 2 ; 3.
☞ x - 1.
 
[List] shift

Shifts off the first element of the list.
 
[List] count

Returns the number of elements in the list.
 
[List] from: [Begin] length: [End]

Copies part of an array indicated by from and to and
returns a new array consisting of a copy of this region.
 
[List] replace: [Number] length: [Number] with: [List].

Returns a copy of the list with the specified elements replaced.
The first argument indicates the start index to begin the replacement.
Here, 0 means the beginning of the list.
The second argument (length)
must indicate the number of elements to delete in the copy, counting
from the starting point. Finally, one has to provide the replacement
list as the third argument.
If the replacement list is empty, the specified elements will only be
removed from the copy.
If the replacement is not an array an error will be thrown.

Usage:

☞ buy := cakes
replace: 1
length: 2
with: ( List ← 'cinnamon' ; 'pineapple' ).

 
[List] + [List]

Returns a new list, containing elements of itself and the other
list.
 
[List] by: [List].

Combines the first list with the second one, thus creating
a map. The keys of the newly generated map will be provided by the
first list while the values are extracted from the second one.
In the example we derive a temperature map from a pair of lists
(cities and temperatures).

Usage:

☞ city := List ← 'London' ; 'Paris' ; 'Berlin'.
☞ temperature := List ← '15' ; '16' ; '15'.
☞ weather := temperature by: city.
 
[List] copy

Copies the list. The list object will answer this message by
returning a shallow copy of itself. This means that the values in the
newly returned list can be replaced or deleted without affecting
the original one. However, modifying the values in the list will
still cause their counterparts in the original list to be modified
as well.
In the example we replace the first item (1) in b with 999.
The first element in a will still be 1 though because we have created
copy b by sending the message 'copy' to a and assiging the result
to b.

Usage:

☞ a := List ← 1 ; 2 ; 3.
☞ b := a copy.
b put: 999 at: 1.
 
 
[List] sort: [Block]

Sorts the contents of an list using a sort block.
Uses qsort.
 
[List] string

Returns a string representation of the list and its contents.
This representation will be encoded in the Citrine language itself and can
therefore be evaluated again.
In the example: 'string' messages are implicitly
send by some objects, for instance when
attempting to write a List using a Pen.

Usage:

☞ a := List ← 'hello' ; 'world'.
☞ b := a string.
☞ c := b evaluate.
 
[List] fill: [Number] with: [Object]

Fills the list with the specified number of objects.

Usage:

☞ a := List new fill: 42 with: 'x'.
 
[List] find: [Object].

Checks whether the specified object occurs in the list
and returns the index number if so.
If not, the index number -1 will be returned. Note that the comparison
will be performed by converting both values to strings.

 
Map

Creates a Map object.

Usage:

☞ files := Map new.
☞ files put: 'readme.txt' at: 'textfile'.
 
[Map] type

Returns the string 'Map'.

 
[Map] put: [Element] at: [Key]

Puts a key-value pair in a map.

Usage:

map put: 'hello' at: 'world'.

 
[Map] [Key]: [Value]

You can fill the map object with key-value pairs by sending any
binary or keyword message that is not part if its standard behaviour.
Likewise you can retrieve any value from the map by sending the corresponding key
as a unary message. This allows for a very natural looking notation to create
and modify map objects.

Usage:

☞ menu := Map new
Margherita: 11.90,
Hawaii: 12.99,
QuattroFormaggi: 13.00.

✎ write: ( menu ? 'Hawaii' ), brk.
✎ write: ( menu Margherita ), brk.

 
[Map] - [String]

Deletes the entry, identified by the key specified in [String], from
the map.
 
[Map] keys

Returns an array containing all the keys in the map.
The order of the keys is undefined. Use the sort message
to enforce a specific order. The 'entries' message
does exactly the same and is an alias for 'keys'.

Usage:

☞ city := List ← 'London' ; 'Paris' ; 'Berlin'.
☞ temperature := List ← '15' ; '16' ; '15'.

☞ weather := temperature by: city.
cities := weather entries sort: {
:a :b ↲ (a compare: b).
}.
 
[Map] values

Returns an array containing all the keys in the map.
The order of the keys is undefined. Use the sort message
to enforce a specific order.

Usage:

☞ city := List ← 'London' ; 'Paris' ; 'Berlin'.
☞ temperature := List ← '15' ; '16' ; '15'.

☞ weather := temperature by: city.
temperatures := weather values sort: {
:a :b ↲ (a compare: b).
}.
 
[Map] at: [Key]

Retrieves the value specified by the key from the map.
 
[Map] ? [Key]

Alias for [Map] at: [Key].

 
[Map] count

Returns the number of elements in the map.
 
[Map] each: [Block]

Iterates over the map, passing key-value pairs to the specified block.
Note that within an each/map block, '⛏' and '⚿' refer to the collection.
 
[Map] has: [Object]

Checks whether the map contains the specified value.
Note that the object gets converted to a string before
comparison. In case of a map or array this means the comparison
will be based on the serialized structure.
The example will output: True False False False False.

Usage:

☞ shop := (Map new
put: 'magazine' at: 'books',
put: 'computer' at: 'electronics',
put: 'lipstick' at: 'cosmetics'
).
✎ write: (shop has: 'computer'), end.
✎ write: (shop has: 'sausage'), end.
✎ write: (shop has: 'computers'), end.
✎ write: (shop has: 'compute'), end.
✎ write: (shop has: '2computer'), end.
 
[Map] string

Returns a string representation of a map encoded in Citrine itself.
This will give you an
evallable representation of the map and all of its members.
The sting method is automatically invoked when attempting to
print a Map:

Usage

m := (Map new) put: 'hello' at: 'world'.
x := m string.
✎ write: (Map new).

 
File

Represents a File object.
Creates a new file object based on the specified path.

Usage:

File new: '/example/path/to/file.txt'.
 
[File] path

Returns the path of a file. The file object will respond to this
message by returning a string object describing the full path to the
recipient.
 
[File] string

Returns a string representation of the file. If a path has been associated
with this file, this message will return the path of the file on the file system.
If no path has been associated with the file, the string [File (no path)] will
be returned.
 
[File] read

Reads contents of a file. Send this message to a file to read the entire contents in
one go. For big files you might want to prefer a streaming approach to avoid
memory exhaustion.
In the example we read the contents of the entire CSV file callled mydata.csv
in the variable called data.

Usage:

☞ data := File new: '/path/to/mydata.csv', read.

 
[File] write: [String]

Writes content to a file. Send this message to a file object to write the
entire contents of the specified string to the file in one go. The file object
responds to this message for convience reasons, however for big files it might
be a better idea to use the streaming API if possible (see readBytes etc.).
In the example we write the XML snippet in variable data to a file
called myxml.xml in the current working directory.

Usage:

☞ data := '<xml>hello</xml>'.
File new: 'myxml.xml', write: data.

 
[File] append: [String]

Appends content to a file. The file object responds to this message like it
responds to the write-message, however in this case the contents of the string
will be appended to the existing content inside the file.
 
[File] exists

Returns True if the file exists and False otherwise.
 
[File] include

Includes the file as a piece of executable code.
 
[File] delete

Deletes the file.
 
[File] size

Returns the size of the file.
 
[File] open: [string]

Open a file with using the specified mode.
The example opens the file in f for reading and writing.

Usage:

☞ f := File new: '/path/to/file'.
f open: 'r+'.
 
[File] close.

Closes the file represented by the recipient.
The example above opens and closes a file.

Usage:

☞ f := File new: '/path/to/file.txt'.
f open: 'r+'.
f close.
 
[File] read bytes: [Number].

Reads a number of bytes from the file.
The example reads 10 bytes from the file represented by f
and puts them in buffer x.

Usage:

☞ f := File new: '/path/to/file.txt'.
f open: 'r+'.
☞ x := f read bytes: 10.
f close.
 
[File] write bytes: [String].

Takes a string and writes the bytes in the string to the file
object. Returns the number of bytes actually written.
The example above writes 'Hello World' to the specified file as bytes.
The number of bytes written is returned in variable n.

Usage:

☞ f := File new: '/path/to/file.txt'.
f open: 'r+'.
☞ n := f write bytes: 'Hello World'.
f close.

 
[File] seek: [Number].

Moves the file pointer to the specified position in the file
(relative to the current position).
The example opens a file for reading and moves the
pointer to position 10 (meaning 10 bytes from the beginning of the file).
The seek value may be negative.

Usage:

file open: 'r', seek: 10.
 
[File] rewind.

Rewinds the file. Moves the file pointer to the beginning of the file.
The example reads the same sequence of 10 bytes twice, resulting
in variable x and y being equal.

Usage:

file open: 'r'.
☞ x := file read bytes: 10.
file rewind.
☞ y := file read bytes: 10.

 
[File] end.

Moves the file pointer to the end of the file. Use this in combination with
negative seek operations.
The example will read the last 10 bytes of the file. This is
accomplished by first moving the file pointer to the end of the file,
then putting it back 10 bytes (negative number), and then reading 10
bytes.

Usage:

file open: 'r'.
file end.
☞ x := file seek: -10, read bytes: 10.

 
 
[File] unlock.

Attempts to unlock a file. This message is non-blocking, on failure
it will immediately return. Answers True if the file has been
unlocked succesfully. Otherwise, the answer is False.
 
[File] lock.

Attempts to acquire an exclusive lock on file.
This message is non-blocking, on failure
it will immediately return. Answers True if the lock has been
acquired and False otherwise.
 
[File] list: [String].

Returns the contents of the specified folder as a an array.
Each entry of the array contains a map with the keys 'file'
and 'type'. The 'file' entry contains a string with the name
of the file while the 'type' entry contains a string describing
the type of the file.

Usage:

☞ files := File list: '/tmp/testje'.

 
 
 
 
[Program] clean memory

GarbageCollector, to invoke use:

Program clean memory.
 
[Program] memory
 
[Program] memory: [Number]

Sets the memory limit, if this limit gets exceeded the program will produce
an out-of-memory error.
 
[Program] tidiness: [Number]

Selects mode of operation for GC.

Available Modes:
0 - No Garbage Collection
1 - Activate Garbage Collector (default)
4 - Activate Garbage Collector for every single step (testing only)
8 - Activate experimental Pool Memory Allocation Manager (experimental!)
 
[Program] shell: [String]

Performs a Shell operation.

Usage:

☞ files := Shell ls

 
[Program] argument: [Number]

Obtains an argument from the CLI invocation.
 
[Program] arguments

Returns the number of CLI arguments passed to the script.
 
[Program] end

Exits program immediately.
 
[Program] setting: [String]

Returns the value of an environment variable.

Usage:

☞ x := Command setting: 'MY_PATH_VAR'.
 
[Program] setting: [Key] value: [Value]

Sets the value of an environment variable.
 
[Program] ask

Ask a question on the command-line, resumes program
only after pressing the enter key.
Only reads up to 100 characters.
The example asks the user for his/her name and
then displays the input received.

Usage:

✎ write: 'What is your name ?'.
☞ x := Program ask.
✎ write: ('Hello you' you: x), end.

 
[Program] input.

Reads all raw input from STDIN.
The input message reads the standard input stream of the application
which allows you to deal with pipes for instance. However this
mechanism can also be used to read raw POSTs in case of CGI applications.
Note that unlike other implementations the input messages also collects
null bytes, a null byte \0 in the input stream will NOT cause it to end.
Also note that the trailing newline (in case of CLI applications) will
be stripped so you don't have to do this manually. This allows for
one-liners like the one in the example below.
The input message is not allowed if message countdown has been activated
(Program remainingMessages:) because it might wait for content and this
is not allowed in a countdown sandbox.

Usage:

echo "hello" | ctr test.ctr

☞ x := Program input.
✎ write: x.

 
[Program] flush.

Flushes the STDOUT output buffer.
 
[Program] error: [String]

Logs the specified message string using syslog using log level LOG_ERR.
Use this to log errors.
 
[Clock] wait: [Number]

Suspends program execution for the specified number of seconds.
This can be used for instance, together with a whileFalse loop as the
following example illustrates. The following example demonstrates the
use of the Clock object and the wait message to wait until an
exclusive lock on the specified file has been acquired.

Usage:

{ ↲ file lock. }
false: { ⏰ wait: 1. }.

 
[Clock] new: [Number]

Creates a new clock instance from a UNIX time stamp.
 
 
 
[Clock] like: [Clock]

Syncs a clock. Copies the time AND zone from the other clock.

Usage:

☞ clock := Clock new: timestamp.
☞ copied := Clock new like: clock.
 
[Clock] zone: [String]

Sets the time zone of the clock.
 
[Clock] zone

Returns time zone of the clock.
 
[Clock] year: [Number]

Sets the year of the clock.
 
[Clock] month: [Number]

Sets the month of the clock.
 
[Clock] day: [Number]

Sets the day of the clock.
 
[Clock] hour: [Number]

Sets the hour of the clock.
 
[Clock] minute: [Number]

Sets the minute of the clock.
 
[Clock] second: [Number]

Sets the second of the clock.
 
[Clock] year

Returns year of the clock.
 
[Clock] month

Returns month of the clock.
 
[Clock] day

Returns day of the clock.
 
[Clock] hour

Returns hour of the clock.
 
[Clock] minute

Returns minute of the clock.
 
[Clock] second

Returns second of the clock.
 
[Clock] day of the year

Returns day number of the year.
 
[Clock] weekday

Returns the week day number of the clock.
 
[Clock] time.

Returns the UNIX time stamp representation of the time.
Note: this is the time OF CREATION OF THE OBJECT. To get the actual time use:

Usage:

☞ time := Clock new time.
 
[Clock] week

Returns the week number of the clock.
 
[Clock] format: [String]

Returns a string describing the date and time represented by the clock object
according to the specified format. See strftime for format syntax details.
 
[Clock] string

Returns a string describing the date and time
represented by the clock object. On receiving this message, the Clock
instance will send the message 'format:' to itself and the argument:
'%Y-%m-%d %H:%M:%S'. It will return the answer as a string. Note that you
can override this behaviour by adding your own 'format:' implementation.

Usage:

⏰ on: 'format:' do: { ↲ 'beautiful moment'. }.
⏰ on: 'time' do: { ↲ '999'. }.

✎ write: ⏰, end.
✎ write: ⏰ number, end.
 
[Clock] number

Returns a timestamp describing the date and time
represented by the clock object. On receiving this message, the Clock
instance will send the message 'time' to itself
and return the answer as a number. Note that you
can override this behaviour by adding your own 'time' implementation.

Usage:

⏰ on: 'format:' do: { ↲ 'beautiful moment'. }.
⏰ on: 'time' do: { ↲ '999'. }.

✎ write: ⏰, brk.
✎ write: ⏰ number, brk.
 
 
 
[Clock] add: [Number].

Adds the number to the clock, updating its time accordingly.
Note that this is typically used with a qualifier.
If the qualifier is 'hours' the number is treated as hours and
the specified number of hours will be added to the time.

The Clock object understands the following qualifiers
if the selected language is English:

sec, second, seconds,
min, minute, minutes,
hrs, hour, hours,
day, days,
week, weeks,
month, months,
year, years

Note that it does not matter which form you use, 2 hour means
the same as 2 hours (plural).

Usage:

clock add: 3 minutes.
clock add: 1 hour.
clock add: 2 second.
 
[Clock] subtract: [Number].

Same as '[Clock] add:' but subtracts the number instead of adding it to
the clock's time.
 
[Clock] new

Creates a new clock, by default a clock will be set to
the UTC timezone having the current time.
 
[Pen] write: [String]

Writes string to console.
 
[Pen] end

Outputs a newline character.
 
 
 
 
 
Request get: [string]

Returns the value of the specified GET parameter from the HTTP query string.
For example if the query string of an url is: ?search=glasses
then the value of:

item := Request get: 'search'.

would be 'glasses'.
 
Request getArray: [string].

Returns an array of strings extracted from the query string.
For example if the query string contains: ?option=a&option=b

Request getArray: 'option'.

will contain two elements: 'a' and 'b'. Note that
this also works with array-like notation: ?option[]='a'&option[]=b:

Request getArray: 'option[]'.

will return the same array.
 
Request post: [string].

Obtains a string from the HTTP POST payload. Just like 'get:' but for
POST variables. See 'Request get:' for details.
 
Request postArray: [string].

Obtains an array from the HTTP POST payload. Just like 'getArray:' but for
POST variables. See 'Request getArray:' for details.
 
Request cookie: [string].

Obtains a string from the HTTP COOKIE payload. Just like 'get:' but for
COOKIE variables. See 'Request get:' for details.
 
Request cookieArray: [string].

Obtains an array from the HTTP COOKIE payload. Just like 'getArray:' but for
COOKIE variables. See 'Request getArray:' for details.
 
Request file: [string].

Returns array containing the path to the uploaded temporay file (0) and
the desired name of the uploaded file (1).
 
Request serverOption: [string] is: [string].

Sets a server option, available server option for SCGI server include:

- minidle, minimum number of idle processes
- maxidle, maximum number of idle processes
- maxproc, maximum number of processes
- maxreq, maximum number of concurrent requests to allow

Usage:

Request
serverOption: 'minidle' is: 8,
serverOption: 'maxreq' is: 100.

This sets the minimum number of idle processes to 8 and the
maximum number of concurrent requests to 100, you can chain
multiple options using a comma (,).
 
Request host: [string] listen: [string] pid: [string] callback: [block].

Sets up Storm Server.
Storm Server is an SCGI server. Both the Request Object Plugin and Storm Server
are based on S. Losen's CCGI library (http://libccgi.sourceforge.net/doc.html)
licensed LGPL.

To set up a Storm Server, specify host (i.e. 'localhost'),
a port to listen to (i.e. 9000) a pid file '/var/run/mypid.pid' and a
callback block.

Usage:

Request host:'localhost' listen:4000 pid:'/var/run/storm.pid' callback: {
Pen write: 'Content-type: text/html\n\n'.
var fname := Command env: 'DOCUMENT_URI'.
var script := File new: '/var/www/webapp'+fname.
script include.
}.

Here we set up a server listening to port 4000. The callback prints out
the content type header. Then, we extract the DOCUMENT URI, i.e. '/hello.ctr'
and map this to a path '/var/www/webapp/hello.ctr'

By default there is no output buffering, either create another callback or
simply override the '<' or 'Pen' object to buffer instead of outputting
directly.
 
 
[String] escape: '0.

Escapes the specified ASCII character in a string.
If the character is a control character, the well known
C-based character substitute will be used.
 
[String] unescape: '0.

'UnEscapes' the specified ASCII character in a string.
 
[Json] new

Creates a new instance of the Json object.
The Json object allows you to use the Json protocol to communicate with
other applications.
 
 
[Json] parse: [String].

Parses a string containing Json encoded data into native Citrine objects.
The Json structure must begin with an object (notation: {}). Therefore,
the answer to this message from the Json object will always be a Map.

Usage:

☞ tasks := '{"todo":7,"finished":3}'.
✎ write: tasks todo. #7

 
[Json] jsonify: [Map].

Given a map, the jsonify: message will make the Json object return a
String object representing the Map.
 
C-constructor function.

This function gets called when the plugin is loaded into memory.
Here we have a chance to add the new object(s) to the World.

In this case, we are going to add the Json object to the
world.
 

BUGS

This is a preliminary version (< 1.0) of Citrine, there might still be very serious bugs. Please refrain from using this version in a production environment. This version of Citrine is still considered 'alpha' stage and cannot be expected to be reliable.
 

AUTHOR

Gabor de Mooij and the Citrine Community
14 July 2018 1.0