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...we have these parts:

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

So things like CALL/SHELL should let you use those.

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

So I noticed generalized accessors bring some promising ideas.

But they aren't quite what's needed here. You could make an object with a field in it that was able to read or write an environment variable when accessed via TUPLE! or SET-TUPLE!. But making an object that had no literal fields but did the tuple decoding itself is another thing.

Fortunately tuple processing is now built on PICK and POKE. So what's necessary here is to make a way for objects to have their own custom PICK and POKE methods.