Lisp will at least warn you if you bind a variable with earmuffs that isn't declared special though. Biggest downside to environment variables is the lack of warning if you misspell something.
Re:Conventions for Command Line Options
by chriswarbo on Saturday August 01, 2020 @04:51PM
(#24023811)
Interesting that you bring up Lisp and dynamic scope, since I've previously combined env vars with Racket's "parameters" (AKA dynamic bindings): https://lobste.rs/s/gnniei/setenv_fiasco_2015#c_owz2pp
Re:Conventions for Command Line Options
by TeMPOraL on Saturday August 01, 2020 @05:17PM
(#24023975)
Yeah, I just can't stop thinking about envs / dynamic binding when someone brings up the other.
Speaking of using both direct and dynamic arguments, a common pattern in (Common) Lisp is using dynamically-bound variables (so-called "special" variables) to provide default values. Since default values in (Common) Lisp can be given as any expression, which gets evaluated at function-call time, I can write this:
(defun function (&key (some-keyword-arg *some-special*))
...)
And then, if I call this function with no arguments, i.e (some-function), the some-keyword-arg will pull its value from current dynamic value of some-special. In process land, this would be equivalent to having command line parser use values in environment variables as defaults for arguments that were not provided.
I can't stop but see here parallels between cmdline arguments vs. environment variables for programs, and keyword arguments vs. dynamic binding for functions in a program (particularly in a Lisp one).
That is, $ program --foo=bar vs. $ FOO=bar program
seems analogous to:
When writing code (particularly Lisp), keyword arguments are preferred to dynamic binding because the function signature is then explicitly listing arguments it uses, and dynamic binding (the in-process phenomenon analogous to inheriting environment from a parent process) is seen as dangerous, and a source of external state that may be difficult to trace/spot in the code.I suppose the latter argument applies to env vars as well - you can accidentally pass values differing from expectation because you didn't know a parent process changed them. The former doesn't, because processes don't have a "signature" specifying its options, at least not in a machine-readable form. Which is somewhat surprising - pretty much all software written over the past decades follows the pattern of accepting argc, argv[] (and env[]), and yet the format of arguments is entirely hidden inside the actual program. I wonder why there isn't a way to specify accepted arguments as e.g. metadata of the executable file?