19
$\begingroup$

Before setting any definitions to the symbol f, the DefaultValues of f is empty:

DefaultValues[f]
(*  {}  *)

Define SyntaxInformation for f:

SyntaxInformation[f] = {"ArgumentsPattern" -> {_, _}};

Now, DefaultValues for f is not empty:

DefaultValues[f]
(*  {HoldPattern[SyntaxInformation[f]] :> {"ArgumentsPattern" -> {_, _}}}  *)

Also, DefaultValues of built-ins that do have syntax highlighting such as BesselJ have empty DefaultValues:

DefaultValues[BesselJ]
(*  {}  *) 
  1. Why does defining SyntaxInformation for a symbol add definitions to DefaultValues?

  2. Why do built-in symbols with syntax highlighting not have DefaultValues associated with them?

  3. Running DefaultValues[f]={} does not remove the syntax highlighting. But does manually clearing DefaultValues for a symbol cause any problems?

  4. Bonus Why does MatchQ[DefaultValues[f], DefaultValues[f]] yield False after setting SyntaxInformation for f.

$\endgroup$

1 Answer 1

20
+100
$\begingroup$

In my view, the Mathematica front end would have needed a complete rewrite a long time ago to be in a shape where it can compete with modern UI's. Looking at MATLAB, it's clear that you always find things that are even more out-of-date. Also, I don't want to say that you can't create beautiful content inside a notebook. However, especially the capabilities of the notebook's editor carry a lot of technological depts.

One of the major problems is how you make the knowledge of the kernel available to the front end for autocompletion, highlighting or even code inspections. In a perfect world, the front end would simply ask the kernel questions like

  • What existing functions match "Plo*"?
  • What is the highlighting of myFunc?

and use this information for highlighting. However, this has proven to be too slow or too heavy when you consider how often you get autocompletion pop-ups and how much code needs to be highlighted. As a side note: The original implementation of the front end's autocompletion did exactly that. It always asked the kernel about defined functions.

My feeling is that Wolfram moved to an approach where they keep these pieces of information in the front end and try to sync with the kernel when you evaluate code. In fact, when you use the LinkSnooper to peek into the information flow, you see that each evaluation is combined with the front end asking the kernel for all defined symbols.

For FunctionInformation it appears to be similar. That means when you evaluate

SyntaxInformation[f] = {"ArgumentsPattern" -> {_, _}}; 

the only thing the kernel does is to put the information in the DefaultValues. The real trickery is that the front end captures this call to update its own function information. This is done with the front end function

FrontEnd`SetFunctionInformation[...]

Important is that both things are separated and only what the front end knows will be used for highlighting. Now, we are ready to answer your questions with the usual disclaimer that I don't have more information than what spelunking tells me:

  1. Why does defining SyntaxInformation for a symbol add definitions to DefaultValues?

We need to look at this from the point of the Mathematica kernel of the year 1990. Fancy highlighting for arguments did not exist, but the different bags of rules where information about a symbol could go were already there. We have DownValues, OwnValues, UpValues, Messages, and DefaultValues. I guess the only half-decent place where you could put a thing like the function information rules is in the DefaultValues. It's not intuitive, but it's probably the least harmful way to do it. If a call to SyntaxInformation is supposed to attach the given information to the symbol, it needs to go into one of the rule bags, and I guess Wolfram decided that the DefaultValues were a good place.

  1. Why do built-in symbols with syntax highlighting not have DefaultValues associated with them?

Because they are never called with SyntaxInformation[..] = .... What Mathematica does is to use the syntax information you find in

$InstallationDirectory/SystemFiles/Kernel/TextResources/English/FunctionInformation.m

and call FrontEnd`SetFunctionInformation directly. These definitions never see the kernel. For more details, please look into the file

FileNames["GetFEKernelInit.tr", {$InstallationDirectory}, Infinity]

and search for SetFunctionInformation.

  1. Running DefaultValues[f]={} does not remove the syntax highlighting. But does manually clearing DefaultValues for a symbol cause any problems?

Besides that calling SyntaxInformation[f] won't give you the rule anymore while the front end still highlights it according to your settings, I don't think there are further problems. Btw, you can also do this the other way around: Tell the front end that there is a function to highlight, while there is none:

info = {{"Global`", {{"func", {_}}}}};
MathLink`CallFrontEnd[FrontEnd`SetFunctionInformation[info]]

Now, you have autocompletion for func and it highlights missing/excessive arguments, but the kernel has absolutely no clue about func. Even cooler is doing this with Plot because then the FE (yeah, I'm finally abbreviating this) thinks your stupid soul tried to add another global Plot definition and marks it with red :)

  1. Bonus Why does MatchQ[DefaultValues[f], DefaultValues[f]] yield False after setting SyntaxInformation for f.

From the documentation:

Verbatim[expr] represents expr in pattern matching, requiring that expr be matched exactly as it appears, with no substitutions for blanks or other transformations.

Therefore,

MatchQ[DefaultValues[f], Verbatim[DefaultValues[f]]]
(* True *)
$\endgroup$
4
  • $\begingroup$ Thank you for the very insightful answer! My LinkSnooper just shows "large contents not printed". Do you know how to make it show those contents? $\endgroup$
    – QuantumDot
    Commented Nov 4, 2019 at 9:39
  • $\begingroup$ The only way from the top of my head is to fix this in the LinkSnooper Java code which ships with your installation. Then you can build your own LinkSnooper that shows this. $\endgroup$
    – halirutan
    Commented Nov 4, 2019 at 9:54
  • $\begingroup$ I see, I wanted to know what the FrontEnd`SetFunctionInformation call looks like if the syntax information has OptionsPattern[] in it. Do you know what that looks like? $\endgroup$
    – QuantumDot
    Commented Nov 4, 2019 at 9:59
  • $\begingroup$ Look into the GetFEKernelInit.tr. There you see that it feeds the contents of FunctionInformation.m directly with the contexts as a second argument. If you grep through all sources of Mathematica, you find at least one other usage, which suggests the way I showed in my post with only one argument. $\endgroup$
    – halirutan
    Commented Nov 4, 2019 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.