Trust the User's Judgment... *When You Can*

In the CONSTRUCT dialect, we allow you to mix and match plain words, and inline assignments.

But if plain words are being picked up as locals there's potential for error if you accidentally wrote an expression that didn't work, like:

func [
    arg [integer!]
    {
       local1 local2
       local3: arity-2-but-I-think-it's-3 a b c
       local4: 10
    }
][
    ...
]

That could wind up making a local c that you didn't intend. But then again, sometimes it would be just a very obvious simple initialization, like local4: 10. Forcing people to use parentheses could do more harm than good, vs. trusting them to use the parentheses if they feel it's warranted.

I realized this kind of dove to the heart of Rebol philosophy:

If you need to evaluate an expression multiple times, it has to be in a List. But if you're doing an evaluation just once, trust the user to formulate the expression and use an array if they deem it necessary.

Most people encounter this first with the difference between IF and WHILE.

Certainly IF could take its condition in a BLOCK!. But it doesn't. You can mess up:

In Rebol2:

block: [a b]
data: [c]

if 3 = length? append block [
   print "Appending data to block gave us 3 elements"
]

stuff: [a b c]

You run the code and you get no output, because you forgot to say append block data. So what did you get instead?

>> block
== [a b
    print "Appending data to block gave us 3 elements"
]

What you thought was a branch got appended. And the branch actually wound up being the block from the next expression (SET-WORD!s evaluate to what they are assigned).

(As it so happens in Ren-C, it catches this...due to soft-quoted branching. Since it quotes its branch slot, it saw a SET-WORD! in the position, and it doesn't allow things like WORD! or SET-WORD! there. If we didn't already have enough reasons to appreciate soft quoted branching, there's one more!)

Should It Have Required a Block For The Condition?

The answer for the Rebol Core is: No. The goal is to trust the user to make that call.

If you think the expression you're writing is too risky to get right, you should use a GROUP! or break it into subexpressions or otherwise rethink your code so it's not risky. Being able to cook up a DSL in ten minutes that solves patterns you find useful is the tool you use when you find yourself making code that's at risk of mistakes.

The answer for You is: Your Choice. If you find you're making lots of mistakes and want to set a policy that IF always takes a BLOCK! condition, suit yourself. IF is yours, just like everything. Redefine it. It's about putting the personal back into personal computing.

Well Then Why Use A BLOCK! For WHILE's Condition?

Because there wasn't another choice.

You can't tell how long an expression is going to be just by looking at it. You have to evaluate it.

The condition in a WHILE needs to be evaluated more than once. So it's taken as a BLOCK!.

This Is One of The "Big Ideas"

Whether you see it as a big idea or just kind of gonzo programming, is up to you.

With the state of software being how it is, I think we need the occasional Flower Sermon.

https://en.wikipedia.org/wiki/Flower_Sermon

Ren-C has thrown in another big tool here, with COMMA!. Giving you yet more choice.

Yet EVAL and PARSE still let you write your streams of consciousness, giving the code a written-English like fluidity, of mostly words and spaces...which we are naturally good at working with.

1 Like

It's that edge of FORTH

Prefix
Infix
Postfix

Rebol Red RenC

all have interesting flow
But it can be confusing to read if you expect syntax like Lisp

Someone somewhere one wrote that Rebol started life as LISP without Parentheses
Then borrowed stuff from Wolfram

I'm no expert
But it did help me understand
Something

I've long wished for nice slide lecture strange Loop that would present Rebol Red RenC in context

Rich Hickey
Douglas Crockford
heads up

1 Like

To some this is a fatal flaw, e.g. Joe Marshall:

https://rebol.metaeducation.com/t/the-sherman-rebol-to-scheme-compiler/2076

[Not using parentheses] turns out to be a bad idea. Not only does it greatly complicate the interpreter and compiler, it turns out to be rather unreadable in practice. As an example, here is a line from the REBOL BBS tutorial:

update-topic topic-id length? msgs first last msgs

Certainly REBOL knows how many arguments each function takes (and which of those identifiers refer to functions), but if you don't know, you can't parse it.

But as Flon's Law goes:

"There is not now, and never will be, a language in which it is the least bit difficult to write bad programs."

I'm not surprised that someone who hasn't seen good Rebol code wouldn't get it.

That day is coming. But there were just too many open questions in Rebol to really teach/evangelize it outside of the little group of self-selected monks... (I don't think it's just me who has been somewhat intentionally low-profile about it.)