Language Reference
Learn how to read and write Polonio templates, from values and output to reusable page logic.
Start with a template, then add the language features your page needs. Web, storage, and database features are introduced separately in the Runtime guide.
Template Structure
Templates mix literal HTML, emitted as written, with embedded Polonio code. Use the .pol extension for templates.
Code blocks
<%
var title = "Docs"
if title != null
echo title
end
%>
Interpolation + inline echo
<h1>$title</h1>
<p>2 + 3 = <% echo 2 + 3 %></p>
<p>Literal $: write "$$" in text.
<% ... %>: code blocks for declarations, control flow, functions, and includes.$var: interpolation in HTML or text.nullbecomes an empty string; escape untrusted HTML explicitly.- Inline
<% echo expr %>: output an expression where a full block would be awkward.
/* ... */ for block comments. In HTML segments, those comments are removed before rendering.Equality & Comparison
== never converts values: different types are unequal. Arrays and objects compare structurally; functions and Error views compare by identity. != is its negation.
<, <=, >, and >= support two numbers or two strings only. Strings use byte-wise lexicographic order; other pairs raise a RuntimeError.
Types
Polonio has seven value types.
| Type | Description |
|---|---|
null | Default value for uninitialized variables and missing function arguments. |
bool | true / false. |
number | Double-precision floating point (all integers are represented as doubles). |
string | UTF-8 text with " or ' quoting plus \n, \t, \", \' escapes. |
array | Ordered list accessed with numeric indices. |
object | String-keyed map storing arbitrary values. |
function | User-defined or built-in function value; user functions can close over surrounding values. |
Variables
<%
var name
var count = 2
name = "Ana"
count += 3
count ..= " total"
%>
- `var name`: Declares a variable initialized to
null. - `var name = expr`: Declares and initializes.
- Assignment: use
=, compound math (+=,-=, and similar), or..=to concatenate.
Operators
Use parentheses when an expression would be clearer. Function calls and indexing bind most tightly; assignments are right-associative.
| Precedence (high → low) | Operators |
|---|---|
| Call / Index | fn(), array[index], object["key"] |
| Unary | -expr, not expr |
| Multiplicative | *, /, % |
| Additive | +, - |
| Concatenation | .. |
| Comparison | <, <=, >, >= |
| Equality | ==, != |
| Logical AND | and |
| Logical OR | or |
| Assignment | =, +=, -=, *=, /=, %=, ..= |
Control Flow
If / Elseif / Else
<%
if user["role"] == "admin"
echo "Welcome"
elseif user["role"] == "editor"
echo "Hi"
else
echo "Guest"
end
%>
Loops
<%
for i, item in items
echo i .. ": " .. item
end
while total < 10
total += 1
end
%>
- for/in: Iterates arrays and objects. Use
for value in arrayorfor index, value in array. Objects yieldkey+valuepairs. - while: Evaluated each loop until its condition becomes false or execution otherwise exits the loop.
Functions
<%
function greet(name)
return "Hello " .. name
end
function counter()
var value = 0
return function()
value += 1
return value
end
end
%>
- Functions capture their surrounding environment; returning a nested
functionproduces a closure. - Parameters default to
nullwhen callers omit arguments. returnexits the nearest function. If no value is provided,nullis returned.- Named functions are self-recursive because the interpreter binds the function name inside its environment.
See Fibonacci for recursion and Closures for captured state.
Includes
include "partial.pol" streams another template using the same interpreter and environments.
<% include "partials/nav.pol" %>
- Paths are resolved relative to the including file’s directory.
- Includes may nest up to 50 levels. Circular include chains raise an error.
- Variables defined before the include remain readable and writable inside the partial.
- Includes are available while rendering templates.
Operational recovery
Use attempt / recover only for unavailable capabilities and resources. Programming errors remain fatal; recovery never retries or rolls back output or side effects.
attempt
var config = file_read("config.json")
recover error
echo error["category"]
end
The optional binding is immutable and exists only in recover. A finalized send_file response cannot be recovered.
Truthiness
Conditions treat values as follows:
| Value | Truthy? |
|---|---|
null | false |
false | false |
true | true |
number | false if zero (including -0), otherwise true. |
string | false if empty; "0", whitespace, and every other non-empty byte string are true. |
array | false if empty, otherwise true. |
object | false if empty, otherwise true. |
function | Always true. |
Error view | Always true. |
Conditions do not convert values. The same table is used by if, elseif, while, not, and, and or.
Scope & Closures
Lookup is lexical. var binds the current scope; assignment updates the nearest existing binding or creates a current binding when absent. Functions and each for iteration create scopes, while conditionals, while, includes, and template blocks share their current scope.
Polonio uses lexical scope:
- Each
functionremembers the values available when it is defined. - Loop bindings are local to the loop; assignments to existing outer variables still update those variables.
includedoes not create a new environment; partials share the same scope to keep template variables fluid.- Built-in functions are available in global scope.
function render_item(item) and call it immediately to avoid polluting globals.See Closures for a complete lexical-capture example.
Collection Mutation
Arrays and mutable objects are shared reference-like values. Assignment, calls, returns, and nesting do not deep-copy them. Mutating builtins update the shared collection; slice and concat create new outer arrays. See Collections and Aliasing.
Next steps
Practice these ideas in the Examples, then use the Built-in Functions reference as you build. When a template needs requests, sessions, files, or SQLite, continue to the Runtime guide. The language specification is the frozen v1.0 contract.