This is IMO a very deep and valid question, and judging by the vote count, I am not alone in thinking this. If we had this feature fully supported on the language level, this would give one a whole new way to manipulate the scoping and encapsulation, and would IMO often allow for a cleaner code and better information hiding. This would be similar to from module-name import name1,name2,...
in Python.
Perhaps as many of us, I have tried multiple approaches, but all of them seem fragile and incomplete. The worst case is for packages, for which I have no good solution. For the interactive work in the FrontEnd, here is one which might be acceptable. First define a general macro to make the literal substitutions:
ClearAll[withImported];
SetAttributes[withImported, HoldAll];
withImported[importingRules : {(_Symbol -> _String) ..}, code_] :=
With @@ Join[
Hold[importingRules] /.
(name_Symbol -> context_String) :>
With[{eval =
Block[{$ContextPath = Append[$ContextPath, context]},
ToExpression[context <> ToString[Unevaluated@name]]
]},
Set[name, eval] /; True],
Hold[code]];
withImported[importingRules : {({__Symbol} -> _String) ..}, code_] :=
Reverse[Hold @@ Flatten[Unevaluated[importingRules] /.
({syms__Symbol} -> s_String) :> Thread[s :> {syms}]], {2}] /.
RuleDelayed -> Rule /.
Hold[expandedRules : ((_Symbol -> _String) ..)] :>
withImported[{expandedRules}, code];
Then, create a function which would incorporate your favorite shortcuts, for example:
shortcutF =
Function[code,
withImported[
{
{PackedArrayQ, ToPackedArray, FromPackedArray} -> "Developer`",
{InheritedBlock, WithLocalSettings} -> "Internal`"
},
code
],
HoldAll];
You can now wrap your code in shortcutF
and start using the short names. Up to now, this would also work for packages, but you will have to wrap all your code (or at least those pieces which contain short-cuts) in shortcutF
, which is not very convenient. As a further convenience step, you may assign the above function to $Pre
:
$Pre = shortcutF;
Here are some examples of use:
In[31]:=
WithLocalSettings[Null,Abort[],Print["Cleanup"]]
During evaluation of In[31]:= Cleanup
Out[31]= $Aborted[]
In[32]:= PackedArrayQ[Range[10]]
Out[32]= True
In[33]:= PackedArrayQ@FromPackedArray[Range[10]]
Out[33]= False
Since With
is used under the cover, what really happens is that your short-cut symbols get substituted by fully-qualified symbol names, before the code is executed.
This is as far as I could get, but this feature seems to be particularly crying for a native support from the language.
Internal`
andDeveloper`
. You could write a wrapper function to implement your kludge with attributes etc... – RemunerativeUnprotect
or similar tools, one can redefine the context of aSystem`
orInternal`
symbol usingContext[symbol] = "context`"
. However, this removes the symbol from its original context, which is unacceptable. Is there any way to assign two different contexts to a symbol? – Accentuatethis is neither clean nor fully correct
. Can you explain further? – Holguin...Values
, and even for the top-level is not without flaws. – ZellerSet
adds the evaluation process to the mix. And I am with him - this indeed does not feel right (to me anyway). – Zellersymbol and adding the context to the context path). On the other hand, I think allowing native support for symbol cloning may open loopholes and difficulties in code comprehension that I feel are not justified by the scarce gain of saving the context
symbol syntax. Method overriding in OOP risk the same kind of confusions, but at least the gains may justify the means. – Holguin