Plans

Latte 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:

 {\def {\foo \x} The value of x is \x}

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 \foo, above, produces only 17 with the new version of Latte.

### The first change

Functions like this can be restored to their correct behavior by enclosing the body of the function with an extra pair of braces, like so:

 {\def {\foo \x} {The value of x is \x}}

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 change

The bodies of \let expressions are treated the same way as the bodies of function definitions. So in a \let expression like this:

 {\let {{\x 17}} The value of x is \x}

older versions of Latte would produce

 The value of x is 17

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:

 {\let {{\x 17}} {The value of x is \x}}

### 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.

 This document was produced by Latte from the file upgrade.latte (with extra definitions from style.latte).