Brain

The Brain Programming Language Manual

Edition 0.5.2 Version 0.5.2

2 January 2000

Manuel Tomis


Table of Contents


GNU GENERAL PUBLIC LICENSE

Version 2, June 1991

Copyright © 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
  2. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
  3. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
    1. You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
    2. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
    3. If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
    These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
  4. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
    1. Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    2. Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    3. Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
    The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
  5. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
  6. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
  7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
  8. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
  9. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
  10. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
  11. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

    NO WARRANTY

  12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

one line to give the program's name and an idea of what it does.
Copyright (C) 19yy  name of author

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'.  This is free software, and you are welcome
to redistribute it under certain conditions; type `show c' 
for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision'
(which makes passes at compilers) written 
by James Hacker.

signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.

Basic Concepts

Brain is a prototype based, fully object-oriented, high level scripting language. It's features include: dynamic typing, a classless prototype based object model, built-in high-level data structures, closures, exceptions, lexical scope and more. It's syntax can be characterized as a cross between Smalltalk and JavaScript. Brain tries to be as simple and minimal as possible, yet at the same time to be orthogonal, flexible, complete and easy to extend.

Invoking Brain

Syntax

Brain has an extremely simple syntax. Basically all you can do in Brain is send messages to objects, and assign the results of expressions to variables, or object fields. Besides that the only other syntactical elements are literal forms for creating various objects, like strings, numbers, lists etc.

Comments

There are three kinds of comments in brain. The first kind begins with -- and extends to the end of the line. The second kind can span multiple lines, or be embedded in the middle of the line; it starts with {- and ends with -}. Also the third kind starts with #! and extends to the end of the line.

-- This is a single line comment
#! This is also a single line comment
{- 
This is a multi-line
comment. -}

Names

There are three kinds of names in Brain: variables/properties/unary-messages, operators and keywords.

Variables, properties and unary-messages must begin with a letter or an underscore (_), and after that can contain any number of letters, numbers, underscores, and dashes (-).

this-is-a-variable __this_ONE_2 

An operator is a sequence of characters containing any number of the following characters: + - / * ^ > < = .?  ~ ! $ % & \.

Some examples are:

+ - ++? -...

A keyword has the same syntax as a variable/property/unary but must end with a colon (:).

key: word: another-one:

Objects

Brain is a fully object-oriented language, and therefore everything in Brain is an object. That includes everything from numbers, characters, strings to files, directories, code blocks and whole programs. Unlike class-based languages that have two kinds of entities, classes and instances, Brain being a prototype-based language has only objects. New objects are created, not by creating instances of classes, but by cloning existing objects. This is usually done by sending them the new or the copy message, both of which are usually supported and usually have identical semantics.

new-object = object new.
new-object = object copy.
new-file = file new.
new-folder = folder new.

Another way of creating objects, is by using one of the many literal forms, that the syntax of Brain supports. More information about each object's special syntax is in corresponding node for that object (see section Standard Objects)).

Here are some examples Brain's different kinds of object literals:

Strings
"Hello" "One\nTwo\n"
"""Multiline
String"""
Symbols
#symbol #+++ #from:to:
Characters
'a' 'B' '\x3f'
Numbers
123 123.456 123.4e-10

0x23  -- Hexadecimal
0b1001 -- Binary
006701 -- Octal

Lists
[1, 2, 3, '4', "This", true, false, {"hello"} println]
[1..10] [1,3 .. 100]
Hashtables
#["foo" = #bar, "yada" = bla, 6 = 66]
Sets
#{1, 2, 3, #little, "piggies"}
Objects
#(name = "Manuel", age = 22)
#(|object-to-clone| title = "Gnurassic")
Byte Arrays
#|12 34 6 56 67|
Code Blocks
{"This is a code block that" print.
 " print prints this string when evaluated" print}
{|a b| a + b}

Any object that was created using the #() form or was cloned from the built-in object object supports a special syntax for referencing and assigning it's fields using the ! operation.

o = #(foo = "Mommy, I saw a UFO!").
o!foo println.
=> Mommy, I saw a UFO!
o!foo = "Greetings terrans! Take me to your leader"
o!foo println.
=> Greetings terrans! Take me to your leader

Instead of inheritance Brain supports delegation. This is done by assigning a special object property called prototype. Whenever a method is sent to an object, or a property of it is referenced or assigned then, if the method or property is not found, it is looked up in the object that is the value of the prototype field (If it is not found there then it is looked up in the prototype of the prototype and so on). If the method or property is found in the prototype then it is the prototype that becomes the receiver object of the message.

thing = object subtype.
thing method: #foo is: {"Foo!!!" println}.
object!prototype = thing.
object foo.

=> Foo!!!

There are some methods that are supported by all object types.

Method: object print
Displays a string on standard output that describes this object.

Method: object println
Displays a string on standard output that describes this object, and also prints a newline character.

Method: object to-string
Returns a string containing a description of the object.

Method: object print-to: stream
Prints a textual description of the object onto stream.

Method: object hash
Returns a hash value for this object.

Method: object type
Returns a symbol that represents the type of the object.

Method: object switch: selection
Similar to the switch statement in C. selection is either a list or a hashtable containing pairs of values to match and results to return if matched. If the result is a code block it is evaluated and the result is returned otherwise the result is returned as is. If there was no match nil is returned.
3 switch: [2, {"X" println}, 3, {"Y" println}, 4, {"Z" println}].
=> Y

3 switch: #[2 = {"X" println}, 3 = {"Y" println}, 4 =  {"Z" println}].
=> Y

Method: object switch:else: selection no-match
Similar to the switch statement in C. selection is either a list or a hashtable containing pairs of values to match and results to return if matched. If the result is a code block it is evaluated and the result is returned otherwise the result is returned as is. If there was no match no-match is returned (if it is a code block it is evaluated and it's result is returned).

Method: object if-nil: action
Evaluates action if the object is nil, otherwise it returns the object itself.

Method: object if-not-nil: action
Evaluates action if the object is not nil, otherwise it returns the object itself.

Method: object if-nil:if-not-nil: nil-action not-nil-action
Evaluates nil-action if the object is nil, otherwise it evaluates not-nil-action.

Method: object if-not-nil:if-nil: nil-action not-nil-action
Evaluates nil-action if the object is nil, otherwise it evaluates not-nil-action.

Method: object method:is: name code
Adds a method to this object called name (which must be a string or a symbol). The code is either a code block that will be the code for the method or it can be a string or a symbol in which case the code for the method will be the code for an existing method.
object method: #hello is: {"hello world" println}.
object method: "hello-again" is: #hello.

Expressions

Expressions basically consist of sending messages to objects, referencing variables, and creating objects using literal forms.

There are four different kinds of messages. The first kind is the unary message which does not take any parameters. You can send more than one unary message in a row by putting one message keyword after the other. The receiver of each message will be the result of the last message:

object message.
"Hello" print print println.

The second kind of message is the binary message which takes one parameter and is used to implement operators. All operators have the same precedence and are evaluated from left to right.

2 - 3 + 4 / 5 ** 100

The third kind of message is the keyword message which can take any number of parameters (except zero parameters).

object key: param1 word: param2 message: param3. -- Method key:word:message:
0 to: 10 do: {|i|i println}. -- Method to:do:

The fourth kind of message is the block evaluation message, usually sent to code blocks to evaluate them:

block ().
block2 (1, 2, 3, 4, 5, 6, 7).

However this message can be defined for any kind of object:

object method: "()" is: {"Hello" println}.
object ().
=> Hello

The precedence of the messages is the following: unary (highest), block-evaluation, binary, keyword (lowest).

You can use the result of one expression in another expression using parenthesis:

(1 + (10 / 2)) println.
list put: (other-list at: 4).

There is a special form expression; message; message that is equivalent to (((expression) message) message):

[] put: 1; put: 2; put: 3; println.
-- equivalent to ((([] put: 1) put: 2) put: 3) println.

Assignment

There are two kinds of statements in Brain: plain expressions and assignment statements. Statements within a block are separated by a dot . and not by a semicolon an in other languages.

There are two kinds of things that can be assigned to in brain: The first thing is variables and the other thing is properties of objects.

my-name = "Manuel Tomis".
captain!name = "J. L. Picard".

The first example assigns a value to the variable my-name. The second example assigns a value to the property name. An object does not need to have a property in order to assign a value to it, but the assignment automatically creates that property if the object does not already have it. (Note that usually built-in objects, like strings, characters, files, etc can not have properties).

Brain supports lexical scope and closures. That means the there exist variables that are visible to all scopes, and variables that are visible only within a scope and the scopes within that scope. New scopes are created when defining code blocks (Each code block definition starts a new scope, which is terminated at the end of the code block definition). A new local variable is created with the keyword var. If an assignment is made to a variable that wasn't declared with var, then that variable will be considered a global variable. Note that local variable declarations must appear in a block before other kinds of statements.

a-global-variable = "Hello there".
{
  var local-variable-here = "hello".
  {
    var another-local = local-variable + " again!".
    var enterprise. -- initialized to nil
    another-global = "This one is a global variable".
  }
}

There is a special variable called self, which is meaningful within methods. This variable is the object the method belongs to.

person = #(name = "Karl", surname = "Marx").
person method: #print is: {
  "My name is " + self!name + " " + self!surname + "."; println
}

Multiple variables and properties can be assigned in the same statement:

[a, b!c!d, e] = [1, 2, 3].

list = [1, 2, 3].
[a, b!c!d, e] = list.

As can be seen from the examples, on the left hand side the variables and properties to be assigned are given in a list like notation, and on the right hand a list must be supplied with the values. Each variable in the left-hand list will be assigned the value in the corresponding position in the right-hand list. Note that when the right-hand list is given explicitly, as in the first case, this is recognized by the compiler and an actual list object is not created during runtime, but the values are evaluated and assigned directly.

Standard Objects

Block

A block represents an executable piece of code, something like a function in other languages. It can take parameters, and have local variables. The block consists of a set of statements, which are separated by a dot (.).

{} -- An empty code block.
{"Hello" println}
{|a b c| a + b + c} -- A code block with 3 parameters
{'1' print. '2' print. '3' print} -- A code block with 3 statements.

The last statement/expression in a block is the value that is returned when the block is evaluated. Brain, like Scheme/Lisp, does not have a return statement. The reason for that is that all code blocks are considered equal in Brain, and there is no distintion between blocks that are methods of an object, and blocks that are not. That means that a return statement, would only return to the outer block, and not return from the method, while the statements following the return statement would never be executed. If you need to use the equivalent of a return/break statement you can use exceptions:

{
bla do-this.
{this == that} if-true: {#return throw: value}.
bla do-that.
} catch: #return do: {|retval| retval}.

A code block can be evaluated by sending it the special message ().

f = {"Hello" world} ().

add = {|a b| a + b}.
add (1, 3); println.

Method: block catch:do: exception action ...
Catches an exception. If the exception, which is a symbol, is caught then action is evaluated. If the exception is equal true, then any exception is caught. Variants of this method are defined for catching up to 10 exceptions in one handler. If action is a block it is evaluated, otherwise it is returned as is.

{
#foo throw.
}
catch #bar do: {"Caught bar" println}.
catch #foobar do: {"Caught foobar" println}.
catch #foo do: {"Caught foo" println.}.

Method: block loop
Continuously evaluates the block. The loop can only be exited with an exception or with then brain exit message.

Method: block parameters
Returns the number of parameters this block requires.

Method: block while-false
Continuously evaluates the closure as long as the result of the evaluation is false.

Method: block while-false: action
Continuously evaluates action while the block evaluates to false.

Method: block while-nil
Continuously evaluates the block while the result is nil.

Method: block while-nil: action
Continuously evaluates action while the block evaluates to nil.

Method: block while-not-nil
Continuously evaluates the block until the result is nil.

Method: block while-not-nil: action
Continuously evaluates action as long as the block doesn't evaluate to nil. The action can either take no parameters or take as a parameter the result of the block.

Method: block while-true
Continuously evaluates the closure as long as the result of the evaluation is true.

Method: block while-true: action
Continuously evaluates action while the block evaluates to true.

Boolean

The brain language has two objects once called true and the other false. These objects are used to represent the behaviour of the boolean type of other languages. For example the expression (1 == 1) , which compares the number 1 to itself returns the object true. In the same way the expression (['a', 'b', 'c'] contains: 'g') returns the object false.

In the spirit of minimalism and orthogonality on which Brain is based (like Smalltalk and Self), it does not include any built-in control structures like if, while etc. Instead these are modeled using messages together with code blocks(closures). Both the true and the false object contain methods with identical names. For example both true and false have an if-true: method. However each object has a different behavior for each corresponding object. This is how control structures are built in Brain.

In the first example the block passed as an argument argument is evaluated by the method if-true: of the true object and `Hello' is displayed on standard output.

