[REBOL] Problem with try [ open/direct/binary tcp://... ] Re:(2)
From: rebol:techscribe at: 4-Oct-2000 2:00
Hi Eric,
you point out that INSERT (and APPEND and JOIN) appear to use FORM to convert
values contained in blocks, whereas they use TO STRING! to convert values which
are not contained in blocks.
If you observe how TO STRING! processes values contained in blocks, you will
find that TO STRING! itself acts no different from FORM with respect to blocks.
If the functions you inspect use nothing but TO STRING! to convert values
(string! or block! values), then the results will be exactly the ones you
observed. Some of your results are unexpected because REBOL does not use a
symmetrical conversion model. The question is, is that good?
[KGD03011--nifty--ne--jp] wrote:
> It seems that INSERT uses FORM to convert values contained in blocks before
> inserting them, and TO STRING! to convert values which aren't contained in
> blocks. Most of the time the results of TO STRING! and FORM are the same, but
> there are several differences.
>
[snipped examples displaying similarities and differences between FORM and TO
STRING!]
> These differences correspond exactly to the behavior of INSERT, APPEND and
> JOIN:
>
> >> append "" to binary! "binary"
> == "binary"
>> to string! to binary! "binary"
== "binary"
> >> append "" reduce [to binary! "binary"]
> == "#{62696E617279}"
Here you conclude that REBOL appears to be using FORM instead of TO STRING!,
because a block is being converted. However, TO STRING! does the exact same
thing:
>> to string! reduce [to binary! "binary"]
== "#{62696E617279}"
> >> append "" first [abc/def/ghi]
> == "abcdefghi"
>> to string! first [abc/def/ghi]
== "abcdefghi"
> >> append "" [abc/def/ghi]
> == "abc/def/ghi"
Again you note the similarity to using FORM. However, TO STRING! acts no
different:
>> to string! [abc/def/ghi]
== "abc/def/ghi"
> >> append "" ["abc" "def" "ghi"]
> == "abcdefghi"
>> to string! ["abc" "def" "ghi"]
== "abcdefghi"
> >> append "" [["abc" "def" "ghi"]]
> == "abc def ghi"
>> to string! [["abc" "def" "ghi"]]
== "abc def ghi"
In all cases TO STRING! behaves as FORM would with respect to blocks.
Nevertheless the results are surprising in some instances. That is because one
would expect that REBOL uses a SYMMETRICAL CONVERSION model, which it doesn't.
What I mean is:
A SYMMETRICAL CONVERSION MODEL in REBOL would look something like this:
1. In REBOL data always occurs in association with a datatype. The combination
of data with a datatype is a value.
2. CONVERSION means disassociating some data from its current datatype and
associating it with a different datatype, while leaving the data unmodified. Its
value representation changes because it is now associated with a different
datatype.
3. CONVERSION INTEGRITY means that converting a value to a different datatype
and back to the original datatype must result in the same value it originally
had. The reason is that the data was not modified during the conversion.
REBOL does not follow this symmetrical conversion model. REBOL's conversion does
not maintain CONVERSION INTEGRITY. REBOL's CONVERSION implementation is not
always symmetrical. This means that in some instances REBOL does not limit
itself to modifying the datatype associated with the data that is being
converted, instead, the data itself is modified as well.
Some of the examples you show show REBOL supporting symmetrical conversion. For
instance
>> binary-block: reduce [to binary! "binary"]
== [#{62696E617279}]
>> to string! binary-block
#{62696E617279}
and
>> to block! to string! binary-block
== [#{62696E617279}]
The final result of converting the string representation of the data contained
in the block binary-block is a block containing the same data. That is
appropriate.
5. I think it is reasonable to expect that REBOL's conversion routines maintain
CONVERSION INTEGRITY. Unfortunately that is not true. Examples:
>> to string! ["abc" "def" "ghi"]
SHOULD RETURN
~~ {"abc" "def" "ghi"}
INSTEAD IT RETURNS
== "abc def ghi"
Therefore
>> to block! to string! ["abc" "def" "ghi"]
results in
== [abc def ghi]
i.e. a block of words, whereas CONVERSION INTEGRITY would require it to return
== ["abc" "def" "ghi"]
a block containing strings, which was what the original block contained.
Another example is
>> to block! to string! [["abc" "def" "ghi"]]
which returns
== [abc def ghi]
Under a symmetrical model this should result in
== [["abc" "def" "ghi"]]
What happens is that during the string conversion [["abc" "def" "ghi"]] was
converted to "abc def ghi", whereas following a symmetrical model it should have
been converted to
{["abc" "def" "ghi"]}. Only the outer block should have been replaced by a
string. Instead the element of the outer block (a block containing three
strings) was stripped, and in addition the three strings contained in the block
were converted to character sequences. Additional space characters were
inserted, separating the character sequences that were originally strings.
Is REBOL's current implementation of ASYMMETRICAL CONVERSION, i.e. a conversion
that permits the modification of the data and does not limit itself to modifying
the representation of the data by associating the data with a different
datatype, more useful - albeit occasionally surprising - than a symmetrical
conversion would be?