calc: Composition Basics
7.8.10.1 Composition Basics
...........................
Compositions are generally formed by stacking formulas together
horizontally or vertically in various ways. Those formulas are
themselves compositions. TeX users will find this analogous to TeX’s
“boxes.” Each multi-line composition has a “baseline”; horizontal
compositions use the baselines to decide how formulas should be
positioned relative to one another. For example, in the Big mode
formula
2
a + b
17 + ------
c
the second term of the sum is four lines tall and has line three as its
baseline. Thus when the term is combined with 17, line three is placed
on the same level as the baseline of 17.
Another important composition concept is “precedence”. This is an
integer that represents the binding strength of various operators. For
example, ‘*’ has higher precedence (195) than ‘+’ (180), which means
that ‘(a * b) + c’ will be formatted without the parentheses, but ‘a *
(b + c)’ will keep the parentheses.
The operator table used by normal and Big language modes has the
following precedences:
_ 1200 (subscripts)
% 1100 (as in n%)
! 1000 (as in !n)
mod 400
+/- 300
!! 210 (as in n!!)
! 210 (as in n!)
^ 200
- 197 (as in -n)
* 195 (or implicit multiplication)
/ % \ 190
+ - 180 (as in a+b)
| 170
< = 160 (and other relations)
&& 110
|| 100
? : 90
!!! 85
&&& 80
||| 75
:= 50
:: 45
=> 40
The general rule is that if an operator with precedence ‘n’ occurs as
an argument to an operator with precedence ‘m’, then the argument is
enclosed in parentheses if ‘n < m’. Top-level expressions and
expressions which are function arguments, vector components, etc., are
formatted with precedence zero (so that they normally never get
additional parentheses).
For binary left-associative operators like ‘+’, the righthand
argument is actually formatted with one-higher precedence than shown in
the table. This makes sure ‘(a + b) + c’ omits the parentheses, but the
unnatural form ‘a + (b + c)’ keeps its parentheses. Right-associative
operators like ‘^’ format the lefthand argument with one-higher
precedence.
The ‘cprec’ function formats an expression with an arbitrary
precedence. For example, ‘cprec(abc, 185)’ will combine into sums and
products as follows: ‘7 + abc’, ‘7 (abc)’ (because this ‘cprec’ form has
higher precedence than addition, but lower precedence than
multiplication).
A final composition issue is “line breaking”. Calc uses two
different strategies for “flat” and “non-flat” compositions. A non-flat
composition is anything that appears on multiple lines (not counting
line breaking). Examples would be matrices and Big mode powers and
quotients. Non-flat compositions are displayed exactly as specified.
If they come out wider than the current window, you must use horizontal
scrolling (‘<’ and ‘>’) to view them.
Flat compositions, on the other hand, will be broken across several
lines if they are too wide to fit the window. Certain points in a
composition are noted internally as “break points”. Calc’s general
strategy is to fill each line as much as possible, then to move down to
the next line starting at the first break point that didn’t fit.
However, the line breaker understands the hierarchical structure of
formulas. It will not break an “inner” formula if it can use an earlier
break point from an “outer” formula instead. For example, a vector of
sums might be formatted as:
[ a + b + c, d + e + f,
g + h + i, j + k + l, m ]
If the ‘m’ can fit, then so, it seems, could the ‘g’. But Calc prefers
to break at the comma since the comma is part of a “more outer” formula.
Calc would break at a plus sign only if it had to, say, if the very
first sum in the vector had itself been too large to fit.
Of the composition functions described below, only ‘choriz’ generates
break points. The ‘bstring’ function (Strings) also generates
breakable items: A break point is added after every space (or group of
spaces) except for spaces at the very beginning or end of the string.
Composition functions themselves count as levels in the formula
hierarchy, so a ‘choriz’ that is a component of a larger ‘choriz’ will
be less likely to be broken. As a special case, if a ‘bstring’ occurs
as a component of a ‘choriz’ or ‘choriz’-like object (such as a vector
or a list of arguments in a function call), then the break points in
that ‘bstring’ will be on the same level as the break points of the
surrounding object.