*Unset*

Allow me to be a little bit philosophical here. You feel, that the
initialization is bad, because:

[G]
> There's difference between an uninitialized word and one
> initialized to none; with this solution, the interpreter would
no
> more be able to catch typos and a lot of bugs could remain
> unnoticed causing strange and unpredictable effects.
>
[/G]

I do agree with you. The problem is, that the difference between
words initialized to None, Unset or any other legal value is
small. You see some difference just because you see, that Unset is
a "second class" Rebol value as opposed to None, which is "first
class". But, that introduces another bad thing to Rebol. A code
like:

    a: first block

doesn't work for all nonempty blocks, only for blocks containing
"first class" Rebol values. For the code to be exception proof
(sometimes you must process all possible cases), one must write:

    error? set/any 'a first block

This code is working for "any class" values, but it has got its
price: we lost the simplicity of the former expression and, at the
same time, we lost the typo protection.

The problems we have seen above are caused by the fact, that we
wanted to retain the initialization property and at the same time
retain the typo protection available for uninitialized words. The
present solution is a compromise. We surely retained the benefits
of initialization (you can get the value of any word) , the price
is a loss of simplicity. The typo protection is only an illusion
in some cases. At the same time we introduced the "second class"
values that cannot be handled as "first class". That introduces
another kind of bugs - code can be "almost" correct - ie. work
with some exceptions (a tricky thing).

The possible alternatives:

1) Use initialized words and have no exception to the rule, that
we can get the value of any word. In this case the simplicity
wins. Example:

    reduce [:word]

We may miss some typo protection.

2) Use uninitialized words. In this case we lose simplicity
partially - sometimes we must write:

    either value? 'word [
        reduce [:word]
    ] [
        copy []
    ]

We retain the maximum available typo protection, but look out! If
we use:

    wordval: func [word [word!]] [
        either value? 'word [
            reduce [:word]
        ] [
            copy []
        ]
    ]

, than the expressions of type:

    wordval 'word

are not typo protected.

3) The current Rebol solution is closer to 1) than 2) I think, but
we lost simplicity:

    head insert/only copy [] get/any 'word

and retained some typo protection. OTOH we have got a new kind of
bugs not existing in the case 1).

*Armed errors:*

> > Moreover, you cannot legally get error as a result of a
> > computation as in
> >
> >     error? err: do block
>

[G]
> Which is not too bad, why should you produce an error as result
of
> a computation (if it is NOT really an error that should fire)?
>
> If it is an ERROR!, it is an error ! :-)
>
> I don't think being able to return errors would be useful in
real
> code.
[/G]

Well, that is one side of reasoning. The other one is, that our
code should be able to process values. As long as errors are
armed, they are only "second class" values that cannot be handled
with normal code without too much complication. OTOH, disarmed
Error can be handled with usual code. If we introduce "second
class" values, we may introduce complications too. I am pretty
sure, that even the Rebol interpreter could be simpler and faster
without the "second class" values.

    Ladislav

Reply via email to