The No Latte Language
This will be the complete language reference. I've found that a text search (with my browser) on this manual works the best, hence I have not split it up into separate sections.
If this page does not answer your question, you can read the original Latte User Manual. There is only one significant difference: No Latte does not have a macro system (yet). Otherwise, the two languages should be quite compatible.
Latte Examples
An XHMTL document using No Latte consists of two parts: the
head
and the body
. (The
DOCTYPE
and <html>
tags are added
automatically.)
Consider this example:
{\head {\title Hello, World!}} {\body {\h1 Hello, World!} I would like to say hello to the world. }
We can process it through nolatte-html
:
% nolatte-html helloworld.latte > helloworld.html
The resulting file will have this XHTML:
<html> <head><title>Hello, World!</title></head> <body> <h1>Hello, World!</h1> <p>I would like to say hello to the world.</p> </body> </html>
(A DOCTYPE
is also added along with some "generated
by" meta
tags in the head
, but those are
unimportant details for now.)
Markup is done with curly braces {
and
}
and with functions—\head
,
\title
, and \body
in this example. In
this case, the functions used map directly to their equivalent
XHTML tags.
Notice that raw text is the normal input in a No Latte program. This is in contrast to PHP and CGI Perl where you must explicitly print the XHTML from the source language. Printing the text is the default action with No Latte.
Also note that a paragraph tag was put around the one paragraph
of text in the input file. The paragraph-tag inserter is
smart—to the point of generating validated XHTML! Only the
text in the <body>
tag is given paragraph tags;
the <head>
is never considered for paragraph
tags. Also, the <h1>
was ignored because it
should never contain or be contained in paragraph tags.
As seen in this simple example, there is already a savings since
each close tag (e.g., </body>
) turns into a
single right curly brace. There's another significant savings to be
had: function abstraction. Generally, you will repeat the
<head>
and <body>
information
in each page of your website; if you duplicate by hand on each
page, it makes it harder to maintain and debug. No Latte allows you
to create a function to abstract out the boilerplate:
{\def \my-page {\lambda {\the-title \&content} {\group {\head {\title \the-title}} {\body {\h1 \the-title} \content } }}}
This function could go into a file template.latte
which is included in the real pages:
{\load-file template.latte} {\my-page {Hello, World!} I would like to say hello to the world. }
You can now imagine more abstraction and many more pages which can greatly simplify the overall website.
No Latte Syntax
No Latte is an expression-based language. That is, a No Latte program consists of an expression which is evaluated, and the result of this evaluation is XHTML (hopefully).
A No Latte expression can be many different things:
- Whitespace is a sequence of spaces, tabs, and newlines.
- A word is a sequence of characters not
including whitespace or the backslash: e.g.,
Hello,
andWorld!
. - A quoted word is any sequence of characters
(including whitespace) inside escaped double-quotes: e.g.,
\" Hello\"
is a single word consisting of two spaces followed byHello
. - A variable is a backslash followed by letters and
digits and certain punctuation (
+
,-
,_
,?
,!
): e.g.,\head
,\title
,\the-title
,\set!
,\equal?
. - A group is a list of other No Latte expressions,
starting with a left curly brace and ending with a right curly
brace: e.g.,
{\h1 \the-title}
,{\sort {4 9 2 3}}
.
Each of these expression types are covered in more detail in this section of the language manual.
Comments
A comment in No Latte is started with \;
, and
extends to the end of the line.
{\h1 Hello, World!} \; Not seen in the output. This is seen.
Words
In No Latte, words are sequences of interesting
characters. Whitespace, in this context, is actually considered
too interesting, and it's discussed later in this language
manual. Any character is considered text-worthy except for
whitespace and special metacharacters (the blackslash
\
and the curly braces, {
and
}
). Special characters can be escaped to be considered
part of a word. No Latte always makes the largest word it can.
Consider this example (modified from the original Latte User Manual):
In a No Latte "word", you must use \\ to escape \\, \{, and \}.
This turns into fifteen text clumps:
In
a
No
Latte
"word",
you
must
use
\\
to
escape
\\,
\{,
and
\}.
A quoted word is characters surrounded by escaped double-quotes like so:
\"This is a single word.\"
As indicated by the example itself, despite the spaces
separating the English words, No Latte treats this as one
word. This allows you to capture any whitespace you want very
precisely. (See the later section on whitespace handling.) You can
even specify the empty word: \"\"
.
The original Latte (and early versions of No Latte) required you to escape the backslash even in a quoted word. This is no longer necessary.
A quoted word also allows you to enter metacharacters without
escaping them: \"\{}\"
versus \\\{\}
.
Both result in the word \{}
. Not having to escape
metacharacters makes this very useful when typesetting
code.
Variables
A variable stores away one value. All variables in No Latte must be declared, and there are three ways to declare a variable.
Defintiions
A variable can be declared at the top level with a definition:
{\def \variable-name expression}
\def
is a reserved word and can be used only for a
defintion; \variable-name
is the name of your
variable; expression
is any valid No Latte
expression. The expression is evaluated and that value is bound to
the variable. Whenever the variable is used later in the program,
the bound value is used. Variables can be defined only once; they
can be used everywhere.
Valid Variables
A variable always starts with a backslash followed by a
letter or special punctuation (underscore _
, hyphen
-
, question mark ?
, and exclamation point
!
). You may follow those two characters with any
letter, any digit, and any special punctunation.
Let Expressions
The second way to declare a variable is with a \let
expression:
{\let {{\variable1 expression1} {\variable2 expression2} ... {\variableN expressionN}} body }
The expressions are all evaluated first, and then they are bound
to the variables. Then the body (which can be multiple expressions,
although only the last expression's value is returned) is
evaluated. The variables of a \let
are lexically
scoped: they are valid only in the body; they are
not valid in any functions that the body calls; they are
not valid after the body is finished; they shaddow any previous
definitions.
Changing a Variable
The value bound to a variable can be changed with a
\set!
expression.
{\set! \variable expression}
The expression is evaluated, and that value is bound to
the specified variable; the old value is thrown away. It is
unspecified what \set!
returns; it's sole purpose is
for side-effects. \set!
can be used on any variable,
whether defined with a \def
, a \let
, or a
function.
Function Parameters
The last way to declare a variable is as a function parameter.
Like \let
-bound variables, function-bound variables
are only valid in the body of the declaring expression.
Unlike the original Latte, No Latte requires that you have at least as many arguments as positional parameters. (Latte would set "unused" positional parameters to the empty group.) Excess arguments are collected in a rest parameter (see below).
No Latte supports three kinds of parameters. The standard parameter type is the positional parameter:
{\def \foo {\lambda \x \y \z {\add \x {\subtract \y \z}} } }
In this example, \x
, \y
, and
\z
are positional parameters. When \foo
is invoked like so: {\foo 1 2 3}
, \x
is
bound to 1
, \y
is bound to
2
, and \z
is bound to 3
. In
most programming languages, this is the only kind of parameter
supported; it's the standard parameter type in mathematics.
A named parameter must be explicitly named when the function is called. For example:
{\def \foo {\lambda \=x \=y \=z {\add \x {\subtract \y \z}} } }
The equals sign in the identifiers is required in the
parameter list of the \lambda
, but it must be
dropped in the body. To invoke this function, the bindings must be
more explicit, but can come in any order: {\foo \x=3 \z=5
\y=9}
will ultimately compute 3+(9-5)
.
By default, a named parameter is bound to an empty group; any explicit assignment when the function is called overrides this default.
No Latte may or may not warn you if you have excess arguments and no rest parameter.
Finally, if there are more arguments than positional parameters, the remaining arguments are collected together in a group and assigned to a rest parameter. This is very handy for processing large amounts of text:
{\def \my-body {\lambda \&text {\body {\i \text}} } }
Again, similar to named parameters, the special character
&
is used only in the parameter list. Now this
function can be called with any number of arguments, all of which
are grouped together and bound to \text
:
{\my-body This is valid.}
and {\my-body This
longer text is also valid.}
.
These three parameter types can be used in any combination. Positional parameters can be intermixed with named parameters any which way; the rest parameter (if there is one) must be last. You can have as many positional and named parameters as you like; there can be at most one rest parameter.
Groups
Technically, a group corresponds to an array in C, C++, or Java, but it's much better and accurate to think of them as LISP- or Scheme-style lists.
The most basic and sole data structure in No Latte is the group.
A group consists of zero or more subexpressions (or subvalues).
Syntactically, a group is surrounded by curly braces,
{
and }
.
The first purpose of a group is to collect values:
{Hello there}
is a group consisting of two words (plus some whitespace which we're ignoring for now). This is useful and necessary in many situations:
{\def \foo {Hello there}} {\bar \x={Hello there}}
In the first case, the definition wouldn't even parse without
curly braces; you must have exactly one expression in a
definition. In the second case, \x
will be bound to
the whole group; without the curly braces, \x
would be
bound just to Hello
, and there
would be
bound to a positional parameter.
Groups are also used for invoking functions. As seen in the last
example, \bar
is probably a function that has (at
least) one named parameter (\x
) and no positional
parameters. Previous examples included function calls to
\add
and \subtract
.
The type of group is determined at runtime: the subexpressions
are evaluated, and if the first element of the group can be applied
in some way (either a primitive or a function), then it is applied
using the rest of the group as an argument list; otherwise, the
group is returned as evaluated. So, technically,
\bar
in the last example could actually just evalute
to some word or another group, in which case the group is
returned.
Whitespace
Normally, whitespace is not considered primary data in No Latte; the only time it is considered primary data is when it's found in a quoted word. Otherwise, whitespace is attached to the expression that follows it.
Consider this example (taken from the original Latte manual):
{\document {Our second document} This was as exciting to write as our first!}
No Latte sees this:
- A group with no whitespace in front of it; the group consists
of the following:
- A variable reference
\document
with no whitespace in front of it. - A group with a single space in front of it; the group consists
of the following:
- The word
Our
with no whitespace in front of it. - The word
second
with one space in front of it. - The word
document
with one space in front of it.
- The word
- The word
This
with a newline and two spaces in front of it. - The word
was
with a single space in front of it. - The word
as
with a single space in front of it. - ...
- The word
write
with a newline and two spaces in front of it. - ...
- The word
first!
with a single space in front of it.
- A variable reference
All expressions (including the groups) have whitespace attached to them. All of the preceeding whitespace (including newlines, spaces, and tabs) are attached to an expression. The expressions carry this whitespace with them, but it may not actually be used, depending on the larger context.
In general, the whitespace is discarded if the expression is evaluated in a new context. For example,
{\def \foo Hello} .\foo. : \foo:
This evaluates to
.Hello. : Hello:
In both cases, the whitespace captured before
Hello
is dropped when \foo
is evaluated.
The only whitespace in the output comes from the last evaluated
context.
\if
expressions also discard attached
whitespace:
{\def \bar Hello} {\def \baz Hello} ${\if \foo \bar \baz}$
will always evaluate to $Hello$
(assuming
\foo
is defined somewhere). Not only is the whitespace
from the definitions discarded, but the whitespace within the
\if
itself is discarded.
In Latte, the "kill whitespace" sequence could be used anywhere
in whitespace; it must
appear just before a real
expression in No Latte.
To improve the readability of your No Latte documents, you may
want to add whitespace that does not appear in the final
document. The sequence \/
will kill all of the
previous whitespace; this must be done at the end of the
whitespace, just before an expression. Using HTML Tidy eliminates a
lot of whitespace, so it is usually not necessary to worry to much
about excess whitespace.
No Latte Builtins
This section of the manual describes the basic builtins to the No Latte language. This includes the control structures, primitives, and basic functions in No Latte.
Each built-in has a level of flexibility
- Language constructs are built directly into No Latte and cannot be changed; any explicit identifiers in a pattern for a language construct are reserved words and cannot be used for anything except for the specified language construct.
- Primitives are operations that are built into No Latte itself, but their identifiers can be reassigned by you if you really want to.
- Basic functions are functions defined in the No Latte standard libraries. They're no more special than the functions that you or anyone else might define.
Control Structures
If Expression
{\if test then else}
Evalutes test. If the test value is true (i.e., not an empty group), the then expression is evaluated and that value is returned; otherwise (i.e., the test value was an empty group), the else expression is evaluated and that value is returned.
If else is left out, the empty group is used by default.
Cond Expression
{\cond clause1 clause2 ... clauseN}
Like the LISP and Scheme construct, the clauses of a
\cond
are turned into a nested if-then-else. In pseudo-code, it is equivalent toif first element of clause1 is true return rest of clause1 else if first element of clause2 is true return rest of clause2 else ... else if first element of clauseN is true return rest of clauseN else return the empty groupFor example:
{\cond {{\lt? \x \y} less than!} {{\gt? \x \y} greater than!} {else equals!} }A description of the relationship between
\x
and\y
is returned by this expression. The wordelse
in the last clause is always true which makes it a very readable default clause.
While Loop
{\while test body}
As in other languages, the test is evaluated first, and if it is immediately false, it returns an empty group. Otherwise, the body is evaluated (which may consist of multiple expressions), and then the test is re-evaluated. This continues until the test fails; at that point, the accumulated evaluations of the body are returned as one group.
For example:
{\let {{\i 0}} {\while {\lt? \i 3} i is \i. \/{\set! \i {\add \i 1}} } }This evaluates to:
i is 0. i is 1. i is 2.
Foreach Loop
{\foreach \variable group body}
The group expression is evaluated for a group; the body is then evaluated once for each element in the group, binding \variable to the current value from the group. The results from each evaluation are gathered together into one group which is returned as the result of the
\foreach
expression.For example:
{\foreach \i {1 2 3} {\add \i 1} }evaluates to
2 3 4
More than likely, you will find the
\lmap
function more useful for simple operations like this one.
Built-ins for Variables
Basic Defintion
{\def \variable expression}
The expression is evaluated and a new variable named
\variable
is defined at the global level. This variable cannot be re-declared with a\def
; it can be shadowed with a\let
or\lambda
—the global is restored when the shadowed version goes out of scope.The expression must be exactly one expression. Anything else is an error.
Alternative Function Definition
{\def {\variable parameters} body}
This is an alternative syntax for declaring functions; it is equivalent to this:
{\def \variable {\lambda {parameters} body }}See the section on
\lambda
for more information about parameters and body.
Let Expression
{\let {{\variable1 expression1} {\variable2 expression2} ... {\variableN expressionN}} body }
All of the expressionI are evaluated first, then each value is bound to the corresponding
\variableI
. (This means that the\variableI
are not in effect while evaluting the binding expressions.) With these new bindings, body is evaluated, and the value of its last expression is returned. The new bindings are discarded when evaluation of the body is completed.For the record, the
\let
above can be re-written as a direct application of a\lambda
:{{\lambda {\variable1 ... \variableN} body } expression1 ... expressionN }See the section on
\lambda
for more information about body.
Set Bang!
{\set! \variable expression}
Like a basic definition, the one expression is evaluated, and the value is bound to \variable; unlike a basic definition, \variable must have been defined before (by a definition, a let, or a lambda); its old binding is tossed and replaced with the new value. The new binding stays in effect as long as the scope of the affected declaration. It is an error if \variable is undeclared.
Consider this example:
{\def \x 5} {\let {{\x 99}} {\set! \x 123124} \x} \xThis evaluates to
123124 5
. The\set!
only affects the let-bound\x
, so the global\x
stays set to5
. There is no way in the body of the\let
to access the\x
declared in the global scope (with or without a\set!
).
Built-Ins for Functions
The basic building block for functions is the
\lambda
expression.
Lambda Expression
{\lambda {parameters} body}
By itself, a lambda expression only creates what's known technically as a closure. The upshot is that a closue is something that can be evaluated later with some values that we pick later, and it works the way we expect.
Early versions of the original Latte would return the values from all of the expressions in the body; No Latte follows the semantics of the latter versions of Latte, returning the value of the last expression only.
parameters can include positional, named, and rest parameters (as described earlier). body can consist of multiple expressions, although only the value of the last expression is returned when the closure is applied.
This is a common mistake (something I still do myself!):
{\def \my-content {\lambda {\&text} {\h1 Welcome} \text Good bye! } }Now
{\my-content whatever}
always evaluates tobye!
no matter what we put in for whatever!!! This is because that one word is the last expression in the body. To get the effect we probably want, this body should be explicitly grouped:{\def \my-content {\lambda {\&text} {\group {\h1 Welcome} \text Good bye! } } }This is so that
\set!
and other side effects can be put into the body of a lambda (or let) without worrying about what they evaluate to.
\funcall
{\funcall function arguments...}
\funcall
first evaluates function and the arguments; then it applies the function-value to the evaluates arguments. An example:{\funcall \add 2 3 4}evaluates to
9
. Frankly, it's the same leaving\funcall
out (although using\funcall
might be slightly slower).
\apply
{\apply function arguments... last-argument}
\apply
works the same as\funcall
except that if last-argument evaluates to a group, the elements of that group are used as further arguments. Consequently, all of these evaluate to9
:{\apply \add 2 3 4} {\apply \add 2 3 4 {}} {\apply \add 2 3 {4}} {\apply \add 2 {3 4}} {\apply \add {2 3 4}}Of course, any of those elements could be more interesting expressions, and the group itself might be the result of some expression.
\compose
{\compose function1 function2}
\compose
returns an expression equivalent to this:{\lambda {\x} {function1 {function2 \x}}}function1 and function2 must both evaluate to functions of one parameter (positional or rest, not named).
\lmap
{\lmap function group}
function is evaluated for a function of one parameter (positional or rest, not named), and group is evaluated for a group (of course).
\lmap
then applies the function to each element of the group, and returns a new group with the results. (Scheme and LISP call this functionmap
; Ruby calls iteach
.)For example,
{\lmap {\lambda {\x} {\add \x 1}} {3 4 5}}evaluates to
4 5 6
.
Group Functions
\append
{\append arguments...}
Each of the arguments are evaluated first, then they are combined into a group. If an evaluated argument is a group, the elements of that group are added directly to the result; otherwise, the evaluated argument itself is added.
For example:
{\append a b {c d} {e {f} g} h}evaluates to
{a b c d e {f} g h}
. As evident from{f}
,\append
does not flatten all groups, just the top ones.
\back
{\back group}
Synonym for
\rac
.
\car
{\car group}
\car
evaluates the group expression, and returns the first element. (Just like the LISP/Scheme function of the same name.)For example,
{\car {a b c}}evaluates to
a
.Synonym for
\front
.
\cdr
{\cdr group}
\cdr
evaluates group for a group and returns a new group with all but the first element from the original group. (Just like the LISP/Scheme function of the same name.)For example,
{\cdr {a b c}}evaluates to
{b c}
.The new group is a true copy of the original.
\caar
, \cadr
, \cdar
,
\cddr
{\caar group}
Composition of
\car
and\cdr
; e.g.,\cdar
is{\compose \cdr \car}
.
\cons
{\cons head tail}
Returns a new group with
head
added to the beginning oftail
. (The originaltail
is not changed.) Synonym for\push-front
.
\empty?
{\empty? group}
Returns true if the group is empty, false otherwise.
\front
{\front group}
Returns the first element of the group; synonym for
\car
.
\group
{\group element...}
Yields a new group consists of the specified elements.
\lenth
{\length group}
Returns the number of elements in the group. Overloaded to also work with text strings.
\member?
{\member? element group}
Yields true if the element is a member of the group (as determined by
\equal?
), false otherwise.
\nth
{\nth group}
Yields the nth element of the group, starting with index 0. Negative indices count from the end of the group backwards. Overloaded to work with text strings.
\push-back
{\push-back element group}
Adds the element to the end of the group, and returns that new group (without affecting the original group). Synonym for
\snoc
.
\push-front
{\push-front element group}
Adds the element to the front of the group, and returns that new group (without affecting the original group). Synonym for
\cons
.
\rdc
{\rdc group}
Returns the elements of the group except the last.
\reverse
{\reverse group}
Reverses the elements of the group. Nested groups are not reversed. For example:
{\reverse {a b c}} => {c b a} {\reverse {a {b c} d}} => {d b c a}
\snoc
{\snoc element group}
Adds the element to the end of the elements.
\subseq
{\subseq group from to}
Returns a subsequence from the group, starting at index
from
up to (but not including) indexto
. The indices can be negative (and thus counted from the end of the group);to
can be omitted and defaults to the length of the group (i.e., through to the last element).Exampes:
{\subseq {a b c d e} 1 3} => {b c} {\subseq {a b c d e} -2} => {d e}
Boolean Functions
The empty group {}
is false; everything
else is true.
\and
{\and expressions...}
Evaluates the expressions, and returns the last value if they all evaluate to anything but the empty group. An empty group is any one of the evaluations result in one. In other words, it returns a true value if all the expressions result in true evaluations; false otherwise. Presently, this is not a short-circuiting evaluation; all of the expressions are evaluated.
\not
{\not expression}
Evaluates the expression, and logically negates it. You are only guaranteed that
{\not {}}
is some true value, so if it happens to be the texttrue
now, not plan on it for the future.
\or
{\or expressions...}
Evaluates the expressions, and returns the first value that evaluates to true. An empty group (i.e. a false value) is returned if all evaluations are false. Presently, this is not a shirt-circuiting evaluation; all of the expressions are evaluated.
Text Functions
Keep in mind how No Latte treats whitespace. In the case of
function arguments, whitespace is merely a separator between
arguments. If you want whitespace in the results, you may have to
quote them with explicit quotes, e.g., \"
.
\concat
{\concat text...}
Evaluates the arguments as text, and concatenates the results together. If any arguments are not text, the function results in an error. Synonym for
\string-append
.
\downcase
{\downcase text...}
Evaluates the arguments as text, and returns the lower-case equivalents in a group.
\explode
{\explode text...}
Evaluates the arguments as text, and constructs a group consisting of the characters of all of the text strings.
\length
{\length text}
Returns the number of character in
text
.\length
is overloaded to also work with a group, so be careful what you pass to it.
\nth
{\nth index text}
Returns the character at the specified index (with 0-based indexing).
\nth
is overloaded to also handle groups.
\string-append
{\string-append text...}
Evaluates to the concatenation of all of the text strings. Synonym for
\concat
.
\string-ge?
{\string-ge? text...}
Synonym for
\string-greater-equal?
.
\string-greater-equal?
{\string-greater-equal? text...}
Evaluates to true if each text string is greater than or equal to the one after it. If the comparison ever fails, false is returned. If one of the arguments is not text, an error is generated. Synonym for
\string-ge?
.
\string-greater?
{\string-greater? text}
Evaluates to true if each text string is greater than the one after it. Otherwise, it evaluates to false. Synonym for
\string-gt?
.
\string-gt?
{\string-gt? text}
Synonym for
\string-greater?
.
\string-le?
{\string-le? text...}
Synonym for
\string-less-equal?
.
\string-less-equal?
{\string-less-equal? text...}
Evaluates to true if each text string is less than or equal to the next; otherwise it evaluates to false. Synonym for
\string-le?
.
\string-less?
{\string-less? text...}
Evaluates the arguments as text; evaluates (as a whole) to true if each text is less than the next; otherwise it evaluates to false. Synonym for
\string-lt?
.
\substr
{\substr text from to}
Evaluates to a substring of
text
, starting at indexfrom
up to (but not including) indexto
. Indexing is 0 based; negative indexes are counted backwards from the end of the string. Ifto
is omitted, the end of the string is used implied.Examples:
{\substr abcde 1 3} => bc {\substr abcde -2} => de
\upcase
{\upcase text...}
Evaluates to a group of text where each original text string is converted to all uppercase letters.
Arithmetic Functions
All arithmetic in No Latte is integer based.
\add
{\add number...}
Adds together all of the given numbers.
\divide
{\divide number...}
Divides the numbers from left to right. Division by zero triggers an error.
\ge?
{\ge? number...}
Synonym for
\greater-equal?
.
\greater-equal?
{\greater-equal? number...}
Evaluates to true if each number is greater than or equal to the next; otherwise, evaluates to false. Synonym for
\ge?
.
\greater?
{\greater? number...}
Evaluates to true if each number is greater than the next; otherwise, it evaluates to false. Synonym for
gt?
.
\gt?
{\gt? number...}
Synonym for
\gt?
.
\le?
{\le? number...}
Synonym for
\less-equal?
.
\less-equal?
{\less-equal? number...}
Evaluates to true if each number is less than or equal to the next; false, otherwise. Synonym for
\le?
.
\less?
{\less? number...}
Evaluates to true if each number is less than the next; false, otherwise. Synonym for
\lt?
.
\lt?
{\lt? number...}
Synonym for
\less?
.
\modulo
{\modulo a b}
Evaluates to the modulus of
a
andb
.
\multiply
{\multiply number...}
Returns the product of the numbers.
\random
{\random n}
Returns a random integer greater than or equal to 0 and less than
n
.
\subtract
{\subtract number...}
If a single number is given, returns the negative value of that number. Otherwise, starting with the first number, each subsequent number is subtracted from it.
\zero?
{\zero? number}
Evaluates to true if
number
is 0;false
, otherwise.
File Functions
\file-contents
{\file-contents filename}
Returns, as a text string, the contents of the specified file.
\process-output
{\process-output program arg...}
Runs the
program
on the system with the specified arguments; output of the program is returned a text string. Does not work on Windows machines. Yet.
\load-file
{\load-file filename}
Evaluates the contents of the specified file as No Latte code. Textual results are discard, but all definitions and side effects take effect.
\load-library
{\load-library filename}
Like
\load-file
, evaluates the contents of the file, and only definitions and side-effects have effect.The primary difference is that
\load-library
will search for the file in the "No Latte path". By default, this is/usr/local/share/latte
and.
; it can be set by setting the environment variableLATTE_PATH
.
\include
{\include filename}
Evaluates the content of the specified file as No Latte code. Both textual results and side effects are included in the output and further execution.
Other Functions
\equal?
{\equal? value...}
Returns true if all of the values are equal (deeply so);
false
, otherwise.
\error
{\error text...}
Exits from the interpreter with the specified text as an error message.
\group?
{\group? value}
Return true if the value is a group,
false
otherwise.
\operator?
{\operator? value}
Return true if the value is an operator (i.e., a function),
false
otherwise.
\string?
{\string? value}
Return true if the value is a text string,
false
otherwise.
\warn
{\warn text...}
Emits a warning message on the standard error as specified by the text arguments.
Predefined Variables
\__latte-version__
Contains the version number of the No Latte interpreter.
{\__latte-version} => No Latte 0.3alpha
© 2007. Developer and
website author: Jeremy D.
Frens
This website is licensed under a Creative
Commons Attribution-Noncommercial-Share Alike 3.0
License