(1 == 1) if-true: {"Hello" println}.

In this case the block argument is not evaluated by the method if-true: of the false object, and therefore nothing is displayed on standard output.

(1 == 3) if-false: {"Goodbye" println}.

Method: boolean and: param
Implements the boolean and operation. The parameter param must either be one of the boolean objects (that is either true or false), or it must be a closure. In the second case a kind of `short-circuit-evaluation' is performed, and the closure is evaluated only if it is needed. It returns true if both the receiver and param evaluate to true, otherwise it returns false.

Method: boolean if-false: action
If the receiver was false then the action parameter, which must be a closure is evaluated, otherwise if the receiver is true then nothing is done.

Method: boolean if-false:if-true: false-action true-action
If the receiver was true then the true-action parameter, which must be a closure is evaluated, otherwise if the receiver is false then the false-action parameter is evaluated.

Method: boolean if-true: action
If the receiver was true then the action parameter, which must be a closure is evaluated, otherwise if the receiver is false then nothing is done.

Method: boolean if-true:if-false: true-action false-action
If the receiver was true then the true-action parameter, which must be a closure is evaluated, otherwise if the receiver is false then the false-action parameter is evaluated.

Method: boolean not
Implements the boolean not operation. If the receiver was true it returns false, otherwise if the receiver was false it returns true.

Method: boolean or: param
Implements the boolean or operation. The parameter param must either be one of the boolean objects (that is either true or false), or it must be a closure. In the second case a kind of `short-circuit-evaluation' is performed, and the closure is evaluated only if it is needed. It returns true if either the receiver or param evaluate to true, otherwise it returns false.

