11

Say I have a macro that does something in math mode (say, change the mathalphabet). This macro, \somecommand, takes one argument. I might want use is like this, feeding an empty argument into it: \(\somecommand{} +x\). I also want the plus sign before x to be a unary operator.

I find that whether a plus or minus sign is considered unary or binary is, while clear in theory, not always obvious upon first inspection:

\documentclass{article}

\newcommand{\zeroArgCommand}{}
\newcommand{\oneArgCommand}[1]{}

\begin{document}

\noindent
\(                    +x\) \\ % unary:  "+x"
\(\zeroArgCommand     +x\) \\ % unary:  "+x"
\(\zeroArgCommand{}   +x\) \\ % binary: " + x"
\(\oneArgCommand{}    +x\) \\ % unary:  "+x"
\(\oneArgCommand{}{}  +x\) \\ % binary: " + x"

\end{document}

In the light of this, I am wondering about the best way of defining a unary plus/minus sign.

Intuitively I would write \(\somecommand{} {+} x\) or \(\somecommand{} {+ x}\), but I am wondering about expert opinion about a method that for sure works in all contexts.

This question was posed because in another thread, a user suggested that defining a \unaryplus macro is clearer than \somecommand {+} x. (I think what that commenter had in mind was that the reader might not be familiar with the arity of \somecommand.)


Addendum: Is there a good way to define a macro \genuineunaryplus that produces a + but that in a context <before>\genuineunaryplus<after> attaches to <after> as a unary operator but has spacing to <before> exactly as if the \genuineunaryplus were not there? That is, a macro such that if the spacing between <B> <A> is of length/type L, the expression <B>\genuineunaryplus<A> will produce <B> +<A> in the output, with the spacing between <B> and + exactly like the spacing would be between <B> and <A> if the \genuineunaryplus were not there, namely L?

Answer idea for addendum: David Carlisle's comment below outlines a possible answer for this addendum.

  • 1
    Surprisingly, the output is as expected... – Werner Feb 18 '13 at 22:33
  • @Werner See my edit, giving a rationale for the question. – Lover of Structure Feb 18 '13 at 22:38
  • 1
    Why not just use \unaryplus x where \newcommand{\unaryplus}{{+}}? – Werner Feb 18 '13 at 22:49
  • @Werner See my new comments in the thread to David Carlisle's answer. – Lover of Structure Feb 18 '13 at 23:48
  • Again, this is too generic a question. TeX has no concept of "unary operator" in your sense; just an ordinary symbol will do, so \mathord{+} would be the answer, maybe buried in a macro. Using the same symbol for two different purposes is, in general, wrong. If your + has always to behave as unary, then use a different name for it. – egreg Feb 19 '13 at 00:16
  • @egreg I certainly didn't mean to redefine + as \mathord{+}; there might be a misunderstanding, but then my question's motivation wasn't completely clear, though I think the edit (in italics at the bottom) should have cleared that up (it was to give a better outlet for David Carlisle's comment elsewhere, which might have been deleted by now; he suggested that a separate question might be better). Anyways, see also my addendum; I think this is what I actually want. – Lover of Structure Feb 19 '13 at 01:33

1 Answers1

9

The inspection of the math list happens after expansion (and after assignments). It is an extra stage just applicable to math mode that converts the math list into a horizontal list that is then typeset as a normal horizontal list.

So there is no real connection between the macro structure and the math spacing, It does not matter whether the thing to the left of the + has arguments or not, it just matters what it expands to (nothing in your example) so your example is equivalent to

\noindent
\(                    +x\) \\ % unary:  "+x"
\(     +x\) \\ % unary:  "+x"
\({}   +x\) \\ % binary: " + x"
\(    +x\) \\ % unary:  "+x"
\({}  +x\) \\ % binary: " + x"

and as your comments show a binop like + gets binary spacing if it is between two mathord atoms such as {} or x.

Your example (from elsewhere, with \somecommand being a zero-argument macro)

\(\somecommand{} {+} x\) 

is

\({} {+} x\) 

Here the {+} construct makes a mathord so you get no spacing. My comment that this was probably bad markup was mainly related to the trailing {} after \somecommand it is OK to do that habitually in text mode to avoid dropping spaces but in math mode it's usually has an effect.

\(\somecommand{} {+ x}\)

is

\({} {+ x}\)

