Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Introduction: REBOL datatype!
Index -> Programming, General Programming -> Functional Programming
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
btiffin




PostPosted: Tue Apr 08, 2008 2:09 am   Post subject: Introduction: REBOL datatype!

An introduction to REBOL datatypes

By Brian Tiffin
April 2008
By the way ... the designer pronounces REBOL as rebel.

datatype!

REBOL, the Relative Expression Based Object Language has many features. One of the key elements of this scripting language are the datatypes.

REBOL is a datatype rich environment with more than 50 types. Lexically, type names end with an exclamation mark. Lexically is common rebol speak to describe the text source code scanner which includes make, load and evaluate steps as it determines datatype. The datatype names end in !, but there is a fairly complex lexical scanner built into the REBOL interpreter, such that all values can be typed and read from source. From the 2.7.6 release;
code:
>> help "!"
Found these words:
   action!         datatype! action!
   any-block!      datatype! any-block!
   any-function!   datatype! any-function!
   any-string!     datatype! any-string!
   any-type!       datatype! any-type!
   any-word!       datatype! any-word!
   binary!         datatype! binary!
   bitset!         datatype! bitset!
   block!          datatype! block!
   char!           datatype! char!
   datatype!       datatype! datatype!
   date!           datatype! date!
   decimal!        datatype! decimal!
   email!          datatype! email!
   error!          datatype! error!
   event!          datatype! event!
   file!           datatype! file!
   function!       datatype! function!
   get-word!       datatype! get-word!
   hash!           datatype! hash!
   image!          datatype! image!
   integer!        datatype! integer!
   issue!          datatype! issue!
   library!        datatype! library!
   list!           datatype! list!
   lit-path!       datatype! lit-path!
   lit-word!       datatype! lit-word!
   logic!          datatype! logic!
   money!          datatype! money!
   native!         datatype! native!
   none!           datatype! none!
   number!         datatype! number!
   object!         datatype! object!
   op!             datatype! op!
   pair!           datatype! pair!
   paren!          datatype! paren!
   path!           datatype! path!
   port!           datatype! port!
   refinement!     datatype! refinement!
   routine!        datatype! routine!
   series!         datatype! series!
   set-path!       datatype! set-path!
   set-word!       datatype! set-word!
   string!         datatype! string!
   struct!         datatype! struct!
   symbol!         datatype! symbol!
   tag!            datatype! tag!
   time!           datatype! time!
   tuple!          datatype! tuple!
   unset!          datatype! unset!
   url!            datatype! url!
   word!           datatype! word!


Each of these types have lexical conventions. Far more than I can describe here, but a quick overivew can be found in the Values Quick Tour

For example:

integer! optional +/- and one or more digits from 0 to 7 just kidding, REBOL is base 10, not octal -987654321
email! triggered by at symbol, btiffin@hisplace.moc
money! triggered by $ and can include country info $123.45 or CDN$123.45
tuple! two or more (up to 10) decimal points separating small integers 255.0.255 (good for colors), 128.0.0.1 (good for ip addresses), 1.2.3.4.5
tag! triggered by values surrounded by less than and greater than symbols
file! triggered by percent %file.txt This can take some getting used to, the percent in front of filenames, but it is all in support of REBOL being able to provide the plethora of rich datatypes
block! triggered by opening and closing square brackets. A mainstay REBOL datatype allowing the code is data and data is code paradigm
date! Lots of input format options, but I prefer the 7-Apr-2008 form.

See the Values Appendix
for details.

Scalar
Among those datatypes there are scalars and series.

number! which includes decimal! and integer! are scalar types and react as you would expect. char! is also scalar as is word! and a few others.

Series
Most other REBOL data can be accessed using ordinal and series functions. The series concepts cover strings, ports, images, hash, functions and many other REBOL data types. Series accessors also provide REBOL with its reflective properties. function! specs, source and documentation can be accessed with first, second and third actions.

head or tail
All series have a head and a tail. Series can be referenced or values retrieved. Reference actions include, but are not limited to, head, tail, next, back, at and skip.

values
The actions first, second through ninth retrieve values as well as pick, special path notations and others.

operations
Series can also be copied, transformed, changed, scanned, sorted, reversed, to name but a few of the available operations.

This isn't your father's scripting language
The importance of series! may not be immediately obvious. A developer can happily program useful REBOL scripts without ever realizing how this feature can be exploited. It takes a little rethinking if you have experience with other programming languages.

