Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
Allow using dynamically built strings for external commands #764
Right now, Elvish always resolves commands at compile time, and it is not allowed to use a dynamically built string as a command. The compile-time resolution only accepts single string literals. For instance:
The rationale is that, references to functions must be resolved statically for lexical scoping to work correctly. If dynamically strings were allowed (which used to be the case), consider the following code:
The user would expect the call at  to refer to the
This rule has some unintended consequence. For instance, neither of the following is allowed:
Instead an explicit
Since building the paths of external commands is a pretty common use case, we can re-allow the use of dynamically built strings as commands, but always resolve them to external commands. However, doing this naively can have some other unintended consequences:
A compromise is to only allow such dynamically built commands if they contain at least one slash or backslash. Since slashes and backslashes are not allowed in function names, this means that no ambiguity can arise. For instance:
@krader1961 Closures are precisely why the function names have to be resolved statically.
The runtime representation of closures do not carry all the outer lexical scopes of the closure; it only captures the variables that are referenced from the closure (upvalues). Deciding which names get captured as upvalues happens at compile-time; hence the compiler needs to know the command names statically. In the contrived example, the compiler can reason that
Capturing all values in the outer lexical scopes is an option, but that is wildly inefficient and I don't think any language actually does that.