so here the math list has two, not three, mathord atoms: {} and +x. In this simple case it doesn't affect the spacing, but the inner expression is a single atom, so {+x} (and not x) would take any superscripts etc, and as it is an inner list linebreaking is suppressed and any white space is forced to its natural width (again not relevant here); basically in math node {...} is a box command like \hbox{....}.

There are in fact two choices for a unary math sign, a mathord or a mathop, it's easy to get an ad hoc mathord by using {+} but it is probably more consistent to declare the operators explicitly.

enter image description here

1 $a-+b$

2 $a-{+}b$

3 $a-\mathord{+}b$

4 $a-\mathop{+}b$

5 $x+y$

6 $x{+}y$

7 $x\mathord{+}y$

8 $x\mathop{+}y$

As you see from (1) if two binop atoms are adjacent the second one effectively turns into a mathord so you get the spacing as in (2) or (3) although arguably as a prefix operator giving it mathop spacing (with a small gap before its argument) is more consistent.

either way you don't want to be filling you document expressions with weird {} constructs and \mathxx primitives, just define

\unaryplus{{+}}

or whatever version you like and then use

a + \unaryplus b 

and it will all work out OK.

David Carlisle
  • 757,742
  • What if I would like to juxtapose x and +y, like so: x +y? Not sure whether this is useful for ordinary math, but it might be if x and y are more complicated symbols/expressions and I am using some special, domain-specific notation. Is there a macro definition that will always work? – Lover of Structure Feb 18 '13 at 23:34
  • Just now I realize that this isn't really a matter of creating a unary plus symbol, as I'd like relational spacing on the left and no spacing on the right. As this is what also motivated my question, I'll leave this comment as is, perhaps someone has a good idea that's different from the ad-hoc \(x\;{+}y\), which feels like a hack to me. – Lover of Structure Feb 18 '13 at 23:46
  • @LoverofStructure If you feel that a thick space should go after x, then \(\mathrel{x}+y\) will do what you want. – egreg Feb 19 '13 at 00:04
  • \;{x} isn't a bad thing necessarily just don't use it mid document call that \unaryplus (or whatever name you want) and let your document markup concentrate on the structure and you can fine tune spacing at the end (you may decide \; (thickmuskip) is a bit much and you want medmuskip or whatever, it is easy to change a single definition. – David Carlisle Feb 19 '13 at 00:47
  • You mean \;{+}. You've turned the x by 45° :-) – Lover of Structure Feb 19 '13 at 01:21
  • er yes:-)​​​​​​ – David Carlisle Feb 19 '13 at 01:31
  • @DavidCarlisle Btw see also my addendum to the question. (Sorry for keeping everyone here so busy ... but while I'm at it, I might as well be precise and clear stuff up and help create a complete question/answer pair.) – Lover of Structure Feb 19 '13 at 01:34
  • 1
    answer to addendum is "yes" but that's all you get at this time of night you need to rip apart the code of bm package that works out what type of atom each thing is, the instead of reconstructing a bold version of the same you'd just insert a + can be simpler as it only needs to find the first atom not iterate over a list but it's surprisingly tricky (and even trickier if you want xetex or luatex) to work out the mathclass of mathchardefed tokens. 99 times out of 100 a unary plus is going to be applied to a mathord isn't it? – David Carlisle Feb 19 '13 at 01:50
  • @DavidCarlisle Okay. Is there an easy way to define this under the assumption that the next token is a mathord? That is, there is a dependence on the previous token's math character class only. – Lover of Structure Feb 21 '13 at 16:07
  • 1
    if the next token is a mathord then the space between B and + in B{+}Ais the same as the space between B and A inBA`. So there is nothing to do in that case? – David Carlisle Feb 21 '13 at 16:24
  • @DavidCarlisle Oh, because {+} is a mathord itself, you're right! – Lover of Structure Feb 21 '13 at 19:11
  • @DavidCarlisle Btw, I occasionally miss your comments because they're not @-addressed to me. A question's OP currently doesn't get notifications to comments to answers to his questions. – Lover of Structure Feb 21 '13 at 19:12
  • @DavidCarlisle Now that my question about mixed math character classes has an ingenious answer, is there now an easy way to answer my "Addendum" (see bottom of the original question statement here)? If so, I'm very glad to write a separate question about this. – Lover of Structure May 31 '13 at 23:44
  • 1
    @LoverofStructure you could recycle bm code which looks up the mathclass of the thing following the + but it's a lot of work for little gain, and still falls foul if you do bad markup like \zeroArgCommand{} which introduces spurious mathord atom from the {} – David Carlisle Jun 01 '13 at 00:02