Doc: progress about builtin modules

This commit is contained in:
Celestino Amoroso 2026-04-18 12:21:42 +02:00
parent 92bd366380
commit 1f57ba28dd
2 changed files with 1093 additions and 40 deletions

View File

@ -27,6 +27,10 @@ Expressions calculator
// Workaround to manage asterisk in back-tick quotes
:star: *
:sp:  
:2sp:   
:4sp:     
toc::[]
@ -67,6 +71,37 @@ _Expr_ creates and keeps a inner _global context_ where it stores imported funct
Imported functions are registered in the _global context_. When an expression first calls an imported function, that function is linked to the current context; this can be the _main context_ or a _function context_.
===== Inspecting contexts
_Expr_ provides the operator [blue]_$$_ that returns the current context. This can be used to inspect the content of the context, for example to check the value of a variable or to see which functions are currently linked to the context. This operator is primarily intended for debugging purposes.
An interactive tool could like `dev-expr` (see <<_dev-expr_test_tool>>) can be used to inspect contexts interactively.
.Example: inspecting contexts
`>>>` [blue]`$$` +
[green]`{"variables": {"ls": "[10, 20, 30]", "it": "$(#3)", "last": "-1"}, "functions": {"about": "about():string{}", "bin": "bin(value, digits=8):integer{}", "ctrl": "ctrl(prop, value):any{}", "ctrlList": "ctrlList():list-of-strings{}", "envGet": "envGet(name):string{}", "envSet": "envSet(name, value):string{}"}}` +
`>>>` [gray]_// Let use the *ml* command to activate multi-line output of contexts, which is more readable._ +
`>>>` [blue]`ml` +
`>>>` [blue]`$$` +
[green]`{` +
[green]`{2sp}"variables": {` +
[green]`{4sp}"last": {"variables": {"last": "-1", "ls": "[10, 20, 30]", "it": "$(#3)"}, "functions": {"ctrlList": "ctrlList():list-of-strings{}", "envGet": "envGet(name):string{}", "envSet": "envSet(name, value):string{}", "about": "about():string{}", "bin": "bin(value, digits=8):integer{}", "ctrl": "ctrl(prop, value):any{}"}},` +
[green]`{4sp}"ls": [10, 20, 30],` +
[green]`{4sp}"it": $(#3)` +
[green]`{2sp}},` +
[green]`{2sp}"functions": {` +
[green]`{4sp}"ctrlList": ctrlList():list-of-strings{},` +
[green]`{4sp}"envGet": envGet(name):string{},` +
[green]`{4sp}"envSet": envSet(name, value):string{},` +
[green]`{4sp}"about": about():string{},` +
[green]`{4sp}"bin": bin(value, digits=8):integer{},` +
[green]`{4sp}"ctrl": ctrl(prop, value):any{}` +
[green]`{2sp}}` +
[green]`}`
In order to inspect the global context issue the [blue]`$$global` operator.
=== `dev-expr` test tool
Before we begin to describe the syntax of _Expr_, it is worth introducing _dev-expr_ because it will be used to show many examples of expressions.
@ -995,6 +1030,383 @@ The clone modifier can also be used to declare the formal parameters of function
[green]`9`
====
== Builtins
Builtins are collection of function dedicated to specific domains of application. They are defined in Golang source files called _modules_ and compiled within the _Expr_ package. To make builtins available in _Expr_ contextes, it is required to activate the builtin module in which they are defined.
There are currently several builtin modules. More builtin modules will be added in the future.
.Available builtin modules
* *base*: Base expression tools like isNil(), int(), etc.
* *fmt*: String and console formatting functions
* *import*: Functions import() and include()
* *iterator*: Iterator helper functions
* *math.arith*: Functions add() and mul()
* *os.file*: Operating system file functions
* *string*: string utilities
Builtins activation is done by using the [blue]`BUILTIN` operator. All modules except "base" must be explicitly enabled. The syntax is as follows.
.Builtin activation syntax
====
*_builtin-activation_* = [blue]`BUILTIN` (_builtin-name_ | _list-of-builtin-names_) +
_builtin-name_ = _string_ +
_list-of-builtin-names_ = **[** _string_ { "**,**" _string_ } **]**
====
The following example shows how to activate the builtin module "math.arith" and then use the function add() defined in that module.
.Example: using built functions
`>>>` [blue]`BUILTIN "math.arith"` +
[green]`1` +
`>>>` [blue]`add(5, 3, -2)` +
[green]`6`
TIP: To avoid the need to activate builtin modules one by one, it is possible to activate all builtin modules at once by using the [blue]`BUILTIN "*"` syntax.
=== Builtin modules
==== Module "base"
The "base" builtin module provides functions for type checking and type conversion. These functions are always available in _Expr_ contexts without the need to activate the "base" module.
.Checking functions
* <<_isbool,isBool()>>
* <<_isdict,isDict()>>
* <<_isfloat,isFloat()>>
* <<_isfract,isFract()>>
* <<_islist,isList()>>
* <<_isnil,isNil()>>
* <<_isrational,isRational()>>
* <<_isstring,isString()>>
.Conversion functions
* <<_bool,bool()>>
* <<_int,int()>>
* <<_dec,dec()>>
* <<_string,string()>>
* <<_fract,fract()>>
.Other functions
* <<_eval,eval()>>
* <<_var,var()>>
===== isBool()
Syntax: `isBool(<expr>) -> bool` +
Returns _true_ if the value type of _<expr>_ is boolean, false otherwise.
.Examples
>>> isBool(true) +
true +
>>> isBool(3==2) +
true
===== isDict()
Syntax: `isDict(<expr>) -> bool` +
Returns _true_ if the value type of _<expr>_ is dictionary, false otherwise.
.Examples
>>> isDict({}) +
true +
>>> isDict({1: "one", 2: "two"}) +
true +
>>> isDict(1:"one") +
Eval Error: denominator must be integer, got string (one)
===== isFloat()
Syntax: `isFloat(<expr>) -> bool` +
Returns _true_ if the value type of _<expr>_ is float, false otherwise.
.Examples
>>> isFloat(4.) +
true +
>>> isFloat(4) +
false +
>>> isFloat("2.1") +
false
===== isFract()
Syntax: `isFract(<expr>) -> bool` +
Returns _true_ if the value type of _<expr>_ is fraction, false otherwise.
.Examples
>>> isFract(4.5) +
false +
>>> isFract(4:5) +
true +
>>> isFract(4) +
**false** +
>>> isFract(1.(3)) +
true
===== isList()
Syntax: `isList(<expr>) -> bool` +
Returns _true_ if the value type of _<expr>_ is list, false otherwise.
.Examples
>>> isList([]) +
true +
>>> isList([1, "2"])
true
>>> isList(1,2)
Eval Error: isList(): too many params -- expected 1, got 2
===== isNil()
Syntax: `isNil(<expr>) -> bool` +
Returns _true_ if the value type of _<expr>_ is nil, false otherwise.
.Examples
>>> isNil(nil)
true
>>> isNil(1)
false
===== isRational()
Syntax: `isRational(<expr>) -> bool` +
Returns _true_ if the value type of _<expr>_ is fraction or int, false otherwise.
.Examples
>>> isRational(4.5) +
false +
>>> isRational(4:5) +
true +
>>> isRational(4) +
**true** +
>>> isRational(1.(3)) +
true
===== isString()
Syntax: `isString(<expr>) -> bool` +
Returns a boolean value , false otherwise.
.Examples
>>> isString("ciao") +
true +
>>> isString(2) +
false +
>>> isString(2+"2") +
true
===== bool()
Syntax: `bool(<expr>) -> bool` +
Returns a _boolean_ value consisent to the value of the expression.
.Examples
>>> bool(1)
true
>>> bool(0)
false
>>> bool("")
false
>>> bool([])
false
>>> bool([1])
true
>>> bool({})
false
>>> bool({1: "one"})
true
===== int()
Syntax: `int(<expr>) -> int` +
Returns an _integer_ value consistent with the value of the expression.
.Examples
>>> int(2) +
2 +
>>> int("2") +
2 +
>>> int("0x1") +
Eval Error: strconv.Atoi: parsing "0x1": invalid syntax +
>>> int(0b10) +
2 +
>>> int(0o2) +
2 +
>>> int(0x2) +
2 +
>>> int(1.8) +
1 +
>>> int(5:2) +
2 +
>>> int([]) +
Eval Error: int(): can't convert list to int+
>>> int(true) +
1 +
>>> int(false) +
0
===== dec()
Syntax: `dec(<expr>) -> float` +
Returns a _float_ value consistent with the value of the expression.
.Examples
>>> dec(2) +
2 +
>>> dec(2.1) +
2.1 +
>>> dec(2.3(1)) +
2.311111111111111 +
>>> dec("3.14") +
3.14 +
>>> dec(3:4) +
0.75 +
>>> dec(true) +
1 +
>>> dec(false) +
0
===== string()
Syntax: `string(<expr>) -> string` +
Returns a _string_ value consistent with the value of the expression.
.Examples
>>> string(2) +
"2" +
>>> string(0.8) +
"0.8" +
>>> string([1,2]) +
"[1, 2]" +
>>> string({1: "one", 2: "two"}) +
"{1: "one", 2: "two"}" +
>>> string(2:5) +
"2:5" +
>>> string(3==2) +
"false"
===== fract()
Syntax: `fract(<expr>) -> fraction` +
Returns a _fraction_ value consistent with the value of the expression.
.Examples
>>> fract(2) +
2:1 +
>>> fract(2.5) +
5:2 +
>>> fract("2.5") +
5:2 +
>>> fract(1.(3)) +
4:3 +
>>> fract([2]) +
Eval Error: fract(): can't convert list to float +
>>> fract(false) +
0:1 +
>>> fract(true) +
1:1
===== eval()
Syntax: `eval(<string-expr>) -> any` +
Computes and returns the value of the [.underline]#string# expression.
.Examples
>>> eval( "2 + fract(1.(3))" ) +
10:3
===== var()
Syntax: +
`{4sp}var(<string-expr>, <expr>) -> any` +
`{4sp}var(<string-expr>) -> any`
This function allows you to define variables whose names must include special characters. The first form of the function allows you to define a variable with a name specified by the first parameter and assign it the value of the second parameter. The second form only returns the value of the variable with the specified name.
.Examples
>>> var("$x", 3+9) +
12 +
>>> var("$x") +
12 +
>>> var("gain%", var("$x")) +
12 +
>>> var("gain%", var("$x")+1) +
13
==== Module "fmt"
===== print()
===== println()
==== Module "import"
===== _import()_
[blue]_import([grey]#<source-file>#)_ -- loads the multi-expression contained in the specified source and returns its value.
===== _importAll()_
==== Module "iterator"
===== run()
==== Module "math.arith"
Currently, the "math.arith" module provides two functions, add() and mul(), that perform addition and multiplication of an arbitrary number of parameters. More functions will be added in the future.
===== add()
Syntax: +
`{4sp}add(<num-expr1>, <num-expr2>, ...) -> any` +
`{4sp}add(<list-of-num-expr>]) -> any` +
`{4sp}add(<iterator-over-num-values>) -> any`
Returns the sum of the values of the parameters. The parameters can be of any numeric type for which the [blue]`+` operator is defined. The result type depends on the types of the parameters. If all parameters are of the same type, the result is of that type. If the parameters are of different types, the result is of the type that can represent all the parameter types without loss of information. For example, if the parameters are a mix of integers and floats, the result is a float. If the parameters are a mix of number types, the result has the type of the most general one.
.Examples
>>> add(1,2,3) +
6
>>> add(1.1,2.1,3.1) +
6.300000000000001 +
>>> add("1","2","3") +
Eval Error: add(): param nr 1 (1 in 0) has wrong type string, number expected +
>>> add(1:3, 2:3, 3:3) +
2:1 +
>>> add(1, "2") +
Eval Error: add(): param nr 2 (2 in 0) has wrong type string, number expected +
>>> add([1,2,3]) +
6 +
>>> iterator=$([1,2,3]); add(iterator) +
6 +
>>> add($([1,2,3])) +
6
===== mul()
Syntax: +
`{4sp}mul(<num-expr1>, <num-expr2>, ...) -> any` +
`{4sp}mul(<list-of-num-expr>]) -> any` +
`{4sp}mul(<iterator-over-num-values>) -> any`
Same as add() but returns the product of the values of the parameters.
==== Module "os.file"
===== fileOpen()
===== fileAppend()
===== fileCreate()
===== fileClose()
===== fileWriteText()
===== fileReadText()
===== fileReadTextAll()
==== Module "string"
===== strJoin()
===== strSub()
===== strSplit()
===== strTrim()
===== strStartsWith()
===== strEndsWith()
===== strUpper()
===== strLower()
== Iterators
Iterators are objects that can be used to traverse collections, such as lists and dictionaries. They are created by providing a _data-source_ object, the collection, in a `$(<data-source>)` expression. Once an iterator is created, it can be used to access the elements of the collection one by one.
@ -1044,6 +1456,10 @@ Named operators are operators that are identified by a name instead of a symbol.
* *_.next_*: same as [blue]`{plusplus}`.
* *_.current_*: same as [blue]`{star}`.
* *_.reset_*: resets the state of the iterator to the initial state.
* *_.count_*: returns the number of elements in the iterator, if it can be determined.
* *_.index_*: returns the index of the current element in the iterator. Before the first use of the [blue]`{plusplus}` operator, it returns the error [red]_-1_.
TIP: Iterators built on custom data-sources can provide additional named operators, depending on the functionality they want to expose. For example, an iterator over a list could provide a named operator called [blue]`.reverse` that returns the next element of the collection in reverse order.
.Example: using the named operators
`>>>` [blue]`it = $(["one", "two", "three"])` +
@ -1067,14 +1483,6 @@ It is possible to create iterators over custom data-sources by defining a dictio
#TODO: custom data-sources#
== Builtins
#TODO: builtins#
=== Builtin functions
=== [blue]_import()_
[blue]_import([grey]#<source-file>#)_ loads the multi-expression contained in the specified source and returns its value.
== Plugins
#TODO: plugins#

View File

@ -550,7 +550,11 @@ pre.rouge .ss {
<ul class="sectlevel3">
<li><a href="#_variables">1.1.1. Variables</a></li>
<li><a href="#_multi_expression">1.1.2. Multi-expression</a></li>
<li><a href="#_calculation_context">1.1.3. Calculation context</a></li>
<li><a href="#_calculation_context">1.1.3. Calculation context</a>
<ul class="sectlevel4">
<li><a href="#_inspecting_contexts">Inspecting contexts</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_dev_expr_test_tool">1.2. <code>dev-expr</code> test tool</a></li>
@ -590,20 +594,87 @@ pre.rouge .ss {
<li><a href="#_function_context">6.4. Function context</a></li>
</ul>
</li>
<li><a href="#_iterators">7. Iterators</a>
<li><a href="#_builtins">7. Builtins</a>
<ul class="sectlevel2">
<li><a href="#_operators_on_iterators">7.1. Operators on iterators</a>
<li><a href="#_builtin_modules">7.1. Builtin modules</a>
<ul class="sectlevel3">
<li><a href="#_named_operators">7.1.1. Named operators</a></li>
<li><a href="#_module_base">7.1.1. Module "base"</a>
<ul class="sectlevel4">
<li><a href="#_isbool">isBool()</a></li>
<li><a href="#_isdict">isDict()</a></li>
<li><a href="#_isfloat">isFloat()</a></li>
<li><a href="#_isfract">isFract()</a></li>
<li><a href="#_islist">isList()</a></li>
<li><a href="#_isnil">isNil()</a></li>
<li><a href="#_isrational">isRational()</a></li>
<li><a href="#_isstring">isString()</a></li>
<li><a href="#_bool">bool()</a></li>
<li><a href="#_int">int()</a></li>
<li><a href="#_dec">dec()</a></li>
<li><a href="#_string">string()</a></li>
<li><a href="#_fract">fract()</a></li>
<li><a href="#_eval">eval()</a></li>
<li><a href="#_var">var()</a></li>
</ul>
</li>
<li><a href="#_iterator_over_custom_data_sources">7.2. Iterator over custom data-sources</a></li>
<li><a href="#_module_fmt">7.1.2. Module "fmt"</a>
<ul class="sectlevel4">
<li><a href="#_print">print()</a></li>
<li><a href="#_println">println()</a></li>
</ul>
</li>
<li><a href="#_builtins">8. Builtins</a>
<li><a href="#_module_import">7.1.3. Module "import"</a>
<ul class="sectlevel4">
<li><a href="#_import"><em>import()</em></a></li>
<li><a href="#_importall"><em>importAll()</em></a></li>
</ul>
</li>
<li><a href="#_module_iterator">7.1.4. Module "iterator"</a>
<ul class="sectlevel4">
<li><a href="#_run">run()</a></li>
</ul>
</li>
<li><a href="#_module_math_arith">7.1.5. Module "math.arith"</a>
<ul class="sectlevel4">
<li><a href="#_add">add()</a></li>
<li><a href="#_mul">mul()</a></li>
</ul>
</li>
<li><a href="#_module_os_file">7.1.6. Module "os.file"</a>
<ul class="sectlevel4">
<li><a href="#_fileopen">fileOpen()</a></li>
<li><a href="#_fileappend">fileAppend()</a></li>
<li><a href="#_filecreate">fileCreate()</a></li>
<li><a href="#_fileclose">fileClose()</a></li>
<li><a href="#_filewritetext">fileWriteText()</a></li>
<li><a href="#_filereadtext">fileReadText()</a></li>
<li><a href="#_filereadtextall">fileReadTextAll()</a></li>
</ul>
</li>
<li><a href="#_module_string">7.1.7. Module "string"</a>
<ul class="sectlevel4">
<li><a href="#_strjoin">strJoin()</a></li>
<li><a href="#_strsub">strSub()</a></li>
<li><a href="#_strsplit">strSplit()</a></li>
<li><a href="#_strtrim">strTrim()</a></li>
<li><a href="#_strstartswith">strStartsWith()</a></li>
<li><a href="#_strendswith">strEndsWith()</a></li>
<li><a href="#_strupper">strUpper()</a></li>
<li><a href="#_strlower">strLower()</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#_iterators">8. Iterators</a>
<ul class="sectlevel2">
<li><a href="#_builtin_functions">8.1. Builtin functions</a></li>
<li><a href="#_import">8.2. <em class="blue">import()</em></a></li>
<li><a href="#_operators_on_iterators">8.1. Operators on iterators</a>
<ul class="sectlevel3">
<li><a href="#_named_operators">8.1.1. Named operators</a></li>
</ul>
</li>
<li><a href="#_iterator_over_custom_data_sources">8.2. Iterator over custom data-sources</a></li>
</ul>
</li>
<li><a href="#_plugins">9. Plugins</a></li>
@ -683,6 +754,43 @@ pre.rouge .ss {
<div class="paragraph">
<p>Imported functions are registered in the <em>global context</em>. When an expression first calls an imported function, that function is linked to the current context; this can be the <em>main context</em> or a <em>function context</em>.</p>
</div>
<div class="sect4">
<h5 id="_inspecting_contexts"><a class="anchor" href="#_inspecting_contexts"></a><a class="link" href="#_inspecting_contexts">Inspecting contexts</a></h5>
<div class="paragraph">
<p><em>Expr</em> provides the operator <em class="blue">$$</em> that returns the current context. This can be used to inspect the content of the context, for example to check the value of a variable or to see which functions are currently linked to the context. This operator is primarily intended for debugging purposes.</p>
</div>
<div class="paragraph">
<p>An interactive tool could like <code>dev-expr</code> (see <a href="#_dev-expr_test_tool">[_dev-expr_test_tool]</a>) can be used to inspect contexts interactively.</p>
</div>
<div class="paragraph">
<div class="title">Example: inspecting contexts</div>
<p><code>&gt;&gt;&gt;</code> <code class="blue">$$</code><br>
<code class="green">{"variables": {"ls": "[10, 20, 30]", "it": "$(#3)", "last": "-1"}, "functions": {"about": "about():string{}", "bin": "bin(value, digits=8):integer{}", "ctrl": "ctrl(prop, value):any{}", "ctrlList": "ctrlList():list-of-strings{}", "envGet": "envGet(name):string{}", "envSet": "envSet(name, value):string{}"}}</code><br></p>
</div>
<div class="paragraph">
<p><code>&gt;&gt;&gt;</code> <em class="gray">// Let use the <strong>ml</strong> command to activate multi-line output of contexts, which is more readable.</em><br>
<code>&gt;&gt;&gt;</code> <code class="blue">ml</code><br>
<code>&gt;&gt;&gt;</code> <code class="blue">$$</code><br>
<code class="green">{</code><br>
<code class="green">&#160;&#160;"variables": {</code><br>
<code class="green">&#160;&#160;&#160;&#160;"last": {"variables": {"last": "-1", "ls": "[10, 20, 30]", "it": "$(#3)"}, "functions": {"ctrlList": "ctrlList():list-of-strings{}", "envGet": "envGet(name):string{}", "envSet": "envSet(name, value):string{}", "about": "about():string{}", "bin": "bin(value, digits=8):integer{}", "ctrl": "ctrl(prop, value):any{}"}},</code><br>
<code class="green">&#160;&#160;&#160;&#160;"ls": [10, 20, 30],</code><br>
<code class="green">&#160;&#160;&#160;&#160;"it": $(#3)</code><br>
<code class="green">&#160;&#160;},</code><br>
<code class="green">&#160;&#160;"functions": {</code><br>
<code class="green">&#160;&#160;&#160;&#160;"ctrlList": ctrlList():list-of-strings{},</code><br>
<code class="green">&#160;&#160;&#160;&#160;"envGet": envGet(name):string{},</code><br>
<code class="green">&#160;&#160;&#160;&#160;"envSet": envSet(name, value):string{},</code><br>
<code class="green">&#160;&#160;&#160;&#160;"about": about():string{},</code><br>
<code class="green">&#160;&#160;&#160;&#160;"bin": bin(value, digits=8):integer{},</code><br>
<code class="green">&#160;&#160;&#160;&#160;"ctrl": ctrl(prop, value):any{}</code><br>
<code class="green">&#160;&#160;}</code><br>
<code class="green">}</code></p>
</div>
<div class="paragraph">
<p>In order to inspect the global context issue the <code class="blue">$$global</code> operator.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
@ -2578,7 +2686,544 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
</div>
</div>
<div class="sect1">
<h2 id="_iterators"><a class="anchor" href="#_iterators"></a><a class="link" href="#_iterators">7. Iterators</a></h2>
<h2 id="_builtins"><a class="anchor" href="#_builtins"></a><a class="link" href="#_builtins">7. Builtins</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Builtins are collection of function dedicated to specific domains of application. They are defined in Golang source files called <em>modules</em> and compiled within the <em>Expr</em> package. To make builtins available in <em>Expr</em> contextes, it is required to activate the builtin module in which they are defined.</p>
</div>
<div class="paragraph">
<p>There are currently several builtin modules. More builtin modules will be added in the future.</p>
</div>
<div class="ulist">
<div class="title">Available builtin modules</div>
<ul>
<li>
<p><strong>base</strong>: Base expression tools like isNil(), int(), etc.</p>
</li>
<li>
<p><strong>fmt</strong>: String and console formatting functions</p>
</li>
<li>
<p><strong>import</strong>: Functions import() and include()</p>
</li>
<li>
<p><strong>iterator</strong>: Iterator helper functions</p>
</li>
<li>
<p><strong>math.arith</strong>: Functions add() and mul()</p>
</li>
<li>
<p><strong>os.file</strong>: Operating system file functions</p>
</li>
<li>
<p><strong>string</strong>: string utilities</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Builtins activation is done by using the <code class="blue">BUILTIN</code> operator. All modules except "base" must be explicitly enabled. The syntax is as follows.</p>
</div>
<div class="exampleblock">
<div class="title">Example 16. Builtin activation syntax</div>
<div class="content">
<div class="paragraph">
<p><strong><em>builtin-activation</em></strong> = <code class="blue">BUILTIN</code> (<em>builtin-name</em> | <em>list-of-builtin-names</em>)<br>
<em>builtin-name</em> = <em>string</em><br>
<em>list-of-builtin-names</em> = <strong>[</strong> <em>string</em> { "<strong>,</strong>" <em>string</em> } <strong>]</strong></p>
</div>
</div>
</div>
<div class="paragraph">
<p>The following example shows how to activate the builtin module "math.arith" and then use the function add() defined in that module.</p>
</div>
<div class="paragraph">
<div class="title">Example: using built functions</div>
<p><code>&gt;&gt;&gt;</code> <code class="blue">BUILTIN "math.arith"</code><br>
<code class="green">1</code><br>
<code>&gt;&gt;&gt;</code> <code class="blue">add(5, 3, -2)</code><br>
<code class="green">6</code></p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
To avoid the need to activate builtin modules one by one, it is possible to activate all builtin modules at once by using the <code class="blue">BUILTIN "*"</code> syntax.
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="_builtin_modules"><a class="anchor" href="#_builtin_modules"></a><a class="link" href="#_builtin_modules">7.1. Builtin modules</a></h3>
<div class="sect3">
<h4 id="_module_base"><a class="anchor" href="#_module_base"></a><a class="link" href="#_module_base">7.1.1. Module "base"</a></h4>
<div class="paragraph">
<p>The "base" builtin module provides functions for type checking and type conversion. These functions are always available in <em>Expr</em> contexts without the need to activate the "base" module.</p>
</div>
<div class="ulist">
<div class="title">Checking functions</div>
<ul>
<li>
<p><a href="#_isbool">isBool()</a></p>
</li>
<li>
<p><a href="#_isdict">isDict()</a></p>
</li>
<li>
<p><a href="#_isfloat">isFloat()</a></p>
</li>
<li>
<p><a href="#_isfract">isFract()</a></p>
</li>
<li>
<p><a href="#_islist">isList()</a></p>
</li>
<li>
<p><a href="#_isnil">isNil()</a></p>
</li>
<li>
<p><a href="#_isrational">isRational()</a></p>
</li>
<li>
<p><a href="#_isstring">isString()</a></p>
</li>
</ul>
</div>
<div class="ulist">
<div class="title">Conversion functions</div>
<ul>
<li>
<p><a href="#_bool">bool()</a></p>
</li>
<li>
<p><a href="#_int">int()</a></p>
</li>
<li>
<p><a href="#_dec">dec()</a></p>
</li>
<li>
<p><a href="#_string">string()</a></p>
</li>
<li>
<p><a href="#_fract">fract()</a></p>
</li>
</ul>
</div>
<div class="ulist">
<div class="title">Other functions</div>
<ul>
<li>
<p><a href="#_eval">eval()</a></p>
</li>
<li>
<p><a href="#_var">var()</a></p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="_isbool"><a class="anchor" href="#_isbool"></a><a class="link" href="#_isbool">isBool()</a></h5>
<div class="paragraph">
<p>Syntax: <code>isBool(&lt;expr&gt;) &#8594; bool</code><br>
Returns <em>true</em> if the value type of <em>&lt;expr&gt;</em> is boolean, false otherwise.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; isBool(true)<br>
true<br>
&gt;&gt;&gt; isBool(3==2)<br>
true</p>
</div>
</div>
<div class="sect4">
<h5 id="_isdict"><a class="anchor" href="#_isdict"></a><a class="link" href="#_isdict">isDict()</a></h5>
<div class="paragraph">
<p>Syntax: <code>isDict(&lt;expr&gt;) &#8594; bool</code><br>
Returns <em>true</em> if the value type of <em>&lt;expr&gt;</em> is dictionary, false otherwise.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; isDict({})<br>
true<br>
&gt;&gt;&gt; isDict({1: "one", 2: "two"})<br>
true<br>
&gt;&gt;&gt; isDict(1:"one")<br>
Eval Error: denominator must be integer, got string (one)</p>
</div>
</div>
<div class="sect4">
<h5 id="_isfloat"><a class="anchor" href="#_isfloat"></a><a class="link" href="#_isfloat">isFloat()</a></h5>
<div class="paragraph">
<p>Syntax: <code>isFloat(&lt;expr&gt;) &#8594; bool</code><br>
Returns <em>true</em> if the value type of <em>&lt;expr&gt;</em> is float, false otherwise.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; isFloat(4.)<br>
true<br>
&gt;&gt;&gt; isFloat(4)<br>
false<br>
&gt;&gt;&gt; isFloat("2.1")<br>
false</p>
</div>
</div>
<div class="sect4">
<h5 id="_isfract"><a class="anchor" href="#_isfract"></a><a class="link" href="#_isfract">isFract()</a></h5>
<div class="paragraph">
<p>Syntax: <code>isFract(&lt;expr&gt;) &#8594; bool</code><br>
Returns <em>true</em> if the value type of <em>&lt;expr&gt;</em> is fraction, false otherwise.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; isFract(4.5)<br>
false<br>
&gt;&gt;&gt; isFract(4:5)<br>
true<br>
&gt;&gt;&gt; isFract(4)<br>
<strong>false</strong><br>
&gt;&gt;&gt; isFract(1.(3))<br>
true</p>
</div>
</div>
<div class="sect4">
<h5 id="_islist"><a class="anchor" href="#_islist"></a><a class="link" href="#_islist">isList()</a></h5>
<div class="paragraph">
<p>Syntax: <code>isList(&lt;expr&gt;) &#8594; bool</code><br>
Returns <em>true</em> if the value type of <em>&lt;expr&gt;</em> is list, false otherwise.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; isList([])<br>
true<br>
&gt;&gt;&gt; isList([1, "2"])
true
&gt;&gt;&gt; isList(1,2)
Eval Error: isList(): too many params&#8201;&#8212;&#8201;expected 1, got 2</p>
</div>
</div>
<div class="sect4">
<h5 id="_isnil"><a class="anchor" href="#_isnil"></a><a class="link" href="#_isnil">isNil()</a></h5>
<div class="paragraph">
<p>Syntax: <code>isNil(&lt;expr&gt;) &#8594; bool</code><br>
Returns <em>true</em> if the value type of <em>&lt;expr&gt;</em> is nil, false otherwise.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; isNil(nil)
true
&gt;&gt;&gt; isNil(1)
false</p>
</div>
</div>
<div class="sect4">
<h5 id="_isrational"><a class="anchor" href="#_isrational"></a><a class="link" href="#_isrational">isRational()</a></h5>
<div class="paragraph">
<p>Syntax: <code>isRational(&lt;expr&gt;) &#8594; bool</code><br>
Returns <em>true</em> if the value type of <em>&lt;expr&gt;</em> is fraction or int, false otherwise.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; isRational(4.5)<br>
false<br>
&gt;&gt;&gt; isRational(4:5)<br>
true<br>
&gt;&gt;&gt; isRational(4)<br>
<strong>true</strong><br>
&gt;&gt;&gt; isRational(1.(3))<br>
true</p>
</div>
</div>
<div class="sect4">
<h5 id="_isstring"><a class="anchor" href="#_isstring"></a><a class="link" href="#_isstring">isString()</a></h5>
<div class="paragraph">
<p>Syntax: <code>isString(&lt;expr&gt;) &#8594; bool</code><br>
Returns a boolean value , false otherwise.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; isString("ciao")<br>
true<br>
&gt;&gt;&gt; isString(2)<br>
false<br>
&gt;&gt;&gt; isString(2+"2")<br>
true</p>
</div>
</div>
<div class="sect4">
<h5 id="_bool"><a class="anchor" href="#_bool"></a><a class="link" href="#_bool">bool()</a></h5>
<div class="paragraph">
<p>Syntax: <code>bool(&lt;expr&gt;) &#8594; bool</code><br>
Returns a <em>boolean</em> value consisent to the value of the expression.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; bool(1)
true
&gt;&gt;&gt; bool(0)
false
&gt;&gt;&gt; bool("")
false
&gt;&gt;&gt; bool([])
false
&gt;&gt;&gt; bool([1])
true
&gt;&gt;&gt; bool({})
false
&gt;&gt;&gt; bool({1: "one"})
true</p>
</div>
</div>
<div class="sect4">
<h5 id="_int"><a class="anchor" href="#_int"></a><a class="link" href="#_int">int()</a></h5>
<div class="paragraph">
<p>Syntax: <code>int(&lt;expr&gt;) &#8594; int</code><br>
Returns an <em>integer</em> value consistent with the value of the expression.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; int(2)<br>
2<br>
&gt;&gt;&gt; int("2")<br>
2<br>
&gt;&gt;&gt; int("0x1")<br>
Eval Error: strconv.Atoi: parsing "0x1": invalid syntax<br>
&gt;&gt;&gt; int(0b10)<br>
2<br>
&gt;&gt;&gt; int(0o2)<br>
2<br>
&gt;&gt;&gt; int(0x2)<br>
2<br>
&gt;&gt;&gt; int(1.8)<br>
1<br>
&gt;&gt;&gt; int(5:2)<br>
2<br>
&gt;&gt;&gt; int([])<br>
Eval Error: int(): can&#8217;t convert list to int+
&gt;&gt;&gt; int(true)<br>
1<br>
&gt;&gt;&gt; int(false)<br>
0</p>
</div>
</div>
<div class="sect4">
<h5 id="_dec"><a class="anchor" href="#_dec"></a><a class="link" href="#_dec">dec()</a></h5>
<div class="paragraph">
<p>Syntax: <code>dec(&lt;expr&gt;) &#8594; float</code><br>
Returns a <em>float</em> value consistent with the value of the expression.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; dec(2)<br>
2<br>
&gt;&gt;&gt; dec(2.1)<br>
2.1<br>
&gt;&gt;&gt; dec(2.3(1))<br>
2.311111111111111<br>
&gt;&gt;&gt; dec("3.14")<br>
3.14<br>
&gt;&gt;&gt; dec(3:4)<br>
0.75<br>
&gt;&gt;&gt; dec(true)<br>
1<br>
&gt;&gt;&gt; dec(false)<br>
0</p>
</div>
</div>
<div class="sect4">
<h5 id="_string"><a class="anchor" href="#_string"></a><a class="link" href="#_string">string()</a></h5>
<div class="paragraph">
<p>Syntax: <code>string(&lt;expr&gt;) &#8594; string</code><br>
Returns a <em>string</em> value consistent with the value of the expression.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; string(2)<br>
"2"<br>
&gt;&gt;&gt; string(0.8)<br>
"0.8"<br>
&gt;&gt;&gt; string([1,2])<br>
"[1, 2]"<br>
&gt;&gt;&gt; string({1: "one", 2: "two"})<br>
"{1: "one", 2: "two"}"<br>
&gt;&gt;&gt; string(2:5)<br>
"2:5"<br>
&gt;&gt;&gt; string(3==2)<br>
"false"</p>
</div>
</div>
<div class="sect4">
<h5 id="_fract"><a class="anchor" href="#_fract"></a><a class="link" href="#_fract">fract()</a></h5>
<div class="paragraph">
<p>Syntax: <code>fract(&lt;expr&gt;) &#8594; fraction</code><br>
Returns a <em>fraction</em> value consistent with the value of the expression.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; fract(2)<br>
2:1<br>
&gt;&gt;&gt; fract(2.5)<br>
5:2<br>
&gt;&gt;&gt; fract("2.5")<br>
5:2<br>
&gt;&gt;&gt; fract(1.(3))<br>
4:3<br>
&gt;&gt;&gt; fract([2])<br>
Eval Error: fract(): can&#8217;t convert list to float<br>
&gt;&gt;&gt; fract(false)<br>
0:1<br>
&gt;&gt;&gt; fract(true)<br>
1:1</p>
</div>
</div>
<div class="sect4">
<h5 id="_eval"><a class="anchor" href="#_eval"></a><a class="link" href="#_eval">eval()</a></h5>
<div class="paragraph">
<p>Syntax: <code>eval(&lt;string-expr&gt;) &#8594; any</code><br>
Computes and returns the value of the <span class="underline">string</span> expression.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; eval( "2 + fract(1.(3))" )<br>
10:3</p>
</div>
</div>
<div class="sect4">
<h5 id="_var"><a class="anchor" href="#_var"></a><a class="link" href="#_var">var()</a></h5>
<div class="paragraph">
<p>Syntax:<br>
<code>&#160;&#160;&#160;&#160;var(&lt;string-expr&gt;, &lt;expr&gt;) &#8594; any</code><br>
<code>&#160;&#160;&#160;&#160;var(&lt;string-expr&gt;) &#8594; any</code></p>
</div>
<div class="paragraph">
<p>This function allows you to define variables whose names must include special characters. The first form of the function allows you to define a variable with a name specified by the first parameter and assign it the value of the second parameter. The second form only returns the value of the variable with the specified name.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>&gt;&gt;&gt; var("$x", 3+9)<br>
12<br>
&gt;&gt;&gt; var("$x")<br>
12<br>
&gt;&gt;&gt; var("gain%", var("$x"))<br>
12<br>
&gt;&gt;&gt; var("gain%", var("$x")+1)<br>
13</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_module_fmt"><a class="anchor" href="#_module_fmt"></a><a class="link" href="#_module_fmt">7.1.2. Module "fmt"</a></h4>
<div class="sect4">
<h5 id="_print"><a class="anchor" href="#_print"></a><a class="link" href="#_print">print()</a></h5>
</div>
<div class="sect4">
<h5 id="_println"><a class="anchor" href="#_println"></a><a class="link" href="#_println">println()</a></h5>
</div>
</div>
<div class="sect3">
<h4 id="_module_import"><a class="anchor" href="#_module_import"></a><a class="link" href="#_module_import">7.1.3. Module "import"</a></h4>
<div class="sect4">
<h5 id="_import"><a class="anchor" href="#_import"></a><a class="link" href="#_import"><em>import()</em></a></h5>
<div class="paragraph">
<p><em class="blue">import(<span class="grey">&lt;source-file&gt;</span>)</em>&#8201;&#8212;&#8201;loads the multi-expression contained in the specified source and returns its value.</p>
</div>
</div>
<div class="sect4">
<h5 id="_importall"><a class="anchor" href="#_importall"></a><a class="link" href="#_importall"><em>importAll()</em></a></h5>
</div>
</div>
<div class="sect3">
<h4 id="_module_iterator"><a class="anchor" href="#_module_iterator"></a><a class="link" href="#_module_iterator">7.1.4. Module "iterator"</a></h4>
<div class="sect4">
<h5 id="_run"><a class="anchor" href="#_run"></a><a class="link" href="#_run">run()</a></h5>
</div>
</div>
<div class="sect3">
<h4 id="_module_math_arith"><a class="anchor" href="#_module_math_arith"></a><a class="link" href="#_module_math_arith">7.1.5. Module "math.arith"</a></h4>
<div class="sect4">
<h5 id="_add"><a class="anchor" href="#_add"></a><a class="link" href="#_add">add()</a></h5>
</div>
<div class="sect4">
<h5 id="_mul"><a class="anchor" href="#_mul"></a><a class="link" href="#_mul">mul()</a></h5>
</div>
</div>
<div class="sect3">
<h4 id="_module_os_file"><a class="anchor" href="#_module_os_file"></a><a class="link" href="#_module_os_file">7.1.6. Module "os.file"</a></h4>
<div class="sect4">
<h5 id="_fileopen"><a class="anchor" href="#_fileopen"></a><a class="link" href="#_fileopen">fileOpen()</a></h5>
</div>
<div class="sect4">
<h5 id="_fileappend"><a class="anchor" href="#_fileappend"></a><a class="link" href="#_fileappend">fileAppend()</a></h5>
</div>
<div class="sect4">
<h5 id="_filecreate"><a class="anchor" href="#_filecreate"></a><a class="link" href="#_filecreate">fileCreate()</a></h5>
</div>
<div class="sect4">
<h5 id="_fileclose"><a class="anchor" href="#_fileclose"></a><a class="link" href="#_fileclose">fileClose()</a></h5>
</div>
<div class="sect4">
<h5 id="_filewritetext"><a class="anchor" href="#_filewritetext"></a><a class="link" href="#_filewritetext">fileWriteText()</a></h5>
</div>
<div class="sect4">
<h5 id="_filereadtext"><a class="anchor" href="#_filereadtext"></a><a class="link" href="#_filereadtext">fileReadText()</a></h5>
</div>
<div class="sect4">
<h5 id="_filereadtextall"><a class="anchor" href="#_filereadtextall"></a><a class="link" href="#_filereadtextall">fileReadTextAll()</a></h5>
</div>
</div>
<div class="sect3">
<h4 id="_module_string"><a class="anchor" href="#_module_string"></a><a class="link" href="#_module_string">7.1.7. Module "string"</a></h4>
<div class="sect4">
<h5 id="_strjoin"><a class="anchor" href="#_strjoin"></a><a class="link" href="#_strjoin">strJoin()</a></h5>
</div>
<div class="sect4">
<h5 id="_strsub"><a class="anchor" href="#_strsub"></a><a class="link" href="#_strsub">strSub()</a></h5>
</div>
<div class="sect4">
<h5 id="_strsplit"><a class="anchor" href="#_strsplit"></a><a class="link" href="#_strsplit">strSplit()</a></h5>
</div>
<div class="sect4">
<h5 id="_strtrim"><a class="anchor" href="#_strtrim"></a><a class="link" href="#_strtrim">strTrim()</a></h5>
</div>
<div class="sect4">
<h5 id="_strstartswith"><a class="anchor" href="#_strstartswith"></a><a class="link" href="#_strstartswith">strStartsWith()</a></h5>
</div>
<div class="sect4">
<h5 id="_strendswith"><a class="anchor" href="#_strendswith"></a><a class="link" href="#_strendswith">strEndsWith()</a></h5>
</div>
<div class="sect4">
<h5 id="_strupper"><a class="anchor" href="#_strupper"></a><a class="link" href="#_strupper">strUpper()</a></h5>
</div>
<div class="sect4">
<h5 id="_strlower"><a class="anchor" href="#_strlower"></a><a class="link" href="#_strlower">strLower()</a></h5>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_iterators"><a class="anchor" href="#_iterators"></a><a class="link" href="#_iterators">8. Iterators</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Iterators are objects that can be used to traverse collections, such as lists and dictionaries. They are created by providing a <em>data-source</em> object, the collection, in a <code>$(&lt;data-source&gt;)</code> expression. Once an iterator is created, it can be used to access the elements of the collection one by one.</p>
@ -2590,7 +3235,7 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
<p>Lists and, soon, dictionaries, are implicit data-sources. The syntax for creating an iterator is as follows.</p>
</div>
<div class="exampleblock">
<div class="title">Example 16. Iterator creation syntax</div>
<div class="title">Example 17. Iterator creation syntax</div>
<div class="content">
<div class="paragraph">
<p><strong><em>iterator</em></strong> = "<strong>$(</strong>" <em>data-source</em> "<strong>)</strong>"<br>
@ -2613,7 +3258,7 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
<code class="red">Eval Error: EOF</code></p>
</div>
<div class="sect2">
<h3 id="_operators_on_iterators"><a class="anchor" href="#_operators_on_iterators"></a><a class="link" href="#_operators_on_iterators">7.1. Operators on iterators</a></h3>
<h3 id="_operators_on_iterators"><a class="anchor" href="#_operators_on_iterators"></a><a class="link" href="#_operators_on_iterators">8.1. Operators on iterators</a></h3>
<div class="paragraph">
<p>The above example shows the use of the <code class="blue">++</code> operator to get the next element of an iterator. The <code class="blue">++</code> operator is a postfix operator that can be used with iterators. It returns the next element of the collection and updates the state of the iterator. When there are no more elements to iterate over, it returns the error <em class="red">Eval Error: EOF</em>.</p>
</div>
@ -2632,7 +3277,7 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
<code class="green">"one"</code></p>
</div>
<div class="sect3">
<h4 id="_named_operators"><a class="anchor" href="#_named_operators"></a><a class="link" href="#_named_operators">7.1.1. Named operators</a></h4>
<h4 id="_named_operators"><a class="anchor" href="#_named_operators"></a><a class="link" href="#_named_operators">8.1.1. Named operators</a></h4>
<div class="paragraph">
<p>Named operators are operators that are identified by a name instead of a symbol. They are implicitly defined and can be called using a special syntax. For example, the <code class="blue">++</code> has the equivalent named operator <code class="blue">.next</code>.</p>
</div>
@ -2648,8 +3293,26 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
<li>
<p><strong><em>.reset</em></strong>: resets the state of the iterator to the initial state.</p>
</li>
<li>
<p><strong><em>.count</em></strong>: returns the number of elements in the iterator, if it can be determined.</p>
</li>
<li>
<p><strong><em>.index</em></strong>: returns the index of the current element in the iterator. Before the first use of the <code class="blue">++</code> operator, it returns the error <em class="red">-1</em>.</p>
</li>
</ul>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
Iterators built on custom data-sources can provide additional named operators, depending on the functionality they want to expose. For example, an iterator over a list could provide a named operator called <code class="blue">.reverse</code> that returns the next element of the collection in reverse order.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<div class="title">Example: using the named operators</div>
<p><code>&gt;&gt;&gt;</code> <code class="blue">it = $(["one", "two", "three"])</code><br>
@ -2670,7 +3333,7 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
</div>
</div>
<div class="sect2">
<h3 id="_iterator_over_custom_data_sources"><a class="anchor" href="#_iterator_over_custom_data_sources"></a><a class="link" href="#_iterator_over_custom_data_sources">7.2. Iterator over custom data-sources</a></h3>
<h3 id="_iterator_over_custom_data_sources"><a class="anchor" href="#_iterator_over_custom_data_sources"></a><a class="link" href="#_iterator_over_custom_data_sources">8.2. Iterator over custom data-sources</a></h3>
<div class="paragraph">
<p>It is possible to create iterators over custom data-sources by defining a dictionary that has the key <code>next</code> whose value is a function that returns the next element of the collection and updates the state of the iterator. The syntax for creating an iterator over a custom data-source is as follows.</p>
</div>
@ -2681,24 +3344,6 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
</div>
</div>
<div class="sect1">
<h2 id="_builtins"><a class="anchor" href="#_builtins"></a><a class="link" href="#_builtins">8. Builtins</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p><mark>TODO: builtins</mark></p>
</div>
<div class="sect2">
<h3 id="_builtin_functions"><a class="anchor" href="#_builtin_functions"></a><a class="link" href="#_builtin_functions">8.1. Builtin functions</a></h3>
</div>
<div class="sect2">
<h3 id="_import"><a class="anchor" href="#_import"></a><a class="link" href="#_import">8.2. <em class="blue">import()</em></a></h3>
<div class="paragraph">
<p><em class="blue">import(<span class="grey">&lt;source-file&gt;</span>)</em> loads the multi-expression contained in the specified source and returns its value.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_plugins"><a class="anchor" href="#_plugins"></a><a class="link" href="#_plugins">9. Plugins</a></h2>
<div class="sectionbody">
<div class="paragraph">
@ -2709,7 +3354,7 @@ The clone modifier <code class="blue">@</code> does not make a variable a refere
</div>
<div id="footer">
<div id="footer-text">
Last updated 2026-04-15 19:26:58 +0200
Last updated 2026-04-18 12:01:15 +0200
</div>
</div>
</body>