REBOL3 tracker
  0.9.12 beta
Ticket #0002073 User: anonymous

Project:



rss
TypeBug Statussubmitted Date3-Oct-2013 02:32
Versionr3 master CategoryUnspecified Submitted byfork
PlatformAll Severityminor Prioritynormal

Summary Simplify TO STRING! and complex construct via MAKE STRING!
Description This is a follow-on to the general philosophy put forth in #2056.

For starters TO STRING! QUOTE FOO: should just return "FOO" and not "FOO:" ... if you want the colon, that should come from requesting a MOLD or similar. All words should not include their word specifier when converted to strings.

Another issue is regarding the current somewhat ill-defined behavior of TO STRING! for block types. At the moment it goes through FORM, resulting in some odd behavior like:

>> to string! [(a b) [c d] e/f g h]
== "abcde/fgh"

It is fundamentally taking a wider type (a block hierarchy) and flatting it into a narrower type (a linear series of unicode codepoints). This is more the spirit of "projection" than conversion, and is irreversable. FORM and other string flattening functions are available for those who want this.

A cleaner and simpler way for TO to behave, more in the spirit of safe "conversion" rather than "flattening", comes from only accepting blocks with one non-any-block! element. If it behaves as if it had been passed the solo element in that block, then when combined with #2056 an interesting invariant of reversibility in converting a string to a block and back emerges.

The ultimate goal of all of this is a flexible and trustable system for conversions, within the range of what is possible, e.g.

>> to integer! to string! to block! to integer! "10"
== 10

Which will happen if this is implemented across the board for the rest of the types, whose conversions are already more simply understood.
Example code
;;
;; Current behavior
;;

>> to set-word! to string! to set-word! "foo"
*** ERROR
** Syntax error: invalid character in: "foo:"
** Where: to
** Near: to set-word! to string! to set-word! "foo"

>> to string! [(a b) [c d] e/f g h]
== "abcde/fgh"

>> to string! to block! "abc def"
== "abc def"

;; 
;; Desired behavior
;; 

>> to set-word! to string! to set-word! "foo"
== foo:

>> to string! [(a b) [c d] e/f g h]
** Script error: invalid argument: [(a b) [c d] e/f g h]
** Where: to
** Near: to string! [(a b) [c d] e/f g h]

>> to string! to block! "abc def"
== "abc def" ;-- unchanged, thanks to invariant

Assigned ton/a Fixed in- Last Update7-Oct-2013 22:45


Comments
(0004054)
adrians
7-Oct-2013 20:47

I'd go with the proposed behaviour, but one thing should be kept in mind. Most people coming from other languages probably have the expectation that any type (even complex types) has a built-in stringified representation (usually a type name concatenated with a hash, if not overridden) and that it is usually called toString or something similar. Rebol docs should make it clear that 'form or 'mold is the equivalent.
(0004057)
maxim
7-Oct-2013 21:15

one thing which historically complicated matters was the issue of binding. I don't know how it's managed in R3, but in R2, to block! was one of few ways to get unbound words when converting strings into loaded rebol code:

>> a: 5 print to-block "a"
** Script Error: a word has no context
** Near: a

With the better binding controls we have in R3, this distinction is probably now obsolete, so a different action for to string! should be used.
(0004059)
Gregg
7-Oct-2013 22:24

I agree with the change for words: omit word decorations.

On multi-value blocks, it does not go through FORM as I see it. FORM would include spaces, which is a more natural result to me.

TO is like MAKE, or REJOIN without the REDUCE, which may be worth considering. It doesn't mean you can't work around it, but I'm not sure throwing an error is better.
(0004060)
fork
7-Oct-2013 22:45

@Maxim - MAKE BLOCK! works as before for an unbound block, and is used by LOAD.

So @DocKimbel prefers an error on TO INTEGER! of blocks.

I argued that we have built a correspondence of there being a block which a TO conversion has said is unique among all blocks as the one that you get from an integer conversion. (e.g. TO BLOCK! 10 => [10], and not TO BLOCK! 10 == [5 + 5] or TO BLOCK! 10 == [x x x x x x x x x x]) The symmetry offered by this allows the reverse conversion.

He doesn't feel there's a problem with TO BLOCK! 10 == [10] and TO INTEGER! [10] being an error. He voiced that he would rather see TO BLOCK! 10 be an error and a separate BLOCKIFY primitive added, than see TO INTEGER! [10] be 10.

I'd prefer things be symmetrical, myself. So I'd vote for "error on both conversions and add blockify", or "allow both conversions".

Date User Field Action Change
8-Oct-2013 00:21 fork Comment : 0004060 Modified -
7-Oct-2013 22:45 fork Comment : 0004060 Added -
7-Oct-2013 22:24 Gregg Comment : 0004059 Added -
7-Oct-2013 21:15 maxim Comment : 0004057 Added -
7-Oct-2013 20:47 adrians Comment : 0004054 Added -
3-Oct-2013 03:28 fork Description Modified -
3-Oct-2013 03:28 fork Code Modified -
3-Oct-2013 02:32 fork Ticket Added -