Rebol Programming/Language Features/Types

Datatypes edit

Generally datatypes are sets of values and some operations that can be performed with the values. The main purpose of knowing a datatype of a value is to know the operations we can perform with the value.

Dynamic typing edit

The following code is legal in Rebol:

>> x: 1
== 1
>> x: "2"
== "2"

This property can be described by saying, that Rebol is a dynamically typed language. Some Rebol users describe it by saying, that datatypes are associated with Rebol values, not with variables.

Type safety edit

The following code is illegal in Rebol:

>> x: 1 + "2"
** Script Error: Cannot use add on string! value
** Near: x: 1 + "2"

This is called type safety and is caused by the fact, that neither the integer value 1 nor the string "2" is automatically converted when the expression is evaluated.

Rich set of datatypes edit

Rebol has 45 basic datatypes to handle real world concepts like URLs, email addresses, telephone numbers, currency amounts. By stigmatizing each value with a value type, Rebol restricts the kinds of things that a program can do to values.

The richness facilitates the readability of Rebol scripts as well as block parsing as described elsewhere.

With the money! datatype, it is easy to do some basic accounting

>> AU$1.00 + AU$0.50
== AU$1.50

Rebol even ensures that we keep to the same currency

>> AU$1.00 + US$0.02
** Script Error: AU$1.00 not same denomination as US$0.02
** Near: AU$1.00 + US$0.02

Date calculations are as simple as

>> now - 1-Jan-2005
== 251

where now happens to be today's date of 9-Sep-2005.

Datatypes are also how we can specify that functions only take certain values. A function that expects to deal with files does not want to see an email! type of input.

print-file: func [
    file [file!]
][
    print read file
]
>> print-file support@wikibooks.org
** Script Error: print-file expected file argument of type: file
** Near: print-file support@wikibooks.org

The datatype safety means that Rebol protects us from mixing different types which might cause unexpected errors. However, we can specify that a function be polymorphic i.e. is able to accept more than one basic datatype for its argument.

type? is an example of a polymorphic function in that it will accept an argument of any datatype and yield its datatype as a result.

>> type? http://www.rebol.com
== url!

Rebol datatypes can be divided to two groups: virtual datatypes and basic datatypes. Virtual datatypes are datatypes that serve as common "ancestors" for groups of basic datatypes.

Virtual datatypes edit

Type name Groups
any-block! block! path! set-path! lit-path! paren!
any-function! function! native! action! op! routine!
any-string! string! file! email! url! tag! binary! issue!
any-type! all types
any-word! word! set-word! get-word! refinement!
number! integer! decimal!
series! any-block! any-string! list!

Basic datatypes edit

Type name Examples
action! [n 1]
binary! #{7265626F6C}
64#{cmVib2w=}
bitset! #[bitset! #{00}]
block! [r e b o l]
char! #"r"[n 2]
datatype! #[datatype! none!]
date! 24-may-2005
30/Nov/2005
2008-11-30[n 3]
2008/Nov/30
30-Nov-2005/10:30-7:00
decimal! 1e-15
1.5[n 4]
1,5
-1e6
email! mail@rebol.com[n 5]
error!
event!
file! %rebol.exe
%/media/cdrom/file
%another%20file
%"file too"
function!
get-word! :rebol
hash!
image!
integer! 17
issue! #158
#rebol
library! [n 1]
list!
lit-path! 'rebol/words/type?
lit-word! 'rebol
logic! #[true]
#[false]
money! $2.50
US$4.75
DKK$37.75
-EUR$10
native! [n 1]
none! #[none]
object!
op! [n 1]
pair! 100x200
-1x-2
paren! ()
path! rebol/words/print
port!
refinement! /case
routine! [n 1]
set-path! rebol/words/x:
set-word! rebol:
string! "Rebol"[n 2]
struct! #[struct! [] []]
symbol!
tag! <html>
time! 12:45:22
tuple! 120.80.45
40.35.12.50
unset! #[unset!]
url! http://www.rebol.com
ftp://www.rebol.com[n 6]
word! rebol
word?
a+b
word!

Notes edit

  1. a b c d e The datatype does not have a literal representation
  2. a b Rebol supports caret notation
  3. Rebol supports ISO 8601
  4. Rebol decimals are 64-bit IEEE-754 binary floating point numbers
  5. Rebol supports RFC 5322
  6. Rebol supports RFC 3986

Type conversion edit

As stated above, there is no implicit type conversion in Rebol, i.e. when we want to convert a value to a specific datatype, we have to do it explicitly and the conversion needs to be possible. This is how to convert a string to an integer:

>> to integer! "145"
== 145

This rule seems to be contradicted by working code such as:

>> 1 + 2.0
== 3.0

which must have converted the integer 1 to a decimal before adding it to the decimal 2.0. However, the arguments are not converted by the Rebol interpreter before they get to the + operator. It is the + operator which is able to accept and convert that particular combination of types (integer and decimal) before doing its work and returning the result.

Generally the to function is the first function to consider when we are doing a type conversion. The type argument of the to function may be an example value instead of a datatype:

>> to 1 "145"
== 145