Datatype example that shows make, load and reduction
code:
rebol []
;; the alphabet as a string!
alphabet: "abcdefghijklmnopqrstuvwxyz"
;; a block! of data with integer! binary! (in base 2) lit-word! string! money!
;;   binary! (in base 16) issue! char! decimal!
;;   and an expression that will be loaded as word! integer! integer!
;;   but will reduce to a decimal!
data: [1 2#{00000010} 'three "four" $5 #{06} #7 #"^(08)" 9.0 divide 100 10]

probe data
print length? data

probe reduce data
print length? reduce data

print copy/part alphabet 10

words: [vista linux osx]
probe words
probe reduce words
>> do %example1.r
[1 #{02} 'three "four" $5.00 #{06} #7 #"^H" 9.0 divide 100 10]
12
[1 #{02} three "four" $5.00 #{06} #7 #"^H" 9.0 10]
10
abcdefghij
[vista linux osx]
** Script Error: vista has no value
** Near: vista linux osx
>>


REBOL uses the set-word! datatype to set values to words. You can think of it as assignment. set-words end in colon, so alphabet: "abcdefghij..." sets the word alphabet to the next value processed, which is the quoted string! of letters.

Then data: is used to set the word data to a block!. Now a tricky business comes up. Data is code and code is data (that is code (that is data)).

REBOL scans this and creates block! of unevaluated information. The text source has been scanned and typed, but not yet evaluated. The probe statements (a helper word that displays REBOL data) and the prints of the length of the block, look like
code:

[1 #{02} 'three "four" $5.00 #{06} #7 #"^H" 9.0 divide 100 10]
12
[1 #{02} three "four" $5.00 #{06} #7 #"^H" 9.0 10]
10
and that came from
code:
data: [1 2#{00000010} 'three "four" $5 #{06} #7 #"^(08)" 9.0 divide 100 10]
The first probe, shows the loaded values with a length of 12. The divide 100 10 part is three values.

The second probe shows the block! after evaluation, in this case the simplest form of evaluation, reduce. There are other forms such as do, but reduce is all we need to evaluate divide 100 10 as a REBOL expression returning 100 divided by 10 giving 10.0.

Most of the other values are evaluated as the values themselves as they are already reduced.

All except the 'three, a lit-word! that reduces to the word! three, and this is where my description is getting more complicated than it needs to be, but it has to do with word! and lit-word! (or literal word).

divide is in the data block as a word! and when reduced, is found to be the name of a REBOL action which takes two parameters. It then takes the 100 and 10 as arguments and returns the result, 10.0. The reduced block! has 10 elements. Note: notice how the source for 8 #"^(08)" was probed as #"^H" as thats what REBOL uses for output of ascii 8, backspace. It represents Ctrl-H.

Data in block! not evaluated
When interpreting, REBOL does not evaluate data in blocks until told to. It is scanned, typed, made and loaded, but not evaluated.

Copy part of a string!
The next step is a basic series operation; copy in this case with a /part refinement limiting the copy to 10 characters. So the first 10 letters are printed.

Evaluating unset! causes error!
Then the words: set-word! is followed by a block! of three word! items. These words have not be set to any value yet, they are just words. Evaluation of these words will fail. So vista has no value as the script fails to reduce the block!.

This is where lit-word! and word! come from. 'three is a lit-word!, it reduces to the word! three. three, if reduced (evaluated) would fail (as it has no value until it is set).

Math
One thing about REBOL is that it evaluates expressions from left to right, but uses the arity of functions to determine what value are passed as arguments to build up results that may be used as arguments, etc as it parses the source input. Arithmatic expressions have no precedent or priority in REBOL. The data block above could ended with divide 100 add 5 5 or 100 / 5 + 5 but the expression 100 / 5 + 5 is scanned as 100 divided by 5 plus 5. Parenthesis which actually create a paren! datatype - but that's advanced and you won't even notice can be used so data could have ended with 100 / (5 + 5) and still returned 10.0. I grew up using polyFORTH so I rarely use the algebraic symbols and prefer the action words add, subtract to +, -.

Objects
REBOL uses a prototype base for objects. REBOL can not be called Object Oriented but does have object!.
code:
rebol []
;; define an object with x y positions (a pair! datatype) and a speed
;;   again as a pair!  represents delta x, delta y
moving: make object! [
    start: end: speed: 0x0
    nozero: func [top bot] [any [all [zero? bot 1] top / bot]]
    move: does [start: add start multiply abs nozero
        subtract end/y start/y subtract end/x start/x
        multiply speed to pair!
          reduce [sign? subtract end/x start/x  sign? subtract end/y start/y]
    ]
]
bullet: make moving [start: 123x140 end: 245x30 speed: 3x3 name: "your"]
help bullet
loop 4 [bullet/move print bullet/start]
BULLET is an object of value:
start pair! 123x140
end pair! 245x30
speed pair! 3x3
nozero function! [top bot]
move function! []
name string! "your"

125x138
127x136
129x134
131x132
>>

The object moving has no parent prototype, so it uses the REBOL object! type. The bullet is prototyped using moving, sets start, end and speed and adds a field called name, and sets the value to "your". The print shows the first four movements of the bullet from 123x140 on the screen to 245x30. You'll have to excuse me if that code isn't calculating the path properly. I only tested it once (for four whole values even) and I haven't written any games in 20 years.

There is way, way more
Please visit rebol.com for details. REBOL has over 50 datatypes and each can assist is making solutions shorter, more concise and many times, a little more human. This introduction has barley scratched the surface.

By the way, if you are a vista fan; get a copy of REBOL and then type in linux at the >> prompt. You'll get to see your machine error out with linux has no value. It's ok, REBOL runs on Window, Mac, and my favourite, GNU/Linux (I'm a Debian) so I know the value I get out of an OS and can handle friendly trash talk Smile

Cheers
Brian
Sponsor
Sponsor
Sponsor
sponsor
Display posts from previous:   
   Index -> Programming, General Programming -> Functional Programming
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 1 Posts ]
Jump to:   


Style:  
Search: