The Canonical List of Non-Negotiables

I realized this is something that maybe hasn't been attempted, but would be very useful. That is a list of concrete code samples where if Rebol won't run that code looking that way, then it is dead to you.

I'd imagine it's easier to say things like "it's dead to me if it requires me to install Java". But there must be something other than the meta-properties of the language which people consider foundational? Actual code--looking and acting an actual way?

I'm not looking for controversial things here--rather things generally agreed on as good. But naming some of them out loud might have benefit. I'll start.

COMPOSE, UNSPACED, ETC. VAPORIZING CONDITIONALS

The lack of conditional vaporization bugged me to no end about Rebol2:

rebol2>> compose [<a> (if false [<b>]) <c>]
== [<a> none <c>]  ; actually NONE! #[none], poorly rendered as WORD! `none`

rebol2>> rejoin ["a" if false ["b"] "c"]
== "anonec"

You had to throw in an EITHER with an empty branch, to get an UNSET!.

rebol2>> compose [<a> (either false [<b>] []) <c>]
== [<a> <c>]

rebol2>> rejoin ["a" either false ["b"] [] "c"]
== "ac"

So I advocated vaporizing NONE! by default for a while...facing resistance from those wanting to use them as placeholders in blocks, adamant that NONE! was a value.

Hence the idea was moved around to being more like a failed conditional would return an UNSET!. But because UNSET! was "a value", it could legitimately be put into blocks.

Hence Ren-C rethought the playing field to have "non-valued" states...like NULL (which raised errors when you try to put in blocks, but could assign to a variable) and the VOID state (which would be a no-op when appended to blocks).

So failed conditionals were re-tuned to return VOID:

>> compose [<a> (if false [<b>]) <c>]
== [<a> <c>]

>> unspaced ["a" if false ["b"] "c"]
== "ac"

Since NULL state was an error in these situations, you can't go directly from a NULL variable to a vanishing slot without something that turns it into VOID. The construct that does so is called MAYBE.

>> var: null
== ~null~  ; isotope

>> compose [<a> (var) <c>]
** Error: need non-~null~ isotope value in COMPOSE slot

>> compose [<a> (maybe var) <c>]
== [<a> <c>]

DEFINITIONAL RETURNS

Definitely non-negotiable!

...and...

That's only two off the top of my head. But my idea was that we can keep adding posts to this thread whenever someone thinks of something. What has to work else it's "dead to you"? @IngoHohmann, @rgchris, @gchiu, @Mark-hi, @BlackAttr... ?

Like I say: please avoid functionality concepts like "has to talk to ODBC"...unless you have a very specific code sample that looks exactly right for how it needs to look for some case.

3 Likes

I don't have any non-negotiables at this stage of things. In the R2 past I've had minor annoyances, and I'm sure as I use Ren-C there will be things that I wish were more simple or compact.

2 posts were merged into an existing topic: The R3C Branch ("Chris's Rebol" or "Rebol 3 Conservative")

ATOMICITY OF ELEMENTS IN BLOCK!s AND GROUP!s

A new non-negotiable for Ren-C is that for any BLOCK! (or blocklike thing) the following property holds:

block2: copy []

for-each item block1 [append block2 item]

assert [block1 = block2]

Prior to isotopes, it wasn't conceivable that such rules could hold. But after years scaling a mountain of design... I concluded this could be achieved, if all the tricky behaviors came from values "at quoting level -1" that could not be put into blocks.

  • There are no isotopic actions to implicitly execute; you'd get an error trying to put them in the block.

  • There are no blocks/groups/paths that will splice into the target, because splicing requires an explicit conversion to an isotope.

  • There are no "unsets" to trip on that you can find in a block, because the state conveying "unsetness" (trash) is an isotope.

2 Likes