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>] rebol2>> rejoin ["a" if false ["b"] "c"] == "anonec"
You had to throw in an EITHER with an empty branch:
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.
This tension spawned a new philosophy based around a NULL state...which had no datatype and could never be put in blocks. This state was then used to uniquely represent the failure of a conditional (while successful conditionals evaluating to null incidentally were "voidified"):
>> compose [<a> (if false [<b>]) <c>] == [<a> <c>] >> unspaced ["a" if false ["b"] "c"] == "ac"
I don't want to belabor how it's implemented too much (even though I'm 99.99% settled with NULL as the right answer, and correct result for all failed conditionals). But I don't think it should be harder than this. so no opt if condition [...] or other markings.
If some brilliant replacement plan eliminated the idea of failed conditional returning something other than the absence of a value, then those would just have to dissolve in COMPOSE unless you use COMPOSE/ONLY or something. But I'm not holding my breath. NULL is the ticket, here.
Novices using Rebol2 or Red aren't really clear on how their RETURN works. (Or doesn't work, as the case my be.) RETURN climbs the stack until it finds a function that is willing to accept returns.
- Functions in Rebol2/Red that won't accept returns: IF, WHILE, or pretty much any native
- Functions in Rebol2/Red that will accept returns: any user FUNC you write
To give a brutally simple example, you cannot implement UNLESS in terms of IF:
rebol2>> foo: func [x] [if not x = 10 [return "not 10"] return "it's 10!"] rebol2>> foo 20 == "not 10" rebol2>> unless: func [cond block] [if not cond block] rebol2>> bar: func [x] [unless x = 10 [return "not 10"] return "it's 10!"] rebol2>> bar 20 == "it's 10" ; D'oh
That UNLESS, because it's a FUNC and not a native, is a candidate for receiving RETURN. So the UNLESS itself returned "not 10" instead of returning from bar. Execution continued and the `return "it's 10!" ran. I maintain that correct behavior constitutes another must-have, and I was by no means alone in this, nor the first to say so.
>> unless: function [cond block] [if not cond (block)] ; see note re: group! >> bar: function [x] [unless x = 10 [return "not 10"] return "it's 10!"] >> bar 20 == "not 10"
I do not consider annotating UNLESS to say "I'm the kind of thing that doesn't catch returns" to be remotely acceptable. I'd sooner throw out the project than go that route. Addressing definitional returns wasn't at all trivial...even though conceptually it was understood what needed to be done. It was one of the first things I tried to do in open-sourced R3-Alpha. The rearranging I had to do in order to understand the code well enough to accomplish it laid the groundwork for many features to come.
So this belongs in the non-negotiable list.
(Note: The reason you have to put a group! around
block (or say
:block) is due to soft-quoted branching, and I argue for the tradeoff here. I would not consider that one of my non-negotiable points for this list, though I've offered what I believe to be some compelling arguments. I do--however--consider FUNCTION instead of FUNC to be a non-negotiable way of writing this, with current leaning that FUNC is a full synonym for FUNCTION)
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.