From (get-env "FOO") to (environment.FOO) to (env.FOO) to $FOO

If you spend time in bash scripting or something like GitHub CI, you realize that environment variables are really important.

So it's a bit sad that Rebol has had the really ugly get-env and set-env functions as the interface to this.

I'd say it's pretty clear that we'd like for env.FOO to work. I'm also leaning to thinking that at least in some dialected circumstances, $FOO should be interpreted as an environment variable as well...and we need these types:

  • $WORD
  • $TU.P.LE
  • $PA/TH
  • $[BL O CK]
  • $(GR O UP)

(I thought it might be interesting if the way the evaluator treated these types was to call whatever $ was bound to, with the thing as an argument. If that were viable, it could be applied to : and @ as well. But the thorn is that the value only has one binding for the word/path/tuple/etc....nowhere to put the binding for the operator in the cell. New binding models could change that, so I'm keeping an open mind.)

But How To Make An "ANY-CONTEXT!" That Calls Functions?

Right now, the only way to get hooks into the system to run code when you use tuple access is by making a new datatype. And that can only be done in the C code.

So if someone put a gun to my head and told me to make it work right now--today--the quickest path would be to make a new ANY-CONTEXT! type in C called an ENVIRONMENT!. The flaky part is that environment variables come from an extension, and so it would be an "extension type" (like a GOB! or VECTOR!), and those are second-class citizens (they don't work in TYPESET! for instance, they're all considered the same CUSTOM! datatype for those purposes).

I resist the temptation to do this, because while it would be nice to write environment.FOO instead of get-env "FOO", most of the uses are in the rebmake code...which needs to work in the bootstrap executable. So no point in making an existing mess with extension types messier.

Any Usermode Ideas?

I think what we should be looking for is a way that someone without a C compiler could make something that looks like an object, but the behavior for handling the TUPLE! access comes from functions.

Right now you can't "dot an action"... actions only take PATH!s for refinements. So we could say that if we get a dot, it looks to see if the function has a /DOT refinement, and if it does then it will call it accordingly with information from the context of the get or set:

environment: func [variable [word! set-word!] value [<end> any-value!] /dot] [
    assert [dot]  ; let's say you always use with dot for now
    if set-word? variable [
       echo [You asked to set @variable to @value]
    ] else [
       echo [You asked to get @variable]
]

>> environment.FOO
You asked to get FOO

>> environment.FOO: 10
You asked to set FOO to 10

It's better than nothing. But what I don't like about it is that I have the idea that tuple access on functions will be able to get and set properties stored on that function... e.g. that functions will be able to act as objects. This would be where stuff like help informaiton is stored. (This was historically called the "meta object" but we have much more compelling uses for the word "meta" now.)

So Probably Better to be a User-Defined Datatype

Unfortunately these don't exist yet. But I guess now we have a good example of ENVIRONMENT! as something that needs supporting.

2 Likes