Brain

The brain object represents the brain interpreter. It has methods for accessing various system functions that didn't fit anywhere else, as well as methods for accessing various functions of the interpreter.

Method: brain args
Returns a list of strings containing the command line arguments for this program.

Method: brain exception-file
Returns the name of the file in which last exception was thrown.

Method: brain exception-line
Returns the source code line in which the last exception was thrown.

Method: brain exception-symbol
Returns the symbol of last exception that was thrown.

Method: brain exec:with: program flags
Executes a subprocess.

Method: brain exit
Exits the brain interpreter by calling the C function exit (0).

Method: brain exit: number
Exits the brain interpreter by calling the C function exit () with the parameter number.

Method: brain gc
Run the garbage-collector.

Method: brain getenv: name
Returns a string that is the value of the envirnment variable name.

Method: brain global: name
Returns an object that is the value of the global variable name.

Method: brain global:is: name value
Assignes value to the global variable name.

Method: brain import: module
Load and run a Brain module. The module will be loaded and run using it's own namespace. The file will loaded and run only the first time the method is called, and it's result will be cached and retured, in any further calls for the same module. The file parameter must be a string, containing the plain module name, and it must not have either a path, or a suffix. The file is looked up in the module path, and if it is not found a runtime error occurs.

The method returns the result of evaluating the file.

