Next: , Previous: More About Embedded Mode, Up: Embedded Mode

16.3 Assignments in Embedded Mode

The ‘:=’ (assignment) and ‘=>’ (“evaluates-to”) operators are especially useful in Embedded mode. They allow you to make a definition in one formula, then refer to that definition in other formulas embedded in the same buffer.

An embedded formula which is an assignment to a variable, as in

     foo := 5

records ‘5’ as the stored value of foo for the purposes of Embedded mode operations in the current buffer. It does not actually store ‘5’ as the “global” value of foo, however. Regular Calc operations, and Embedded formulas in other buffers, will not see this assignment.

One way to use this assigned value is simply to create an Embedded formula elsewhere that refers to foo, and to press = in that formula. However, this permanently replaces the foo in the formula with its current value. More interesting is to use ‘=>’ elsewhere:

     foo + 7 => 12

See Evaluates-To Operator, for a general discussion of ‘=>’.

If you move back and change the assignment to foo, any ‘=>’ formulas which refer to it are automatically updated.

     foo := 17
     
     foo + 7 => 24

The obvious question then is, how can one easily change the assignment to foo? If you simply select the formula in Embedded mode and type 17, the assignment itself will be replaced by the 17. The effect on the other formula will be that the variable foo becomes unassigned:

     17
     
     foo + 7 => foo + 7

The right thing to do is first to use a selection command (j 2 will do the trick) to select the righthand side of the assignment. Then, 17 <TAB> <DEL> will swap the 17 into place (see Selecting Subformulas, to see how this works).

The C-x * j (calc-embedded-select) command provides an easy way to operate on assignments. It is just like C-x * e, except that if the enabled formula is an assignment, it uses j 2 to select the righthand side. If the enabled formula is an evaluates-to, it uses j 1 to select the lefthand side. A formula can also be a combination of both:

     bar := foo + 3 => 20

in which case C-x * j will select the middle part (‘foo + 3’).

The formula is automatically deselected when you leave Embedded mode.

Another way to change the assignment to foo would simply be to edit the number using regular Emacs editing rather than Embedded mode. Then, we have to find a way to get Embedded mode to notice the change. The C-x * u (calc-embedded-update-formula) command is a convenient way to do this.

     foo := 6
     
     foo + 7 => 13

Pressing C-x * u is much like pressing C-x * e = C-x * e, that is, temporarily enabling Embedded mode for the formula under the cursor and then evaluating it with =. But C-x * u does not actually use C-x * e, and in fact another formula somewhere else can be enabled in Embedded mode while you use C-x * u and that formula will not be disturbed.

With a numeric prefix argument, C-x * u updates all active ‘=>’ formulas in the buffer. Formulas which have not yet been activated in Embedded mode, and formulas which do not have ‘=>’ as their top-level operator, are not affected by this. (This is useful only if you have used m C; see below.)

With a plain C-u prefix, C-u C-x * u updates only in the region between mark and point rather than in the whole buffer.

C-x * u is also a handy way to activate a formula, such as an ‘=>’ formula that has freshly been typed in or loaded from a file.

The C-x * a (calc-embedded-activate) command scans through the current buffer and activates all embedded formulas that contain ‘:=’ or ‘=>’ symbols. This does not mean that Embedded mode is actually turned on, but only that the formulas' positions are registered with Embedded mode so that the ‘=>’ values can be properly updated as assignments are changed.

It is a good idea to type C-x * a right after loading a file that uses embedded ‘=>’ operators. Emacs includes a nifty “buffer-local variables” feature that you can use to do this automatically. The idea is to place near the end of your file a few lines that look like this:

     --- Local Variables: ---
     --- eval:(calc-embedded-activate) ---
     --- End: ---

where the leading and trailing ‘---’ can be replaced by any suitable strings (which must be the same on all three lines) or omitted altogether; in a TeX or LaTeX file, ‘%’ would be a good leading string and no trailing string would be necessary. In a C program, ‘/*’ and ‘*/’ would be good leading and trailing strings.

When Emacs loads a file into memory, it checks for a Local Variables section like this one at the end of the file. If it finds this section, it does the specified things (in this case, running C-x * a automatically) before editing of the file begins. The Local Variables section must be within 3000 characters of the end of the file for Emacs to find it, and it must be in the last page of the file if the file has any page separators. See Local Variables in Files.

Note that C-x * a does not update the formulas it finds. To do this, type, say, M-1 C-x * u after C-x * a. Generally this should not be a problem, though, because the formulas will have been up-to-date already when the file was saved.

Normally, C-x * a activates all the formulas it finds, but any previous active formulas remain active as well. With a positive numeric prefix argument, C-x * a first deactivates all current active formulas, then actives the ones it finds in its scan of the buffer. With a negative prefix argument, C-x * a simply deactivates all formulas.

Embedded mode has two symbols, ‘Active’ and ‘~Active’, which it puts next to the major mode name in a buffer's mode line. It puts ‘Active’ if it has reason to believe that all formulas in the buffer are active, because you have typed C-x * a and Calc has not since had to deactivate any formulas (which can happen if Calc goes to update an ‘=>’ formula somewhere because a variable changed, and finds that the formula is no longer there due to some kind of editing outside of Embedded mode). Calc puts ‘~Active’ in the mode line if some, but probably not all, formulas in the buffer are active. This happens if you activate a few formulas one at a time but never use C-x * a, or if you used C-x * a but then Calc had to deactivate a formula because it lost track of it. If neither of these symbols appears in the mode line, no embedded formulas are active in the buffer (e.g., before Embedded mode has been used, or after a M-- C-x * a).

Embedded formulas can refer to assignments both before and after them in the buffer. If there are several assignments to a variable, the nearest preceding assignment is used if there is one, otherwise the following assignment is used.

     x => 1
     
     x := 1
     
     x => 1
     
     x := 2
     
     x => 2

As well as simple variables, you can also assign to subscript expressions of the form ‘var_number’ (as in x_0), or ‘var_var’ (as in x_max). Assignments to other kinds of objects can be represented by Calc, but the automatic linkage between assignments and references works only for plain variables and these two kinds of subscript expressions.

If there are no assignments to a given variable, the global stored value for the variable is used (see Storing Variables), or, if no value is stored, the variable is left in symbolic form. Note that global stored values will be lost when the file is saved and loaded in a later Emacs session, unless you have used the s p (calc-permanent-variable) command to save them; see Operations on Variables.

The m C (calc-auto-recompute) command turns automatic recomputation of ‘=>’ forms on and off. If you turn automatic recomputation off, you will have to use C-x * u to update these formulas manually after an assignment has been changed. If you plan to change several assignments at once, it may be more efficient to type m C, change all the assignments, then use M-1 C-x * u to update the entire buffer afterwards. The m C command also controls ‘=>’ formulas on the stack; see Evaluates-To Operator. When you turn automatic recomputation back on, the stack will be updated but the Embedded buffer will not; you must use C-x * u to update the buffer by hand.