Module Headers and Quoting: The Final Verdict

So there's been a long historical fight on whether you need quotes on module header fields...:

Rebol [
    Title: {Your title here}
    Type: 'Module
    Name: 'Your-Module-Name-Here
]

...or if you don't, and you can just say:

Rebol [
    Title: {Your title here}
    Type: Module
    Name: Your-Module-Name-Here
]

This wasn't a tremendously huge problem in historical Rebol, because the standard fields did not take WORD! types. The issue was on the rise with the Type: and Name: fields in modules.

While I have flipped back and forth on which I support, I have never flipped on the idea that this has to be a standardardized.

But today, I think my verdict on which way to go is pretty clear.

Just Say No! (To Ticks In Unevaluated Contexts)

It's visual pollution that serves no purpose.

Really, this is a dialect in a BLOCK!. It uses SET-WORD!s. It is not an OBJECT!.

You can make an object out of it, but you need to be careful about it. Not only do you not have to evaluate module headers, you should not evaluate module headers.

It seems to me that the TO OBJECT! conversions can handle this; it fits the bill of my rule of TO not doing evaluation. So the old "CONSTRUCT" operation can go.

Exception: When Quotes are Part of the Dialect

If you come up with your own header field, used for your own script type's purposes, use quotes if you want...if the quoting has meaning.

Maybe you have some kind of generic thing like initial-value: up top in the header. And that can be ANY-VALUE!, so anything you want to run a test on--for instance. If you have:

Initial-Value: '''''<foo>

Then that's fine. But for fields like the module's type, there is no such distinction in meaning intended by 'Module vs. Module. So that's different.

2 Likes

I will also add that I think Type: module looks better than Type: Module.

Discussion of the capitalization of the keys is something that needs study as well. But it seems to be following email header conventions... e.g. From: bob@wherever

The script library doesn't really enforce any consistency on these points, but right side words are pretty much always lowercase.

1 Like

Well no capitalization is fine. Next thing would be CamelCase.
type: module
looks even better.

This is worth talking about, especially in light of the question of if binding is going to wind up being case-sensitive.

I have a hard time telling if I actually prefer the capitalization or am just used to it. :-/

For the moment there are bigger things to focus on, but this will have to be reasoned about someday.

SUMMARY OF PERSPECTIVES


My bias is [type: module] over [Type: 'module] when technical and aesthetic issues are taken into account. @iArnold agrees.

Oldes Rebol3

It seems that Oldes may be ahead of the curve here... e.g. in his GitHub Module:

REBOL [
    version: 0.2.0
    title: "Rebol/GitHub utilities"
    name: github
    type: module
    date: 8-Nov-2024
    needs: json
    home: https://github.com/Oldes/Rebol-GitHub
    exports: [
        github-query
        github-repo
        github-run
        github-get
        github-post
        github-edit
    ]
]

(I have stated that despite our seeming disagreement, retrospectively I've noticed that I more often agree with his comments on old threads or bugs than I do with other people on the thread who aren't me.)

Chris's $0.02

In another thread, @rgchris observed:

There's a bit of ambivalence there...which he can clarify. But the greater aversion appears to be having to use the uppercased keys on access:

Rebol [title: "text/html"]  ; a bit sad it's a little less formal than Title:

system.script.header.Title  ; measurably more annoying ("would balk at")

So if the keys must match the access--and you only get the two choices--seems he'd go with the lowercase keys in the header.

Worth noting is that HTTP headers are case-insensitive. But the issue of wanting to FORM a header with the caps is something to be aware of. Yet maybe this is a job for applying PROPERCASE on those keys when serializing them, vs. making header objects themselves carry that responsibility...?

Carl's (BrianH's?) Rebol3 Examples

In the Rebol2 documentation on script headers, Carl doesn't have any examples of words. But he does say (emphasis mine):

When a script is loaded, the header block is evaluated and its words are set to their defined values. These values are used by the interpreter and can also be used by the script itself.

So that runs up against my feeling that the header block should specifically not be thought of as being "evaluated" (in the sense of DO)... rather as a dialect.

But looking at the Rebol3 documentation for modules, we see plain words... how much of this is Carl's leaning or Brian Hawley's one has to guess:

REBOL [
    Title: "Stock Trading Module"
    Name: stock-trade
    Version: 1.2.0
    Type: module
    Exports: [buy sell]
]

There's not a lot of examples of this in the Rebol3 sources themselves. But we do see for instance [Context: sys] and [Name: draw, Type: extension, Exports: none].

And an example that comes up from @earl is consistent with this. So I'd

Rebol.org Guidance On Module Headers

I cached it here:

Cache of rebol.org Writeup of Standard Header Fields

It makes explicit mention of LIT-WORD! in four places:

platform: - The platform(s) on which this script will run. Can be a lit-word or block.

type: - Says what type of thing the script is, or how it is used. What its purpose is. Can be a lit-word or block.

domain: - What application area(s) the script addresses. (...) Can be a lit-word or block.

license: - Conditions under which the script can be used. See http://www.opensource.org/licenses/index.html for information about various open source licenses. A string, lit-word, block, or none.

You wind up with kind of evaluation rules, where NONE isn't an enumeration value but something that gets "looked up" in "scant evaluation"...so it does look like evaluation:

library: [
    level: 'intermediate
    platform: 'all
    type: [tutorial tool]
    domain: [ftp game]
    tested-under: none
    support: none
    license: none
    see-also: none
]

Red Source Code

Red doesn't seem to make very aggressive use of headers in its own sources. They do propercase the keys, and the Needs field uses a LIT-WORD!s in the header... at least in the examples I can find... such as their recent Textual UI stuff

Red [
    Title: "Red TUI test script"
    Needs: 'View
    Config: [GUI-engine: 'terminal]
]

Red doesn't seem to error if you say [Needs: view], but it also doesn't error if you say [Needs: asdf]. Sigh, am I going to look to see what is happening, yes... okay here

list: select header first [Needs:]
find [word! lit-word! block!] type?/word list  ;-- do not process other types

So explicitly tolerating WORD! and LIT-WORD!, for whatever that is worth.

Boris's Scripts

I look at @hiiamboris's stuff as an example of a "prolific modern adopter with strong opinions".

He typically uses lowercase keys, plus no quotes on WORD!s:

Red [
    title: "#ASSERT macro and ASSERT mezzanine"
    purpose: "Allow embedding sanity checks into the code..."
    author: @hiiamboris
    license: BSD-3
    provides: assert
    notes: {
        ...
    }
]

But it's not 100 consistent. e.g. in his Tetris clone, he puts the apostrophe on view...and on the license as well:

Red [
    title: "Tetris Redborn!"
    description: "Red Tetris Game YAY!"
    author: @hiiamboris
    license: 'MIT
    version: 1.0.0
    needs: 'view
]	

Then on his PARSE visualizer he puts the needs in a block, but still quotes the license:

Red [
    title: "ParSEE"
    description: "Parsing flow visual analysis tool"
    purpose: "Never again debug Parse rules using randomly inserted print statements"
    author: @hiiamboris
    license: 'BSD-3
    needs: [View]
    notes: {
       ...
   }
]

In a bug he reports he seems aware you can write just [needs: view] without the quote.

Conclusions


It seems people haven't been clamoring for consensus about this. The only person I could find raising the issue in bug databases was... uh... me. :roll_eyes:

Unevaluated Headers Are A Win

There does seem to have been a shift from Rebol2 and the understandings of rebol.org in the R3-Alpha world to use WORD!s instead of LIT-WORD!.

I'll observe license: none makes more sense than license: null ... and I actually think this ties into the "not evaluated" nature of the situation. NONE is (now) more obviously a WORD! in an enumeration, that isn't expected to be evaluated.

We also know that TRUE and FALSE and YES and NO and ON and OFF aren't meant to be "evaluated" (directly) either. So "scant" evaluation is obsoleted by Ren-C.... we make the simplifying leap from "headers are barely evaluated" to "headers are not evaluated at all".

That means system.standard.header can be dropped completely. Instead, just have a world where a "null" header field can be presumed to be a field that's not there at all. (e.g. via TRY getting that field.)

Fully unevaluated headers... gold star. :star:

I Don't Think The Lowercase Keys Are A Big Loss

The best argument for retaining the capitalization of keys is @rgchris's point about the convenience of FORM-ing e.g. HTTP headers. But if casing doesn't matter, I think we should probably rethink that as using the case that works with the binding in the system... and generate the casing you want (e.g. by a PROPERCASE OF function) on output.

And I don't think the lowercasing is a big loss:

Rebol [
    title: "Test parsing"
    file: %test-parsing.r
    copyright: [2012 "Saphirion AG"]
    license: {
        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0
    }
    author: "Ladislav Mecir"
    purpose: "Test framework"
]

It does look different, but when you consider all the simplifications -and- not havin to type the capital letters, doesn't it start to feel more consistent? (If you look at it through newbie eyes, vs. just "what you're used to"...)

Rebol [
    Title: "Test parsing"
    File: %test-parsing.r
    Copyright: [2012 "Saphirion AG"]
    License: {
        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0
    }
    Author: "Ladislav Mecir"
    Purpose: "Test framework"
]

When you put them side-by-side, I don't see a big enough benefit to the propercasing to justify it. And hey, easier typing.

1 Like