module = brain import: "banana".

Method: brain load-config: file

Method: brain load-library: library
Loads a native library.

Method: brain load: file
Load and run a Brain source file. The file will be loaded and run using the current namespace. Every time the method is called for the same file, the file will be reloaded and rerun. The file parameter must be a string. The file is looked up in the module path, and if it is not found a runtime error occurs.

The method returns the result of evaluating the file.

brain load: "banana.brn".

Method: brain module-path

Method: brain random
Returns a random number. It uses the stdlib function random ().

Method: brain system: string
Uses the C library funtion system (char *) to execute the shell command string.

Method: brain version
Returns a string that contains information about the version of this distribution of the Brain language.

ByteArray

This object represents an array containing raw bytes. A byte can be between 0 and 255. Possible uses for this object are:

The syntax for creating a byte-array is:

#|123 234 1 2 {- Hex data follows -} #ff #f2|

A byte-array literal starts with #| , then follows a sequence of numbers and then it terminates with a |. Numbers inside a byte-array literal must have values must be between 0 and 255, otherwise a syntax error will be reported. Arbitrary whitespace and even comments can be between the numbers. However the items in the array can only be numeric literals, and not arbitrary expressions.

#|1 2 (3 + 4 / 2)| -- Error! (3 + 4 / 2) is not allowed.

Method: bytearray at: index
Returns a number representing the byte at position index.

Char

Character objects represent a single character. The syntax is like this:

'a' 'B' '\n' '\t' '\\' '\"

Special escape sequences are recognised. '\n' = newline '\t' = tab '\r' = carriage return '\f' = form feed '\0' = null character '\xff' = hex escape

Method: char +

Method: char -

Method: char < char2
Tests whether the character has a smaller value than char2. Returns true is the character is smaller, otherwise it returns false.

Method: char <= char2
Tests whether the character has a smaller or equal value to char2. Returns true is the character is smaller or equal, otherwise it returns false.

Method: char <> char2
Compares the character to char2. Returns false if they are equal, otherwise it returns true.

Method: char == char2
Compares the character to char2. Returns true if they are equal, otherwise it returns false.

Method: char > char2
Tests whether the character has a larger value than char2. Returns true is the character is larger, otherwise it returns false.

Method: char >= char2
Tests whether the character has a larger or equal value to char2. Returns true is the character is larger or equal, otherwise it returns false.

Method: char enum-next:to: char2 char3
Implements the special syntax: [a, b, .. c]

['a', 'c', .. 'i']
=> ['a', 'c', 'e', 'g', 'i']

Method: char enum-to: char2
This method is used to implement the special syntax [a .. b]

['a' .. 'e']
=> ['a', 'b', 'c', 'd', 'e']

Method: char is-digit
Tests whether the character is a digit. Returns true if the character is a digit, otherwise it returns false.

Method: char is-letter
Tests whether the character is a letter. Returns true if the character is a letter, otherwise it returns false.

Method: char is-lower
Tests whether the character is a lowercase character. Returns true if the character is a lowercase character, otherwise it returns false.

Method: char is-space
Tests whether the character is a whitespace character. Returns true if the character is a whitespace character, otherwise it returns false.

Method: char is-upper
Tests whether the character is an uppercase character. Returns true if the character is an uppercase character, otherwise it returns false.

Method: char ord
Returns a number representing the ASCII value of the character.

Method: char to-lower
If the character is an uppercase character, the method returns the corresponding lowercase character, otherwise the character is self is returned.

Method: char to-upper
If the character is a lowercase character, the method returns the corresponding uppercase character, otherwise the character is self is returned.

Date

Method: date <

Method: date <=

Method: date <>

Method: date ==

Method: date >

Method: date >=

Method: date copy

