Allow referring to namespaces with globally unambiguous names
In general, a namespace in Elvish doesn't have a name guaranteed to refer to it in every context. For example, $math:pi is a way to refer to the $pi variable in the standard math module, but that depends on a previous call of use math. If the math module is renamed (e.g. use math x), the same variable would be referred differently (e.g. $x:pi).
However, it is occasionally useful to have a globally unambiguous name for each namespace, mostly for diagnosis purposes. One example is when printing the name of the builtin functions. For example, the key command in the edit module currently has the awkward name <edit>key, instead of just edit:key, because the latter may not be correct. If the edit module actually has a globally unambiguous name, say the:unambiguous:edit which always works, then each command would actually have a valid name.
I've always been slightly irritated by the output of commands such as pprint $edit:global-binding:
> pprint $edit:global-binding
[
&Ctrl-G= <builtin <edit>close-mode>
&'Ctrl-['= <builtin <edit>close-mode>
]
It seems to me it should be possible to produce friendlier output (e.g., $edit:close-mode~) even if the idea in this issue is not implemented. And even if it becomes possible at some future date to use that module under a different name; e.g., use edit my-edit.
It seems to me it should be possible to produce friendlier output (e.g.,
$edit:close-mode~) even if the idea in this issue is not implemented. And even if it becomes possible at some future date to use that module under a different name; e.g.,use edit my-edit.
It's not impossible, but it's a bad idea.
With the following code:
use str mystr
echo $mystr:contains~
It might be feasible to make Elvish mart enough to print $mystr:contains~, that wouldn't actually be desirable, because the output may travel across the boundaries of lexical environments. The code above could be in a module:
// ~/.elvish/lib/a.elv
fn f {
use str mystr
echo $mystr:contains~
}
And the function f invoked from elsewhere. The output $mystr:contains~ is not useful for the caller of f.
@xiaq: I see your point but the current output is the string'<builtin str:contains>' which also is "not useful for the caller of f" AFAICT. Also, to be consistent with the output of pprint $edit:global-binding it seems to me it should be '<builtin <str>contains>'. What am I missing from this picture?
@xiaq: I see your point but the current output is the string
'<builtin str:contains>'which also is "not useful for the caller off" AFAICT. Also, to be consistent with the output ofpprint $edit:global-bindingit seems to me it should be'<builtin <str>contains>'. What am I missing from this picture?
Nothing, the printing of builtin function names is not internally consistent at the moment.
the printing of builtin function names is not internally consistent at the moment.
Thanks for that answer since I was wondering if I was missing some reason for the difference in "stringification" of the value in my two scenarios. It seems to me the "string" form of a callable should, ideally, be equivalent to an Elvish literal that is usable for assigning to, or expanding, the var. Regardless of any import aliasing. At least for the embedded namespaces. In other words, rather than <builtin <edit>close-mode> output $'<builtin>':edit:close-mode~. Where '<builtin>' could be any reserved namespace such as builtin or B and that doesn't need to be quoted.
Update: The "assigning to" in the above is obviously problematic and probably should be explicitly omitted from the spec for such stringification.