Don't Fear The WORD!

Something Rebol touts as a big advantage is that it hasn't pinned a meaning to any words, so you can use them to mean what you want.

But I frequently have stressed over this, because words have associated costs that are non-trivial.

Example: The Section Divider: ===

I thought it would be neat if we could use this to have a Markdown-Like split of headers which just used plain words:

all [

    step1 arg1


    step2 arg2
then [
    print "=== is invisible, so it doesn't interfere with things like ALL!"

The idea is that it could be hooked in ways a comment couldn' print out messages to know you've reached the step (for instance).

Because I thought it was more pleasing, I designed it to permit words. === was as a variadic function which would keep looking across its input until it found a === to terminate.

(Note: Wanting to reclaim == for using as an even briefer way of saying "section" is one of several motivators for cleaning up the use of it for equality)

But there are issues that come up from trying to write strings without string delimiters in Redbol.

You have to write LOAD-able syntax. Having COMMA! makes it a bit more tolerable, but you can still get in trouble with unusual uses of other characters.

=== Here's a 3rd example; broken! ===

That's going to not be able to handle 3rd in the current system (though the PACK! proposal could help here). Then the semicolon will wind out commenting stuff out.

Meaning of GROUP! is contentious. I use a lot of parentheses when I write text, and not mean running code. But we presumably want a way to get expressions in there:

That might not be a problem if we limit that to GET-GROUP!.


count-up n 100 [
    === Running Step :(n) ===
    print "This might be a way of doing it?"

Another alternative could be to use blocks for any evaluated portions, since square brackets don't often come up in English writing.

Plenty of Other Questions... I don't want to tackle them all here, because I'd like to move to the big issue.

Biggest Issue: Creating Tons Of Stray Bindings

On the happy side, with LET we are moving into an idea of dynamism in binding so that using a SET-WORD! doesn't get you a local. That keeps this from throwing in a local definition of PARSE:

foo: function [data] [
    === BEGIN PARSE: It would suck if this overwrote PARSE! ===
    parse data [...]  ; if PARSE: was gathered as local, parse would be unset

Things like this are why I was so adamant against locals gathering. It's good that it's gone from standard use, and relegated to being a weird feature for code golfing. LET may be slow right now, but better to be slow than absolutely wrong. Slow features can be sped up. Wrong features can only be deleted.

The storage and loading of words themselves is actually pretty efficient. The system is geared around it. I'm not terribly concerned about the storage overhead difference between strings and a bunch of words.

What's more troubling is all the bindings made in the user context. These words don't know their binding isn't going to be used. So the user context gets expanded and expanded.

I won't rewrite the explanation of this here. But see The Real Story About User and Lib Contexts

I Think Supporting Words This Way Is Mission Critical

There are a lot of kneejerk responses which would dislike === in the form that I suggest.

Some people wouldn't like that it's variadic. They might believe the principle of Rebol is based on variadic functions shouldn't even be in the language to begin with. I think they're wrong, and we now depend on variadicness quite a lot.

Others might worry about the overhead caused by bloating up the symbol space...or the length of the code block. Or the CPU cycles consumed by having to run a variadic loop across the content of the value at a time.

But I think my leaning is that being able to choose to work this way is the distinguishing factor of the language.

You can still use === {Text} === if you really want to. Or you can avoid using === altogether and just use a comment like ;=== or ;; and it won't have any runtime aspects at all...though then you won't get a log when it reaches that line if you want it.

Using bash is making me realize that even as light as Rebol can be a lot of the time, it's still too heavy sometimes. Having to put things in quotes adds up 2 characters at a time, over time. We should keep an eye on bending the mechanics to make it possible to use LOAD-ed "Rebol sentences" literally, and find places where that makes sense.

This Means Binding Has To Be Rethought... More...

We're just pinning down more of the requirements. So as those requirements get locked, then hopefully that will make a design "emerge".


I like where this conversation may be headed, by the way.

When you set up a PARSE operation, one might start by defining character sets and rules. What are the identifiable values to split up? If it's a dialect you figure out how the input can be transformed into executable expressions, map out the functions you need to write to support those transforms.

With UPARSE and this topic it feels like maybe Ren-C is headed for a similar mindset, where yeah, there's a scripting language there, but more importantly an emphasis on creating your language, with the level of expressivity (e.g., literate or terse, high-level or low-level) that suits your needs. Out of the box, Ren-C supplies the parts, and acts as the substrate that executes your language.

My $.02 but I think this gets a lot closer to realizing the original vision of Rebol than an undercooked messaging language competing with XML.



In this Interview with Drupal Founder Dries Buytaert, the following quote really jumped out at me:

I think this quote could be instructive and perhaps cautionary for designers of new languages-- and in that audience I include designers of dialects and authors of scripts/programs.

It's why I think it's so important to push the boundaries of and redefine what Ren-C is and does. Ren-C probably ought to force us to frequently ask, "Well why would anyone want to do that?" In some cases a feature or decision might be a dud, but in others it could point to new, interesting directions.

I'm skeptical of the idea that there's much to be gained from creating yet another scripting language. And for the same reasons, from yet another dialect or program. These are all examples of cloning things from the past-- like being a musician in a wedding band. :guitar: That's fine for honing skills and absorbing influences, but not so great for doing anything groundbreaking or experimental.


Anyway I thought I'd share that quote. I think a hyper-flexible language like Ren-C is risky-as-hell. But also-- to borrow the highest compliment in science here-- interesting. Who knows what the ability to build mini-languages and dialects might bring-- from what I've seen in the past few decades, maybe not very much. :man_shrugging:

Going back to the music analogy, I think what we see in music and other creative areas (e.g., design, architecture) is an ethos of deconstructing, remixing, re-contextualizing and reinterpreting the past-- of shamelessly ripping-off influences and stealing prior-art to create a version of something capturing here and now. That it's highly derivative scarcely matters. Contemporary music/art is devouring itself and has been for decades, esp with the help of technology, which no doubt led Marc Andreesen to observe that "software is eating the world".

So for Ren-C, I think that it's not only healthy but vital to ask some crazy questions about what this language can do. Because I think the future of programming will be for the less formally/classically trained and less technical. It will be an appalling and shameless remix of prior ideas and influences. Yet for most it will seem fresh and bear little resemblance to the past.

In the right hands, with some luck, I think a preposterously hyper-flexible language like Ren-C could have a lot to offer in that world.



I think the section divider is a good example.

Where other languages would have you think about a logging object and what functions it has, this lets you approach it from an entirely different angle.

You could use integers to indicate logging levels. TOKEN! (issue!) as a hashtag, so you only get the logging when that's set...maybe visually setting the tags aside in a block, maybe not?

=== DO SOME STUFF FOR FOO AND BAR [#foo #bar] ===


do/args script.r [log-level: true]  ; print all section headers    
do/args script.r [log-level: #foo]  ; print section headers with #foo

Having === be variadic, take non-evaluative arguments, and vanish by having no evaluative product is all novel.

The notion that you can write in something that covers most English and have a cheap way of processing it for structure is an unusual idea. There will be sticking points, like the semicolon...but we have strategies that make such things less harmful (such as disallowing it without a space, so that linguistically meaningful; usages cause errors more obviously).

But really, it's about whether the average programmer could design things like PARSE themselves. UPARSE and the whitespace dialect are tackling the hard questions. Ren-C is a backbone that has been gearing up to work on those problems...but solutions don't design themselves. Really it just has to continue one step at a time.


I agree. I think self-documenting features are a great untapped area of high-level languages. Rebol already produces (fairly) plain & concise code, and this code = data. Pushing that envelope further and provide the ability to embed (linguistically meaningful!) information, then ideally you're upgrading that code closer to knowledge.

Java has Javadoc, Rebol has Makedoc, but with a language like Ren-C I'd like to see that pushed so much further. All/most scripts should be queryable (e.g., find fns for re-use) and strongly encouraged to be annotated with embedded metadata to auto-generate a high-level sketch or diagram of the program. Maybe said documentation/diagram is an interactive .svg in WASM; apart from the usual header metadata, you can click on a "live" part of the diagram and see the dev's comment/description and the list of dev-created functions that particular code section calls in another section or file.

Ha-ha, yes, one step at a time though.