Method: date format: format-string
Converts the date to a string, formatted according to the format-string.

Method: date new

Method: date set-from-clock

Method: date set:format: string format-string
Sets the date from the string, which is parsed according to the format-string.

File

This object represents files on a filesystem. You can create file objects by cloning the file object.

Also there exist 3 predefined stream objects, stdin, stdout, and stderr which represent the standard input, standard output, and standard error.

Method: file close
Closes the file. After a close operation a file object is no longer assosiated with an actual file on the filesystem and therefor no operations, except open:with: can be performed on the object.

Method: file copy
Creates a copy of the file object and returns it. If the file object was associated with an open file, then the new object will also be associated with the same file.

The new and the copy methods are identical.

Method: file delete

Method: file flush
Forces a write of all buffered data to the file.

Method: file is-end
Returns true if there are no more characters left to read in the file, otherwise returns false.

Method: file mark
Marks the current position of the file. The file can be reset to that position with the reset method.

Method: file mode: mode

Method: file new
Creates a copy of the file object and returns it. If the file object was associated with an open file, then the new object will also be associated with the same file.

The new and the copy methods are identical.

Method: file open: name

Method: file open:mode: name mode
Opens the file named name, which must be a string with a given mode. The mode, which is a string can be, "w" for writing, "r" for reading, and "rw" for reading and writing.

Method: file peek
Returns the character that will be retured by the next read operation.

Method: file property: name

Method: file read
Reads a character from the file and return it.

Method: file read-all
Returns the contents of the file as a string.

Method: file read-line
Reads a line from the file and returns it as a string.

Method: file reset
Resets the file position to the one marked by the last call to the mark mehtod.

Method: file rewind
Resets the current read/write position of the file, to the beginning of the file.

Method: file seek: pos
Sets the current read/write position of the file to pos.

Method: file skip-lines: n
Advances the read/write position of the file by n lines.

Method: file skip: n
Advances the read/write position of the file by n bytes.

Method: file tell
Returns the current read/write position of the file.

Method: file write: value
Writes the value to the file. The value can be either a character, a string, a string-buffer or a byte-array.

Folder

This object represents a directory on the filesystem.

Method: folder close

Method: folder new
Creates a new directory object.

Method: folder open: name
Associates this object with a directory on the file system that has the name name.

Method: folder peek

Method: folder read
Returns a string containing the name of the next file in the directory.

Method: folder rewind

Method: folder seek

Method: folder tell

Hashtable

Hashtables are unordered collections of objects in which values can be indexed by arbitrary objects.

Method: hashtable at: key
Returns the value that is indexed in the hashtable by key.

Method: hashtable at:put: key value
Inserts value into the hashtable, indexed by key. The value can later be retrieved by table at: value..

Method: hashtable clear

Method: hashtable contains-key: key
Tests whether the hashtable contains key. Returns true if the key is found, otherwise it returns false.

Method: hashtable contains: value
Tests whether the hashtable contains value. Returns true if the object is found, otherwise it returns false.

Method: hashtable copy

Method: hashtable hash

Method: hashtable is-empty

Method: hashtable keys-to-list

Method: hashtable new

Method: hashtable remove: key
Removes the entry in the hastable whose index is key. Both the key and the corresponding value are removed.

Method: hashtable size
Returns the number of elements in the hashtable.

Method: hashtable to-list

Method: hashtable values-to-list

List

Lists are ordered collections of objects. Lists are created using the following syntax:

[] -- An empty list.
[1, 2, 3, 'a', "b", ["hello"]] -- A list containing a variety of elements.

There is another special syntax for creating lists containing ranges of items:

[1..5]
==> [1, 2, 3, 4]
[1, 3 .. 11]
==> [1, 3, 5, 7, 9]

These forms are actually syntactic sugar, and are implemented by two special methods: The first form is translated into a call to the method enum-to:, while the next form is translated into a call to the method enum-next:to:.

Method: list * n
Creates a new list the contains the elements of the original list repeated n times.

[1, 2, 3] * 3
=> [1, 2, 3, 1, 2, 3, 1, 2, 3]

Method: list + list2

Method: list - list2
Creates a new list that contains all the elements of the list that are not also contained in list2.

Method: list all: condition-block

Method: list and

Method: list any: condition-block

Method: list append: list2
Appends the contents of list2 to the end of the list.

Method: list at: index
Returns the object at index, in the list.

Method: list at:insert-list: index values-list
Inserts the elements of the list values-list at position index in the list. All list elements after index are moved further to the end of the list, by values-list size positions to make room for the new entries.

Method: list at:insert: index value
Inserts the value at position index in the list. All list elements after index are moved one position further to the end of the list.

Method: list at:put: index object
Sets the value in the list at index to object.

Method: list clear
Removes all the elements from the list.

Method: list clear: n
Resizes the list so that it contains only the first n elements. If the list contains less that n elements, then nothing happens.

Method: list contains: object
Returns true if object is an element of the list, otherwise it returns false.

