When learning Rebol, one of the first thing you would learn is how to store a number or a string in a “variable” like this:
>> a: 5
== 5
>> b: "abc"
== "abc"
>>
I put the term variable between quotes because ‘a and ‘b are not exactly equivalent to variables in the same sense as in any other traditional languages. Let’s foresee why:
>> v: 1
== 1
>> type? v
== integer!
>> v: "abc"
== "abc"
>> type? v
== string!
>>
The same types as if you executed:
>> type? 1
== integer!
>> type? "abc"
== string!
Indeed the type? function does first evaluate v to get its value before returning the type: it does not return the type of ‘v itself. I just purposedly put ‘ before v as I want to refer to the v container or symbol or word and not the content of v. In Rebol ‘v has a type which is:
>> type? 'v
== word!
Whatever a symbol or word contains, their type returned by the type? function is invariant:
>> type? 'a
== word!
>> type? 'b
== word!
>>
So you can store value of any type in a word whereas in a traditional language, you would first declare the type of a variable and once the type has been fixed this way, you can only store a value of that type, if not you would generate a compile or at least a run-time error. Also words can be easily passed as values to functions. For example if you want to swap ‘a and ‘b contents you can do it like this:
swap: func [a b] [
temp: get a
set a get b
set b temp
]
swap 'a 'b
Test:
>> a: 1
== 1
>> b: 2
== 2
>> swap 'a 'b
== 1
>> a
== 2
>> b
== 1
You can even store a word in another one:
>> v: 1
== 1
>> w: 'v
== v
For sure w contains v:
>> w
== v
What if the value of v changes, can I get its value through w ? Yes by using the get function:
>> v: 5
== 5
>> get w
== 5
>> v: v + 1
== 6
>> get w
== 6
Conversely you can set the value of v through w:
>> set w 10
== 10
>> v
== 10
You can logically chain several indirections:
>> x: 'w
== w
>> get get x
== 10
What happens when you now point w towards z which contains no value:
>> w: 'z
== z
>> get get x
** Script Error: z has no value
** Near: get get x
No value can be detected with the value? function
>> value? 'z
== false
Since
>> w
== z
this is equivalent to:
>> value? w
== false
and since
>> get x
== z
this is also equivalent to:
>> value? get x
== false
Let’s see how we can use this in a function:
f: func[v][probe type? v]
f works fine with v (which contains 10):
>> f v
integer!
But fails with z as z has no value and as such cannot be evaluated by the interpreter before being passed to f:
>> f z
** Script Error: z has no value
** Near: f z
It fails with z even if f does nothing:
>> f: func[v][]
>> F Z
** Script Error: Z has no value
** Near: F Z
We need to test that z has a value before passing it as a parameter like this (we’ll use rebol to-word function to convert “v” or “z” to ‘v or ‘z):
w: to-word ask "v=10 or z (no value): " if/else (value? w) [
f get w
][
print [w "has no value!"]
]
If we answer “v” f will execute successfully and returns the type of v:
v=10 or z (no value): v
integer!
== integer!
If we answer “z” f cannot be executed successfully so we print the warning message:
v=10 or z (no value): z
z has no value!
For the user that’s fine, but for the developer, that’s not really because if f is a highly used library function in his applications, he will have the hassle to not forget to check this no value every time! And if this library was so successfull as to be used by thousands of developers around the Galaxy, how many lifes would have to endure that process ? So the best is to do the checking once in the library function f itself.
The problem we encountered was how to pass z to f without Rebol evaluating it ?
So Let’s try this:
f: func[w [word!]][probe type? get w]
Unfortunately that doesn’t work:
>> f z
** Script Error: z has no value
** Near: f z
Let’s try rather (remembering what we used for defining scala val keyword equivalence):
f: func['w][
probe type? get w
]
It works with v but the console prints an error message:
>> f v
integer!
== integer!
>> f z
** Script Error: z has no value
** Where: f
** Near: probe type? get w
which shows that rebol’s interpreter fails on the probe type? get w instruction which means f did accept z and that’s what we wanted ! So we can treat this error inside the f function with try / disarm rebol functions:
f: func['w][
if error? error: try [
probe type? get w
][
disarm error
print [w "has no value."]
]
]
Addendum: there is a nice function here which can test if a block contains words only:
all-words?: func [
"Returns true if all values in a block are word! values."
block [block!]
] [
parse block [some word!]
]
Test it:
>> all-words? [a b c]
== true
>> all-words? [a "b" c]
== false
For another tutorial see Rebol Guide and Codeconcious Tutorial.

















