8
$\begingroup$

Syntax coloring for the following function definition

foo[x_List] := ...

will color green (and italicize by default) the argument name x as well as the pattern name _List:

enter image description here

On the other hand, syntax coloring for

foo[x:_List]

colors only the identifier x green and not the _List qualifier:

enter image description here

Is there a way to configure the front end to color just the identifier name as in the second example?

Looking through the Option Inspector, I cannot find any relevant switches, so I suspect not. I do wonder however if this behavior is a bug or a feature whose purpose I don't fully understand.

EDIT: The remaining issue in this question is the following: The syntax coloring rule which specifies that function argument names should be colored green in the body of the function in which these names are bound also colors green any head to the right of the underscore that is present for pattern matching purposes. In what sense is the underscore itself and any head that is attached to it part of the function argument name proper?

The two examples provided above exhibit a pair of semantically equivalent function definitions where the coloring (which is syntax) is applied differently to semantically equivalent parts of the respective function definitions.

EDIT: Here is another example where the syntax coloring rule for pattern names is being applied in a seemingly inconsistent fashion:

f[a + b] + f[a + c] /. f[a + x_] + f[a + y_] -> p[x, y]

Shouldn't the x and the y arguments in p[x,y] be colored green much like in a function definition (whose syntax also defines a transformation rule)?

Another puzzling example:

MatchQ[{1, 1}, {x_?IntegerQ, x_ /; x > 0}]

In my front-end (v8) the first x is black. On the other hand, the second and third instances are colored green.

These examples raise the issue of whether or not color syntax rules for pattern names as they are currently implemented cause more confusion than they are worth for helping the user visualize lexical scopes that are in force at a particular position in the code. Anyone else agree?

$\endgroup$
7
  • $\begingroup$ Regarding your recent edit, I don't find that puzzling. The first instance of x_ is naked, while x_ and x is a pairing as the highlighting indicates. I am sorry that Mathematica does not have (AFAIK) more customizable highlighting to suit your wishes. It also bothers me that highlighting is not provided for {x} ~Block~ Mod[x, 2] or i ~Table~ {i, 5} but unlike you I find the existing highlighting internally consistent enough that I am used to it. $\endgroup$
    – Mr.Wizard
    Jun 9, 2012 at 8:50
  • $\begingroup$ @Mr.Wizard: You make a reasonable case for the second example. The first one involving p[x,y] is still a bit puzzling however. I'm glad that you find the syntax coloring rule for pattern names "consistent enough" for your own use. It would be helpful if someone could state in plain English here what the rule is so that others such as myself are not so "surprised" by the resulting application of the rule in examples like those cited above. $\endgroup$ Jun 9, 2012 at 9:05
  • 1
    $\begingroup$ Sorry, I missed that one. x and y in p[x,y] should not be colored green because they are not localized; if you use RuleDelayed (:>) instead you will see that they are colored, because with that they are localized. A useful distinction. $\endgroup$
    – Mr.Wizard
    Jun 9, 2012 at 9:07
  • 1
    $\begingroup$ Yes, that's correct. However, note that they will be replaced by the matching LHS object if they do not evaluate to something else. I always try to use :> when using named patterns on the RHS to avoid this ambiguity, though conceivably there are certain uses when this ambiguity is useful. $\endgroup$
    – Mr.Wizard
    Jun 11, 2012 at 6:01
  • 1
    $\begingroup$ That is generally my understanding, but the highlighting is not perfect (reference ~infix~ comment above). $\endgroup$
    – Mr.Wizard
    Jun 11, 2012 at 6:06

2 Answers 2

2
$\begingroup$

I don't think it's possible, but I hope for an answer proving me wrong.

I don't think you can do anything about how the front-end interprets what you type as boxes. If you could do that, you could make something like x_Integer parse into a certain StyleBox. However, it's interpreted as a single word. Try it, and in the cell expression you'll see BoxData["x_Integer"]. I doubt the front-end allows you any way of treating parts of a word differently than others.

The front-end has some options regarding the syntax coloring, but, as you said, I found none that could apply to this. There are also some styles in the core.nb stylesheet that can be customized, such as the color of unmached brackets, but none related and particularly, none referring to "parts of words".

Similarly, the option AutoStyleWords only helps with specific full words (in box type cells). As John Fultz said in this answer

"This will only work to style things which are lexically word-type tokens. You cannot, for example, auto-style two words in sequence, a subexpression with an operator, or a substring of a word token."

Conclusion

I'm not totally certain, but my best guess is that your only chance is by brute force. This means, some trigger, that runs code that reads your cell's box expressions and turns them into what you like. The trigger could be a CellEventHandler that catches keystrokes, or a ScheduledTask, or some manual input, palette, hotkey, context menu, etc.

Leonid is using this approach in his syntax highlighter package, and if this is important to you, my bet is that the road through this link is your tough but best chance