Method: list copy
Returns a copy of the list.

Method: list drop-while: condition-block

Method: list filter: action

Method: list first
Returns the first element of the list, without removing it.

Method: list first: value
Assignes the value to first position in the list.

Method: list flatten
Returns a new list which contains the elements of the list (which must be all lists) joined together.

[[1,2,3], [4,5], [6, 7]] flatten.
==> [1, 2, 3, 4, 5, 6, 7]

Method: list for-each-group:do: group-size action

Method: list for-each: action

Method: list for-each:until: action end-value

Method: list from: index
Returns a new list containing the elements of the list, from index up to the end of the list.

Method: list from:do: index action

Method: list from:to: index1 index2
Returns a new list containing the elements of the list, from the position index1 of the list up to, but not including position index2.

Method: list from:to:do: index1 index2 action

Method: list hash

Method: list index-of: object
If the object is contained in the list, the index of the first occurence is returned, otherwise nil is returned.

Method: list insert-list: values-list
Inserts the elements of the list values-list at the beginning of the list. All list elements after index are moved further to the end of the list, by values-list size positions to make room for the new entries.

Method: list insert: value
Inserts value at the beginning of the list. All the the other list elements are moved one position further to the end of the list.

Method: list is-empty
Returns true if the list contains no elements, otherwise it returns false.

Method: list last
Returns the last element of the list, without removing it.

Method: list last-index-of: object
If the object is contained in the list, the index of the last occurence is returned, otherwise nil is returned.

Method: list last: value
Assignes the value to last position in the list.

Method: list map: action

Method: list or

Method: list pop
Return the last element of the list, and then removes it from the end of the list.

Method: list put-unique: value

Method: list put: object
Inserts an object at the end of the list.

Method: list reduce: action

Method: list remove: index
Removes the element at position index from the list.

Method: list reverse
Reverses the ordering of the elements of the list.

Method: list rotate: n
Rotates the order of the contents of the list by n positions. The parameter n must be a positive or a negative number. If n is positive then all the elements are moved n positions to the right, otherwise if n is negative all the elements of the list are moved -n positions to the left.

[1, 2, 3, 4] rotate: 2.
=> [3, 4, 1, 2]

[1, 2, 3, 4] rotate: -1.
=> [2, 3, 4, 1]

Method: list select
FIXME:

Method: list size
Returns the number of elements in the list.

Method: list sort
Sorts the list in ascending order.

Method: list sort: cmp-function
Sorts the list, using cmp-function to compare the elements of the list.

Method: list take-while: condition-block

Method: list to: index
Returns a new list containing the elements of the list, from the beginning of the list up to, but not including position index of the list.

Method: list to:do: index action

Method: list trim
Reduces the capacity of the list to be equal to the current number of entries in list. This is usefull for saving memory, if you have constructed a list and want to store it somewhere for a long period of time.

Method: list zip

Number

Brain supports arbitrary precision arithmetic. For efficiency reasons there are actually three different number types: integers, longs, and rationals. Conversion between these types is automatic and transparent.

0
1234567
123456789101112131415161718192021222324252627282930
1234.56-e78
0xabcf        -- Hexadecimal number.
0b110010      -- Binary number.
017064        -- Octal number.

Method: number % number2
Returns the remainder of the number divided by number2.

Method: number * number2
Returns the result of the number multiplied by number2.

Method: number ** n
Raises the number to the n power.

Method: number + number2
Returns the sum of the number and number2.

Method: number - number2
Returns the result of the number minus number2.

Method: number / number2
Returns the result of the number divided by number2.

Method: number < number2
Compares the number to number2. Returns true if the number is smaller that number2, otherwise it returns false.

Method: number <= number2
Compares the number to number2. Returns true if the number is smaller or equal to number2, otherwise it returns false.

Method: number <> number2
Compares the number to number2. Returns false if they are equal, and true otherwise.

Method: number == number2
Compares the number to number2. Returns true if they are equal, and false otherwise.

Method: number > number2
Compares the number to number2. Returns true if the number is greater that number2, otherwise it returns false.

Method: number >= number2
Compares the number to number2. Returns true if the number is greater ot equal to number2, otherwise it returns false.

Method: number abs
Returns the absolute value of the number.

Method: number acos

Method: number acosh

Method: number asin

Method: number asinh

Method: number atan

Method: number atanh

Method: number cos

Method: number cosh

Method: number div: number2
This method performs integer division. Returns the result of the number divided by number2.

Method: number exp

Method: number is-negative
Returns true if the number is negative, otherwise returns false.

Method: number is-positive
Returns true if the number is positive, otherwise returns false.

Method: number log

Method: number max: num
Returns num, if it is greater than the number, otherwise it returns the number itself..

Method: number min: num
Returns num, if it is smaller than the number, otherwise it returns the number itself..

Method: number negate
Return (0 - number).

Method: number sin

Method: number sinh

Method: number tan

Method: number tanh

