Upgrade to Latte 2.0Latte 2.0 contains two changes incompatible with earlier versions. If you've used earlier versions of Latte, you may need to make the following two simple adjustments in your Latte files. The changes involve the way user-defined functions are computed. In earlier versions, the result of invoking a user-defined function was an implicitly constructed group containing the values of all of the body's subexpressions. Example:
Invoking this as {\foo 17} produced a group containing The, value, of, x, is, and 17. The new behavior is for user-defined functions to evaluate all
subexpressions but return only the last one. So the example
function The first changeFunctions like this can be restored to their correct behavior by enclosing the body of the function with an extra pair of braces, like so:
Now the last subexpression of \foo is the only subexpression and contains all of the desired text. Note: it should not be necessary to change the way these functions are used, only the way they are defined. The second changeThe bodies of \let expressions are treated the same way as the bodies of function definitions. So in a \let expression like this:
older versions of Latte would produce
but Latte 2.0 produces only 17 (the last subexpression of the body). To preserve the old behavior, wrap the body in a pair of braces:
Why did we make this change?The behavior of pre-2.0 versions of Latte introduced an ambiguity in certain functions, ones that sometimes returned a group and sometimes returned some other kind of value. Other code wishing to call such functions could never be sure whether the group being returned was actually the desired return value or merely contained the desired return value. As a result, it was very difficult to write Latte code that dealt with structured data, such as groups containing groups. The new behavior eliminates this ambiguity, and makes it possible to write functions not all of whose subexpressions are contained in the result (something that is often desirable). It also corresponds more closely to the behavior of other similar languages. In order to help detect user-defined functions and \let expressions that probably need to be adjusted, we've invented a new kind of error called "useless subexpression." When you invoke a function or \let expression that contains subexpressions that are not part of the return value and that have no other effects (such as setting variables or calling other functions), Latte now signals a "useless subexpression" error. So a function definition like the first \foo, above, would signal a ``useless subexpression'' error as soon as the subexpression The is reached---it's not part of the return value, and it doesn't have any other effects.
|