Good afternoon,
Earlier, I thought that Mathematica creates new characters in the current $Context at the stage of converting the input string (which is assigned to InString ) to enter an expression (which is assigned to In ). But one simple example violated this explanation:
In[1]:= ?f During evaluation of In[1]:= Information::notfound: Symbol f not found. >> In[2]:= Names["`*"] Out[2]= {} In[3]:= DownValues[In]//First InString[1] Names["`*"] Out[3]= HoldPattern[In[1]]:>Information[f,LongForm->False] Out[4]= \(? f\) Out[5]= {}
You can see that there is no f character in $ContextPath , although it is already used inside the definition for In[1] .
This example shows that in Mathematica it is in principle possible to create definitions with characters that do not exist in $ContextPath without creating them. This can be an interesting alternative to preventing the creation of a symbol using Symbol :
In[9]:= ff := Symbol["f"] Names["`*"] Out[10]= {"ff"}
Can someone explain under what conditions and at what stage in the evaluation process Mathematica creates new characters?
EDIT
As Sasha noted in a comment on this question, in fact, I was faked with the default ShowStringCharacters->False settings for output cells in the default stylesheet Core.nb and skipped FullForm for output for DownValues[In]//First . In fact, the character f not used in the definition for In[1] , as we see using InputForm :
In[1]:= ?f DownValues[In]//First//InputForm During evaluation of In[1]:= Information::notfound: Symbol f not found. >> Out[2]//InputForm= HoldPattern[In[1]] :> Information["f", LongForm -> False]
Sorry for the hasty statement.
So, now the question is about the stage at which Mathematica decides to create a new Symbol and how can we prevent this? For example, in the above example, we introduce f as Symbol , but Mathematica converts it to String without creating a new symbol. This is the built-in behavior of MakeExpression :
In[1]:= ?f InputForm[MakeExpression[ ToExpression@InString [1], StandardForm]] During evaluation of In[1]:= Information::notfound: Symbol f not found. >> Out[2]//InputForm= HoldComplete[Information["f", LongForm -> False]]
Perhaps it is possible to define some type of syntactic construct that will prevent the creation of a character until it is evaluated.
About the assessment stage when creating a new character
We see that the increment of $Line occurs before calling MakeExpression , but after creating MakeExpression :
there is a new
Symbol creating and assigning a new value for the variables
InString and
In In[1]:= MakeExpression[My`boxes_,My`f_]/;!TrueQ[My`$InsideMakeExpression]:=Block[{My`$InsideMakeExpression=True},Print[$Line];Print[DownValues[InString][[All,1]]];Print[DownValues[In][[All,1]]];Print[Names["`*"]];MakeExpression[My`boxes,My`f]]; In[2]:= a During evaluation of In[2]:= 2 During evaluation of In[2]:= {HoldPattern[InString[1]]} During evaluation of In[2]:= {HoldPattern[In[1]]} During evaluation of In[2]:= {} Out[2]= a
The same can be said of $PreRead and $NewSymbol call time:
In[1]:= $NewSymbol:=Print["Names[\"`*\"]=",Names["`*"],"\nDownValues[InString]=",DownValues[InString][[All,1]],"\nDownValues[In]=",DownValues[In][[All,1]],"\nName: ",#1,"\tContext: ",#2]& In[2]:= a During evaluation of In[2]:= Names["`*"]={} DownValues[InString]={HoldPattern[InString[1]]} DownValues[In]={HoldPattern[In[1]]} Name: a Context: Global` Out[2]= a
$Pre is executed after creating a new assignment in In and after creating an entire new Symbol in the current $Context :
In[1]:= $Pre := (Print[Names["`*"]]; Print[DownValues[In][[All, 1]]]; ##) & In[2]:= a During evaluation of In[2]:= {a} During evaluation of In[2]:= {HoldPattern[In[1]],HoldPattern[In[2]]} Out[2]= a
It seems impossible to intercept the assignment of a new value for the variable In .
Conclusion: new Symbol are created after calling $PreRead , MakeExpression and $NewSymbol , but before calling $Pre .