Method: number times-repeat: action
Evaluates the block action, number times.

Method: number to-char
Converts the number to a character.

Method: number to:by:do: end step action
For every number from the number to end with an increment factor of step, action is evaluated. action either takes no parameters, or it takes one parameter, a block which takes as a parameter the current value of the iteration.

Method: number to:do: end action
For every number from the number to end, action is evaluated. action either takes no parameters, or it takes one parameter, a block which takes as a parameter the current value of the iteration.

0 to: 10 do: {"No parameter" println}.
10 to: 0 do: {|i| ("With parameter:" + i) println}.

Method: number trunc
Converts the number to an integer, discarting the decimal part, if any.

Object

Objects that are cloned from this one, represent user defined objects. An object consists of a set of properties that have values, and a set of messages it can understand. They can be created thought the new message, or by using a special syntax:

#(a = 1, b = "Hello", c = [1, 2, 3, 4]).
#(|object-to-be-cloned subtype| x = "value1", y = #value2).

The first example creates a new object with the properties a, b and c set to some values. The second example besides specifying the properties of the object, and their values also specifies which object to clone, to create the new object. That is the object specified will be cloned (using the new message), and then the specified properties will be added to it.

You can reference and assign properties of objects using the ! operation:

object!this = "That".
object!this println.

=> That

Method: object property: property

Method: object property:is: property value

Method: object subtype
Creates a new object that contains a copy of both the field table and the method table of the original object. The difference between this method and the new method is that the new method only copies the fields and not the methods.

Process

Method: process error

Method: process input

Method: process output

Method: process status

Method: process wait

Regex

This object represents a compiled regular expression.

Method: regex match: string

Set

A set is an unordered collection object which is similar to the concept of sets in mathematics. A set is a collection the can an either contain or not contain a certain object. Operations on sets include: adding an element, removing an element, checking whether a set contains an object or not, etc. Actually the set object in Brain is really a bag and not a set. Set objects in Brain can actually contain more than once the same item. Methods are provided to use the object both as a set object, and as a bag object.

Sets are created using the following special syntax:

#{1, 2, 'a', 'b', [], "Hello, I am a set element"}

Method: set clear

Method: set contains: object
Tests whether the object is an element of this set. Returns true if the object is an element of this set, false otherwise.

Method: set copy

Method: set count-of: object
Tests whether the object is an element of this set. Returns true if the object is an element of this set, false otherwise.

Method: set hash

Method: set new

Method: set put: object
Inserts the object into the set.

Method: set remove-all: object
Removes all instances of the object from the set.

Method: set remove: object
Removes the object from the set.

Method: set size
Returns the number of elements contained in the set.

String

String objects represent a sequence of characters. The syntax for creating strings is as follows.

"This is a string"

Special escape sequences are recognised in strings. '\n' = newline '\t' = tab '\r' = carriage return '\f' = form feed '\0' = null character '\xff' = hex escape

Method: string * count
Returns a string which is this string count times appended to itself. For example:
"Three times!!!" * 3
=> "Three times!!!Three times!!!Three times!!!"

Method: string + string2
Returns a new string which is the concatenation of string and string2.

Method: string < string2
Compares the string to string2. Returns true if the string is smaller that string2, otherwise it returns false.

Method: string <= string2
Compares the string to string2. Returns true if the string is smaller or equal to string2, otherwise it returns false.

Method: string <> string2
Compares the string to string2. Returns true if they are not equals, and false if they are equal.

Method: string == string2
Compares string to string2 and returns true if they are equal and false if they are not. Two strings are equal if they are of the same size and each corresponding character is the same.

Method: string > string2
Compares the string to string2. Returns true if the string is larger that string2, otherwise it returns false.

Method: string >= string2
Compares the string to string2. Returns true if the string is larger or equal to string2, otherwise it returns false.

Method: string at: offset.
Returns the character contained in the string at offset.

Method: string compare: string2
Compares the string to string2. Returns 1 if the string is greater than string2, 0 if they are equal and -1 if string2 is greater.

Method: string contains: pattern
Returns true if the pattern is contained within the string, otherwise it returns false. The pattern can be a string, a character or a regular expression.

Method: string count-indent: tab-size
Returns the indentation level of the current string. Tabs are expanded and their size is assumed to be tab-size.

Method: string ends-with: pattern
Tests whether this string ends with pattern, which can be a character, a string or a regular expression. Returns true if the string does indeed end with pattern, otherwise it returns false.

Method: string eval

Method: string for-each: action

Method: string from: offset
Returns a new string that contains the characters of this string from offset up to the end of the string.

Method: string from:to: offset-1 offset-2
Returns a new string that contains the characters of this string from offset-1 up to, but not including offset-2.

Method: string hash

Method: string index-of: pattern
Returns the index of the first occurence of pattern in the string. If the string is not found it returns nil. The pattern can be a string, a character or a regular expression.

Method: string print
Displays the string on stdout.