$\endgroup$
4
  • $\begingroup$ FullForm[x_Integer] is Pattern[x,Blank[Integer]] but as you point out "x_Integer" is parsed as a single word BoxData["x_Integer"]. OTOH, "x:_Integer" parses as BoxData[RowBox[{"x", ":", "_Integer"}], which can have its various subexpressions transformed according to different rules by the built-in syntax coloring engine. The (presumed) inability here of the user to customize how Mma parses an expression like "x_Integer" raises an interesting question: how exactly does Mma compare to LISP's flexibility in the area of "read-time macros"? $\endgroup$ May 20, 2012 at 6:37
  • $\begingroup$ I'll keep this question open a little longer before awarding the bounty to see what others have to offer on this issue. Thanks for your insights regarding what are probable limitations on the user's ability to modify the syntax coloring rules. This particular syntax coloring issue is not all that crucial, but I am concerned about the larger issue of what ability does the user have to customize formatting rules in the frontend which is why I'll be following the development of Leonid's package with interest. $\endgroup$ May 20, 2012 at 6:39
  • 2
    $\begingroup$ Correct, there is no conventional way to change whether the FE chooses to color the head of a pattern in the way the StackExchanger is hoping. Somebody might come up with some creative unconventional means, but I would personally be a bit gun-shy about using such a method. $\endgroup$
    – John Fultz
    Jun 10, 2012 at 9:42
  • $\begingroup$ @JohnFultz: Thanks for chiming in here. I can easily live with the current syntax coloring rules -- studying their behavior carefully however has helped me better understand the finer points of scoping and pattern matching. I hope that a future version of Mma will allow the user to customize syntax coloring by evaluating expressions in the front-end and in the process help obviate the need for employing the kind of clever "gymnastics" contained in the package Shifrin is currently developing for this purpose. $\endgroup$ Jun 12, 2012 at 8:00
4
$\begingroup$

I find the difference to be helpful and provides "good to know" syntax information. In the case of using it in a "function" as you did*, naming a pattern (i.e. the : term) allows you to create much more complicated pattern matches for that element. So, while for your example, the full form of each statement evaluates the same:

In[17]:= FullForm[foo[x_List]]
FullForm[foo[x:_List]]

Out[17]//FullForm= foo[Pattern[x,Blank[List]]]
Out[18]//FullForm= foo[Pattern[x,Blank[List]]]

For two more complicated examples (which are legal), the different notations don't make sense:

In[21]:= FullForm[foo[x{_String,_List}]]
FullForm[foo[x:{_String,_List}]]

Out[21]//FullForm= foo[List[Times[x,Blank[String]],Times[x,Blank[List]]]]
Out[22]//FullForm= foo[Pattern[x,List[Blank[String],Blank[List]]]]

Note that the first one doesn't produce a valid function, while the second one does:

In[32]:= Clear[foo]
foo[x:{_String,_List}]:=x
foo[{"Hi",{}}]

Out[34]= {Hi,{}}

In[29]:= Clear[foo]
foo[x{_String,_List}]:=x
foo[{"Hi",{}}]

Out[31]= foo[{Hi,{}}]

I personally prefer the way that MMA currently does it: there should not be any highlighting on {_String,_List} in my example function foo.

* Technically you are defining a pattern matching rule, see: Functions vs. patterns

$\endgroup$
10
  • $\begingroup$ I'm not sure that I understand your answer. Are you claiming that you prefer syntax coloring in the slightly inconsistent way that Mathematica currently performs it, or that you too prefer that only the identifier's name (and not any associated pattern matching syntax) be highlighted? $\endgroup$ May 1, 2012 at 17:43
  • $\begingroup$ @StackExchanger I believe that the way MMA currently does it is the preferred way. Tried to edit the last paragraph to make that clearer $\endgroup$
    – tkott
    May 1, 2012 at 18:15
  • $\begingroup$ The first one does define a valid function; it's just hard to call (because Times has attribute Listable). Here's an example how to call it: foo[Unevaluated[{x"Hello world", x{}}]]. Note the Unevaluated (to prevent x to be passed to the member of the inner list — which here would make it disappear completely because that list is empty) and the manual distribution of x for the outer list (because Unevaluated would prevent that as well, which would also cause the definition not to match). Note that the definition of foo is (as can be seen by ?foo) foo[{x*_String, x*_List}] := x $\endgroup$
    – celtschk
    May 1, 2012 at 18:52
  • $\begingroup$ @tkott: To be clear all I am asking here is whether or not the different way Mma >>colors<< syntax in you first code block is desirable. When the pattern is attached to the identifier name via an underscore, the pattern is colored along with the identifier name, whereas in the case that the identifier name and the pattern are separated by a colon, only the identifier (and not the pattern) is highlighted. I would prefer that both cases are handled by the same rule: only color the identifier name and not any patterns used to constrain what the name can match. $\endgroup$ May 1, 2012 at 18:59
  • $\begingroup$ Tangential to the original Q: is it possible to print notebooks w/ color highlighting? $\endgroup$ May 1, 2012 at 19:25

Your Answer

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

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