What Does "Literal" Mean In Rebol's Model?

In programming, the term "literal" generally refers to when a source item expresses a fundamental value and doesn't need to be looked up in a variable. It is essentially inert.

For C:

int value = 10;  // 10 seen here is an "integer literal"
printf("The value is %d", value);  // "string literal" + "integer variable"

But in Rebol's world, the notion of "what's a literal" is context-dependent, and can be very bent up.

is-this-literal?: func ['word [word!]] [
    print ["The word was" word "- you tell me if that was literal!"]
]

>> is-this-literal? foo
The word was foo - you tell me if that was literal!

So what do you think...is FOO a "literal word" or not?

The answer is that we can't particularly answer whether a value is "literal" or not unless we know how it is being used. The term has kind of lost its meaning.

All we can really say in a particular situation is if a value is being used in a "literal way" or not.

In terms of naming, Rebol historically called quoted things "LIT" things.

rebol2>> type? first ['foo]
== lit-word!

But the evaluator gave LIT-WORD!s a behavior...they'd drop their quote mark:

rebol2>> 'foo
== foo

So important to notice: "inertness" wasn't implied by what was being called "literalness"

2 Likes

Coming back to this question, I think the only real meaningful use of literal is to describe when something is taken "as-is".

So what we've called "quoted parameters" are probably better called "literal parameters"

>> foo: func ['arg] [:arg]

>> foo x
== x

We've historically used the quote mark. But it's a little bit hard to see, easy to overlook.

Today there is the "THE" operator:

>> the x
== x

And the symbolic THE! value, an @, is a subtly different but similar thing:

>> @ x
== x

In both these cases I would say that X was "taken literally".

So I've started leaning to thinking that notationally, we might prefer @ for "literal parameters":

>> foo: func [@arg] [:arg]

>> foo x
== x

One huge advantage is that @arg is an ANY-WORD! type, not a QUOTED!. Doing spec analysis is difficult when you are handling quoted items... and it's not like the generality was being exploited. There weren't 'params and ''''params to be distinguished. So when you noticed something was quoted there were more tests to do...to make sure it's only one level, that it's a word, etc. etc.

Quoting is powerful and useful when it's a fit for what you need. But here it's busywork. And if the busywork is not done then you wind up tolerating ''''params, which do not belong in specs so that's bad. It's lose lose.

Getting away from the term "quoted argument" is didactically beneficial. If anything, META arguments would be "quoted arguments"! :crazy_face:

>> foo: func [^arg] [arg]

>> foo x
== 'x

(Don't take what I just said seriously, ^META parameters should not have been called quoted parameters. (^ null) is null and not ' ... and (^ get/any 'asdfasdf) is ~unset~ which is de-isotoped, but not quoted.)

The @ is easier to see than a ' - When you think about just how significant the difference between the literal parameter convention and the evaluated parameter convention, doesn't it seem like it should be a bit more disruptive in the spec?

foo: func [
    gatheredoneway [word! path! integer!]
    'radicallydifferent [word! path! integer!]
][
    print [gatheredoneway radicallydifferent]
]

bar: func [
    gatheredoneway [word! path! integer!]
    @radicallydifferent [word! path! integer!]
][
    print [gatheredoneway radicallydifferent]
]

Seems Convincing, But What About Escapable-Literals?

So I've been kind of stirring around my whole "GET-WORD! Symbolizes Function Fetching" theory.

To rehash my consistent rehashing of the idea: this is to say that iterations wouldn't give you ACTION! unless you used a GET-WORD! as the iterator:

block: compose [1 (:append) "three"]

for-each x block [...]  ; FOR-EACH errors when it hits the APPEND ACTION!

for-each :x block [...]  ; FOR-EACH won't error, gives it to you as-is

This is based on my belief that 99 times out of a hundred you have no intention of executing an action, yet people who like dotting their i's and crossing their t's will pepper the code with GET-WORD! "just to be safe" (when in reality the code probably wouldn't work with an action anyway, you're just avoiding running arbitrary code, not so much for security but to avoid incomprehensible gibberish errors).

This feels ever more right because of the fact that GET-WORD! doesn't return "unset values" (more generally, BAD-WORD! isotopes). It's exclusively for not running functions. The two seem soul bound.

If GET-WORD! Were Taken To Mean "This Argument Can Be An ACTION!", it raises two questions:

  • How could you take a parameter that was both literal @xxx and could be an action :xxx ?

  • What would step in as the notation for "escapable literals"? e.g. FOR-EACH wants to take a variable name, but it may be computed...currently with GET-WORD!/GET-GROUP!/etc.

    for-each var [...]
    for-each :name [...]
    for-each :(first [var1 var2]) [...]
    

With the recent revelations about the importance of SET-GROUP! acting as SET that I hadn't really grasped before, I'm pretty sure there's a parallel argument for why GET-GROUP! needs to act as GET. If so, the following equivalence does not hold up:

  for-each :(first [var1 var2]) [...]
  =>
  for-each var1 [...]

Because :(first [var1 var2]) semantically needs to have some notion of GET-ting var1.

This may suggest going back to the plain GROUP! for escapable literals. I don't know if that implies that the parameters should look like:

 for-each: func [
      @(var) [...] ;  Is this good for escapable literals?
      data [...]
      block [...]
 ][
      ...
 ]

I really like the semiotics of that--especially if it's plain group that escapes. But I've mentioned that I think it should be easy to make escapable literals, and it's the unescapable literals that should be the last resort.

Maybe the @ is on the Type Block, Not The Variable ?

for-each: func [
     var @[word! ...]
     data [any-series! ...]
     body [block!]
][
     ...
]

That would solve the :var "can be an action" hint. I feel it also looks a little bit better for literal refinements:

@/var [word!]

 vs.

/var @[word!]

Okay, This Is All Just Brainstorming, but...

Nothing decided yet, but there's at least one takeway:

We should be calling them "LITERAL ARGUMENTS" and not "QUOTED ARGUMENTS"

So let's start doing that. :slight_smile:

Agreed, quoted also sounds if there is a closing quotation marker, which there isn't.