Method: string println
Displays the string on stdout and also prints a newline character.

Method: string replace:with: pattern-1 pattern-2
Makes a copy of this string and the replaces all occurences of pattern-1 with pattern-2. pattern-1 can be a character, a string or a regular expression. pattern-2 can be a character or a string. Returns the new string.

Method: string reverse
Returns a new string which contains the characters of this string but in reversed order.

Method: string size
Returns the number of characters contained is this string.

Method: string split
Splits this string into words separated by whitespace and puts the substrings in a list. Returns a list of strings.

Method: string split-at: pattern
Splits this string into words separated by pattern and puts the substrings in a list. Pattern can be a character, a string or a regular expression. Returns a list of strings.

Method: string starts-with: pattern
Tests whether this string begins with pattern, which can be a character, a string or a regular expression. Returns true if the string does indeed begin with pattern, otherwise it returns false.

Method: string to-buffer
Returns a new string-buffer containing only this string.

Method: string to-list
Returns a list containing all the characters of the string.

Method: string to-lower
Returns a new string which contains the characeters of this string, only all upper-case characters are converted to lower-case.

Method: string to-number
Convert the string representing a number to a number.

Method: string to-regex
Creates a new regular-expression object out of the string.

Method: string to-source
Returns a string containing an `official' form of the string, which is the string with a `"' appended to its end and to it's front.

Method: string to-string
Returns the string back.

Method: string to-symbol
Creates a new symbol object out of the string.

Method: string to-upper
Returns a new string which contains the characeters of this string, only all lower-case characters are converted to upper-case.

Method: string to: offset
Returns a new string that contains the characters of the string from the beginning up to, but not including offset.

Method: string trim
Returns a new string that contains this string but without the leading and trailing whitespace.

StringBuffer

A string-buffer is a buffer of characters. Unlike strings, which are immutable and cannot have their contents modified, string-buffers allow modification of their contents, such as inserting characters and strings, changing the value of a certain index in the buffer etc.

String-buffers also behave like character streams, and support an interface that is similar to files.

String-buffers are created by cloning the global object string-buffer.

string-buffer new; put: "Once"; put: " upon "; put: " a time."; println.
=> Once upon a time.

Method: stringbuffer at: index
Returns the character at position index in the buffer.

Method: stringbuffer at:put: index object
Writes object in the buffer beginning at position index. Previous contents at that position are overwritten.

Method: stringbuffer clear
Clears the contents of the buffer.

Method: stringbuffer copy
Returns a copy of the buffer.

Method: stringbuffer flush
This is a dummy method and only exists, for compatibility with the interface of file objects.

Method: stringbuffer is-end
Returns true if the current read/write position has reached the end of the buffer, otherwise false is returned.

Method: stringbuffer new
Returns a copy of the buffer. This method is identical to the new method.

Method: stringbuffer peek
Returns the next character in the buffer, but does not advance the read/write position. If the end of the buffer has been reached it returns nil.

Method: stringbuffer put: object
Inserts an object at the end of the buffer. The object can be a character, a string or a buffer.

Method: stringbuffer read
Returns the next character in the buffer, and advances the read/write position. If the end of the buffer has been reached it returns nil.

Method: stringbuffer read-line
Reads a line from the buffer, and returns it.

Method: stringbuffer rewind
Resets the current read/write position to the beginning of the buffer.

Method: stringbuffer seek: index
Sets the read/write position to index.

Method: stringbuffer size
Returns the number of characters in the buffer.

Method: stringbuffer skip-lines: n
Advances the read/write position of the buffer by n lines.

Method: stringbuffer skip: n
Advances the read/write position of the buffer by n characters.

Method: stringbuffer tell
Returns the current read/write position.

Method: stringbuffer to-number
Converts the buffer to a number.

Symbol

A symbol object is similar to a string object, only that all identical symbols are represented by the same object. That means that for example while two strings, like "Sonia" and another one "Sonia", might be actually represented in memory by two differently allocated objects, while if they were symbols they would always be represented by the same object.

The syntax for creating symbols is:

#Hello  #Hello-again #++ #This:is:a:symbol

Basically the syntax is a `#' followed by a valid identifier, keyword or operator. Another way to create symbols is by the to-symbol method of the string object.

Symbols are also used internally by the interpreter to represent, keywords, operators, and identifiers.

Method: symbol <> sym
Return true if the symbol is not equal to sym, otherwise returns false.

Method: symbol == sym
Return true if the symbol is equal to sym, otherwise returns false.

Method: symbol throw
Throws an exception. The exception can be thrown without parameters as in:

#exception-symbol throw.

There are also variations of this method that can pass parameters to the exception handler:

#syntax-error throw: param-1.
#io-error throw: param-1 with: param-2.
#brain-damage throw: param-1 with: param-2 with: param-3.

Variations of this method exist to support up to ten parameters.

Extending and Embedding

Not supported yet.


This document was generated on 2 January 2000 using the texi2html translator version 1.51a.