{\page \name={Upgrade to Latte 2.0}
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:
{\example
\{\\def \{\\foo \\x\}
The value of x is \\x\}}
Invoking this as {\tt \{\\foo 17\}} produced a group containing {\tt
The}, {\tt value}, {\tt of}, {\tt x}, {\tt is}, and {\tt 17}.
The new behavior is for user-defined functions to evaluate all
subexpressions but return only the {\em last one}. So the example
function {\code \\foo}, above, produces only {\tt 17} with the new
version of Latte.
{\h3 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:
{\example
\{\\def \{\\foo \\x\}
\{The value of x is \\x\}\}}
Now the last subexpression of {\tt \\foo} is the {\em only}
subexpression and contains all of the desired text.
{\b Note:} it should not be necessary to change the way these
functions are {\em used}, only the way they are {\em defined}.
{\h3 The second change}
The bodies of {\tt \\let} expressions are treated the same way as the
bodies of function definitions. So in a {\tt \\let} expression like
this:
{\example
\{\\let \{\{\\x 17\}\}
The value of x is \\x\}}
older versions of Latte would produce
{\example The value of x is 17}
but Latte 2.0 produces only {\tt 17} (the last subexpression of the
body). To preserve the old behavior, wrap the body in a pair of
braces:
{\example
\{\\let \{\{\\x 17\}\}
\{The value of x is \\x\}\}}
{\h3 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 {\em 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 {\tt \\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 {\tt \\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 {\tt \\foo}, above, would signal a ``useless subexpression''
error as soon as the subexpression {\tt The} is reached---it's not
part of the return value, and it doesn't have any other effects.}