About min

min is a concatenative, fully-homoiconic, functional, interpreted programming language.

This basically means that:

Why?

Because creating a programming language is something that every programmer needs to do, at some point in life. And also because there are way too few concatenative programming language out there – so people are likely to be less pissed off than if I made a yet another Lisp instead.

I always wanted to build a minimalist language, but that could also be used for real work and provided a standard library for common tasks and functionalities like regular expression support, cryptography, execution of external programs, shell-like operators, and keywords to work with files, and more.

Additionally, I wanted it to be fully self-contained, cross-platform, and small. Not stupidly small, but I feel it’s a good compromise compared to the alternatives out there, considering that you only need one file to run any min program.

I also created a static site generator called HastySite, which also powers https://min-lang.org. HastySite internally uses min as the language to write the rules to process the source files of the site, and also all its scripts.

Finally, I think more and more people should get to know concatenative programming languages, because concatenative programming matters.

How?

min is developed entirely in Nim – the name is (almost) entirely a coincidence. I wanted to call it minim but then shortened it for more… minimalism.

min’s parser started off as a fork of Nim’s JSON parser – adapted to process a concatenative programming language with less primitive types than JSON. It is interpreted in the traditional sense: no bytecode, no JIT, just plain read, parse, and run.

Who?

min was created and implemented by Fabio Cevasco, with contributions by Peter Munch-Ellingsen, Yanis Zafirópulos, and baykus871.

Special thanks to mwgkgk for contributing to the design of native dictionaries.

When?

min source code repository was created on November 8th 2014. This only means that I’ve been very slowly developing something that was actually made public at the end of July 2017.

Get Started

You can download one of the following pre-built min binaries:

Building from source

Alternatively, you can build min from source in one of the following ways:

Using nimble

If you already installed nim, you probably already have the nimble package manager installed.

If that’s the case, simply run nimble install min.

Building from source for additional platforms

By default, min is released as a pre-built binary executable for Windows x64, macOS x64 and Linux x64. However, it should run without issues on any platform supported by the Nim programming language.

To build on a different operating system and architecture from the default ones, you also need to get or build the following static libraries:

and also specify the following additional flag when compiling:

--passL:"-static -L<dir> -lpcre -lssl -lcrypto"

Where <dir> is the directory containing the *.a files for the static libraries listed above.

Alternatively, if you can also opt out from OpenSSL and PCRE support by:

  • Specifying -d:nossl
  • Specifying -d:nopcre

Additional build options

-d:ssl

If the -d:ssl flag is specified when compiling, min will be built with SSL support, so it will be possible to:

If this flag is not specified:

-d:nopcre

If the -d:nopcre is specified when compiling, min will be built without PCRE support, so it will not be possible to use regular expressions and the following symbols will not be exposed by the global Module:

Running the min shell

To start the min shell, run min with no arguments. You will be presented with a prompt displaying the path to the current directory:

min shell v0.46.0 [/Users/h3rald/test]$

You can type min code and press ENTER to evaluate it immediately:

[/Users/h3rald/test]$ 2 2 + 4 [/Users/h3rald/test]$

The result of each operation will be placed on top of the stack, and it will be available to subsequent operation

[/Users/h3rald/test]$ stack.dup * 16 [/Users/h3rald/test]$

To exit min shell, press CTRL+C or type 0 exit and press ENTER.

Tip

By default, the min shell provides advanced features like tab-completion, history, etc. If however, you run into problems, you can disable these features by running min -j instead, and run min shell with a bare-bones REPL.

Executing a min program

To execute a min script, you can:

min also supports running programs from standard input, so the following command can also be used (on Unix-like system) to run a program saved in myfile.min:

$ cat myfile.min | min

You can enable development mode (runtime checks and validations) by specifying -d (--dev) when running a min program. If development mode is not enabled, min programs run faster.

Compiling a min program

min programs can be compiled to a single executable simply by using the built-in compile command:

$ min compile myfile.min

Essentially, this will:

  1. Generate a myfile.nim containing the equivalent Nim code of your min program.
  2. Call the Nim compiler to do the rest ;)

If you want to pass any options to the Nim compiler (like -d:release for example) you can do so by using the -n (or --passN) option:

$ min compile myfile.min -n:"-d:release –threadAnalysis:off –mm:refc"

Additionally, you can also use -m:<path> (or --module-path) to specify one path containing .min files which will be compiled as well (but not executed) along with the specified file. Whenever a load or a require symbol is used to load/require an external .min file, it will attempt to retrieve its contents from the pre-loaded files first before searching the filesystem.

For example, the following command executed in the root folder of the min project will compile run.min along with all .min files included in the tasks folder and its subfolders:

$ min compile run.min -m:tasks

Similarly, you can also bundle additional files in the executable by specifying the -a:<path> (or --asset-path) option. At runtime, the compiled min program will attempt to lookup bundled asset files before checking the filesystem.

Note

In order to successfully compile .min files, Nim must be installed on your system and min must be installed via nimble.

Getting help on a min symbol

min comes with a built-in help command that can be used to print information on a specific symbol. Essentially, this is equivalent to use the help symbol within the min REPL.

$ min help stack.dup

Syntax highlighting

Learning the min Language

min is a stack-based, concatenative programming language that uses postfix notation. If you already know Forth, Factor or Joy, or if you ever used an RPN calculator, then min will look somewhat familiar to you.

If not, well, here’s how a short min program looks like:

; This is a comment
(1 2 3 4 5) (stack.dup *) map
#| This is a...
...multiline comment |#

This program returns a list containing the square values of the first five integer numbers:

(1 4 9 16 25)

Let’s see how it works:

  1. First, a list containing the first five integers is pushed on the stack.
  2. Then, another list containing two symbols (stack.dup and *) is pushed on the stack. This constitutes a quoted program which, when executed duplicates the first element on the stack — this is done by stack.dup— and then multiplies — with *— the two elements together.
  3. Finally, the symbol map is pushed on the stack. Map takes a list of elements and a quoted program and applies the program to each element.

Note that:

Unlike more traditional programming languages, in a concatenative programming language, there is no inherent need for variables or named parameters, as symbols act as stack operators that consume elements that are placed in order on top of a stack.

Data Types

The following data types are availanle in min (with the corresponding shorthand symbols used in operator signatures in brackets):

null (null)
null value.
boolean (bool)
true or false.
integer (int)
A 64-bit integer number like 1, 27, or -15.
float (flt)
A 64-bit floating-point number like 3.14 or -56.9876.
string (str)
A series of characters wrapped in double quotes: “Hello, World!”.
quotation (quot)
A list of elements, which may also contain symbols. Quotations can be used to create heterogenous lists of elements of any data type, and also to create a block of code that will be evaluated later on (quoted program). Example: (1 2 3 + *)
command (cmd)
A command string wrapped in square brackets that will be immediately executed on the current shell and converted into the command standard output. Example: [ls -a]
dictionary (dict)

A key/value table. Dictionaries are implemented as an immediately-dequoted quotation, are enclosed in curly braces, and are represented by their symbol definitions. Note that dictionary keys must start with :and be followed by a double-quoted string, or a single word (which can be written without double quotes). The dict Module provides some operators on dictionaries.

Additionally, dictionaries can also be typed to denote complex objects like sockets, errors, etc. For example, the following dictionary defines an error:

  {
   "MyError" :error
   "An error occurred" :message
   "symbol1" :symbol
   "dir1/file1.min" :filename
   3 :line
   13 :column
   ;error
  }

Tip

The dict.dtype operator can be used to set the type of a dictionary.

The global Module provides predicate operators to check if an element belongs to a particular data type or pseudo-type (boolean?, number?, integer?, float?, …).

Additionally, the global Module provides operators to convert values from a data type to another (e.g. integer, string, and so on).

Quotations

Quotations are the most important thing to understand in min. Besides being the data type used for lists, they are also used to delimit blocks of min code that is not going to be immediately executed.

Consider for example the following min code which returns all the files present in the current folder sorted by name:

 sys.pwd sys.ls (fs.type "file" ==) filter '> sort

The symbol seq.filter takes two quotations as arguments – the first quotation on the stack is applied to all the elements of the second quotation on the stack, to determine which elements of the second quotation will be part of the resulting quotation. This is an example of how quotations can be used both as lists and programs.

Let’s examine this program step-by-step:

  1. The sys.pwd symbol is pushed on the stack, and it is immediately evaluated to the full path to the current directory.
  2. The sys.ls symbol is pushed on the stack, it consumes the string already on the stack and returns a quotation containing all files and directories within the current directory.
  3. The quotation (fs.type 'file ==) is pushed on the stack. It is treated exactly like a list of data and it is not evaluated.
  4. The filter symbol is pushed on the stack. This symbol takes two quotations as input, and applies the result of the first quotation on the stack ((fs.type "file" ==)) to all elements of the second quotation of the stack (the list of files and directories), returning a new quotation containing only those elements of the second quotation on the stack that satisfy the result of the first quotation. In this case, it returns a new quotation containing only files.
  5. '> is pushed on the stack. The ' sigil can be used instead of the quote symbol to quote a single symbol, > in this case. In other words, it is instantly evaluated to the quotation (>).
  6. The symbol sort is pushed on the stack. This symbol, like filter, takes two quotations as input, and applies the first quotation to each element of the second quotation, effectively sorting each element of the second quotation using the predicate expressed by the first quotation. In this case, all files are sorted by name in ascending order.

Tip

The seq Module provides several symbols to work with quotations in a functional way.

Quoting, dequoting, and applying

When a quotation is created, it is treated as data, no matter what it contains: it is placed on the stack, like an integer or a string would. However, unlike other data types, a quotation can be evaluated in certain situations and when it happens its contents are pushed on the stack.

Consider the following program:

 (1 2 3 4 5 6 7) (odd?) filter

This program returns a new quotation containing all odd numbers contained in quotation (1 2 3 4 5 6 7).

In this case, the second quotation is used to quote the symbol odd? so that instead of being executed immediately, it will be executed by the symbol filter on each element of the first quotation. In this way, we may say that (odd?) is dequoted by the symbol filter.

The symbol dequote or its alias -> can be used to dequote a quotation by pushing all its elements on the main stack. Essentially, this executes the quotation in the current context.

For example, the following program leaves the elements 1 and -1 on the stack:

 (1 2 3 -) ->

Alternatively, the symbol apply or its alias => can also be used to dequote a quotation but in this case it will not push its elements on the main stack, instead it will:

  1. Create a temporary empty stack.
  2. Push all elements on it, one by one.
  3. Push the entire temporary stack as a quotation back on the main stack.

For example, the following program leaves the element (1 -1) on the stack:

 (1 2 3 -) =>

Operators

Every min program needs operators to:

There are two types of operators: symbols and sigils.

Symbols

Symbols are the most common type of operator. A min symbol is a single word that is either provided by one of the predefined min modules like stack.dup or sys.pwd or defined by the user. User-defined symbols must:

If a symbol contains a dot (.) then it is namespaced by its containing module or dictionary. For example, fs.dirname identifies the {fs.dirname}} operator defined in the {{#link-module symbol. The following min program defines a new symbol called square that duplicates the first element on the stack and multiplies the two elements:

 (
   symbol square
   (num :n ==> num :result)
   (n dup * @result)
 ) operator
 ;; Calculates the square of n.

The operator symbol provides way to:

Also, symbol operator definitions can be annotated with documentation comments (starting with ;; or wrapped in #|| ... ||#)) so that a help text can be displayed using the help symbol.

Using the lambda operator

Sometimes you just want to bind a piece of code to a symbol to reuse it later, typically something simple and easy-to-read. In these cases, you can use the lambda operator (or the ^ sigil). For example, the previous square operator definition could be rewritten simply as the following.

 (stack.dup *) ^square

Note that this feels like using define, but the main difference between lambda and define is that lambda only works on quotations doesn’t auto-quote them, so that they are immediately evaluated when the corresponding symbol is pushed on the stack.

Also note that unlike with operator, symbols defined with lambda:

Tip

You can use lambda-bind to re-set a previously set lambda.

Sigils

Besides symbols, you can also define sigils. min provides a set of predefined sigils as abbreviations for commonly used symbols.

A sigil can be prepended to a double-quoted string or a single word (with no spaces) which will be treated as a string instead of using the corresponding symbol.

Currently min provides the following sigils:

'
Alias for quote.
:
Alias for define.
?
Alias for help.
~
Alias for lambda-bind.
$
Alias for |get-env.
@
Alias for bind.
^
Alias for lambda.

Besides system sigils, you can also create your own sigils. Unlike system sigils however, user defined sigils:

Sigils can be a very powerful construct and a way to reduce boilerplate code: you can define a sigil to use as you would use any symbol which requires a single string or quoted symbol on the stack.

Like symbols, sigils can be defined with the operator operator, like this:

 (
   sigil j
   (string :json ==> a :result)
   (json from-json @result)
 ) operator

This definition will add a j sigil that will process the following string as JSON code, so for example:

 j"{\\"test\\": true}"

…will push the following dictionary on the stack:

{true :test}

Also, sigil definitions can be annotated with documentation comments (starting with ;; or wrapped in #|| ... ||#) so that a help text can be displayed using the help symbol.

Auto-popping

Typically, but not always, operators push one or more value to the stack. While this is typically the desired behavior, in some cases you may want to keep the stack clear so in these cases you can append a ! character to any symbol to cause the symbol pop to be pushed on the stack immediately afterwards.

 "test" puts  ;Prints "test" and pushes "test" on the stack.
 "test" puts! ;Prints "test" without pushing anything on the stack.

Operator signatures

When defining symbols and sigils with the operator operator, you must specify a signature that will be used to validate and capture input and output values:

 (
   symbol square
   (num :n ==> num :result)
   (n stack.dup * @result)
 ) operator

In this case for example the square symbol expects a number on the stack, which will be captured to the symbol n and it will place a number on the stack which needs to be bound in the operator body to the symbol result.

In a signature, a type expression must precede the capturing symbol. Such type expression can be:

Note

If the operator you are defining doesn’t require any input value or doesn’t leave ang output value on the stack, simply don’t put anything before or after the ==> separator, respectively. For example, the signature of the puts! operator could be written like (a ==>).

Type classes

Besides standard base types, you can define your own type classes to express custom constraints/validations for operator input and output values.

Consider the following type class definition validating a quotation containing strings:

 (
   typeclass strquot
   (quot :q ==> bool :o)
   (q (string?) all? @o)
 ) ::

The operator operator can be used to define a symbol prefixed with typeclass: (typeclass:strquot in this case) corresponding to a type class that can be used in operator signatures in place of a type, like this:

 (
   symbol join-strings
   (strquot :q ==> str :result)
   ( 
      q "" (suffix) reduce @result
   )
 )

This operator will raise an error if anything other than a quotation of strings is found on the stack.

Tip

typeclass:-prefixed symbols are just like ordinary symbols: they are lexically scoped, they can be sealed, unsealed and deleted.

Capturing lambdas

You can also specify a lambda to be captured to an output value, like this:

 (
   symbol square
   (==> quot ^o)
   (
     (stack.dup *) ~o
   )
 ) ::

Essentially, this allows you to push a lambda on the stack from an operator.

Note that:

Type expressions

When specifying types in operator signatures or through the expect operator, you can specify a logical expression containing types and type classes joined with one of the following operators:

Suppose for example you defined the following type classes:

(typeclass fiveplus
    (int :n ==> bool :o)
    (
      n 5 > @o
    )
) ::

(typeclass tenminus
    (int :n ==> bool :o)
    (
      n 10 < @o
    )
) ::

(typeclass even
    (int :n ==> bool :o)
    (
      n 2 mod 0 == @o
    )
) ::

You can combine them in a type expression as following:

(symbol test
    (!even|tenminus&fiveplus :n ==> bool :o)
    (
      true @o
    )
) ::
4 test  ; error
6 test  ; true
11 test ; true 
Type aliases

As you can see, type expressions can quickly become quite long and complex. To avoid this, you can define type aliases using the typealias operator.

For example, you can create an alias of part of the type expression used in the previous example, like this:

'tenminus&fiveplus 'five-to-ten typealias

(symbol test
    (!even|five-to-ten :n ==> bool :o)
    (
      true @o
    )
) ::

Note that:

Generics

min supports generics in operator signatures. in other words, you can define a custom type alias on-the-fly directly in an operator signature, like this:

(
  symbol add
  ((str|num|quot :t) :a t :b ==> t :result)
  (
   (a type "str" ==)
     (a b suffix @result return)
   when
   (a type "num" ==)
     (a b + @result return)
   when
   (a type "quot" ==)
     (a b concat #result return)
   when
  )
) ::

In this case, t is set to the type union stribg|num|quot, and the add method above can be used to sum two numbers or join two strings or quotations.

Note that the value of t is evaluated to the type of the first value that is processed. In other words, the following programs will work as expected:

 3 5 add ;outputs 8

 "hello, " "world" ;outputs "hello, world"

while the following will raise an error, because the value of t from num to quot within the same operator use:

 12 "test" add ;raises an error
Constructors

The operator operator can also be used to create constructor symbols. A constructor is a particular type of operator that is used to create a new typed dictionary.

Consider the following example:

 (
   constructor point
   (num :x num :y ==> dict :out)
   (
     {}
       x 'x dset
       y 'y dset
     @out
   )
 ) ::

The operator above creates a point constructor symbol that can be used to create a new dict:point typed dictionary by popping two numbers from the stack:

 2 3 point ; {2 :x 3 :y ;point}

Tip

Except for some native symbols, constructors represent the only way to create new typed dictionaries. The more validations you perform in a constructor, the most effective checking for a specific type using the type? operator will be, as type? only checks if a specific type annotation is present on a typed dictionary, nothing else.

Definitions

Being a concatenative language, min does not really need named parameters or variables: symbols just pop elements off the main stack in order, and that’s normally enough. There is however one small problem with the traditional concatenative paradigm; consider the following program for example:

 stack.dup stack.dup
 "\.zip$" match?
 stack.swap fs.size 1000000 > and 
 stack.swap fs.mtime now 3600 - >

This program takes a single string corresponding to a file path and returns true if it’s a .zip file bigger than 1MB that was modified in the last hour. Sure, it is remarkable that no variables are needed for such a program, but it is not very readable: because no variables are used, it is often necessary to make copies of elements and push them to the end of the stack – that’s what the stack.dup and stack.swap are used for.

The good news is that you can use the define operator and the : sigil to define new symbols, and symbols can also be set to fixed values (literals).

Consider the following program:

 :filepath
 filepath "\.zip$" match?
 filepath fs.size 1000000 >
 filepath fs.mtime time.now 3600 - >
 and and

In this case, the filepath symbol is defined and then used on the following three lines, each of which defines a condition to be evaluated. The last line contains just two and symbols necessary to compare the three conditions.

Lexical scoping and binding

min, like many other programming languages, uses lexical scoping to resolve symbols.

Consider the following program:

 4 :a
 ( 
   a 3 + :a
   (
      a 1 + :a
      (a stack.dup * :a) dequote
   ) dequote
 ) dequote

…What is the value of the symbol a after executing it?

Simple: 4. Every quotation defines its own scope, and in each scope, a new variable called a is defined. In the innermost scope containing the quotation (a stack.dup * :a) the value of a is set to 64, but this value is not propagated to the outer scopes. Note also that the value of a in the innermost scope is first retrieved from the outer scope (8).

If we want to change the value of the original a symbol defined in the outermost scope, we have to use the bind or its shorthand sigil @, so that the program becomes the following:

 4 :a ;First definition of the symbol a
 (
   a 3 + @a ;The value of a is updated to 7.
   (
     a 1 + @a ;The value of a is updated to 8
     (a stack.dup * @a) dequote ;The value of a is now 64
   ) dequote
 ) dequote

Sealing symbols

Finally, symbols can be sealed to prevent accidental updates or deletions. By default, all symbols defined in the core min modules are sealed, so the following code if run in min shell will result in an error:

 5 :quote

…because the symbol quote is already defined in the root scope. However, note that the following code will not return an error:

 (5 :quote quote stack.dup *) -> ;returns 25

…because the quote symbol is only defined in the root scope and can therefore be redefined in child scopes.

If you want, you can seal your own symbols so that they may not be redefined using the bind operator or deleted using the delete.

Note

The unseal-symbol operator can be used to effectively un-seal a previously-sealed symbol. Use with caution!

Scopes

As explained in Definitions, min uses lexical scoping to resolve symbols and sigils. A scope is an execution context (a symbol table really) that:

The main, root-level scope in min can be accessed using the global Module symbol and it typically contains all symbols and sigils imported from all the standard library modules. The global symbol pushes a module on the stack that references the global scope:

[/Users/h3rald/test]$ global { <native> :! <native> :!= … <native> :xor <native> :zip ;module }

Note

<native> values cannot be retrieved using the dict.dget operator.

Accessing the current scope

You can access the current scope using the scope operator, which pushes a module on the stack that references the current scope.

Consider the following program:

 {} :innerscope ("This is a test" :test scope @myscope) -> myscope scope-symbols

In this case:

  1. A new variable called innerscope is defined on the global scope.
  2. A quotation is dequoted, but its scope is retrieved using the scope operator and bound to innerscope.
  3. After the quotation is dequoted, myscope is accessed and its symbols (test in this case) are pushed on the stack using the scope-symbols operator.

Note that scopes can only be accessed if they are bound to a dictionary, hence the global and scope operators push a module on the stack, and a module is nothing but a typed dictionary.

Dequoting a quotation within the context of a specific scope

The with operator can be used to dequote a quotation within a specific scope instead of the current one.

Consider the following program, which leaves 2 on the stack:

 (4 2 minus) {'- :minus} with ->

In this case, when with is pushed on the stack, it will dequote (4 2 minus). Note that the symbol minus is defined in the dictionary that will be used by with as the current scope, so after with is pushed on the stack, the stack contents are:

 4 2 (-)

At this point, the dequote operator is pushed on the stack and the subtraction is executed leaving 2 on the stack.

Control Flow

The global Module provide some symbols that can be used for the most common control flow statements. Unlike most programming languages, min does not differentiate between functions and statements – control flow statements are just ordinary symbols that manipulate the main stack.

Conditionals

The following symbols provide ways to implement common conditional statements:

For example, consider the following program:

 (
   (  
     "" :type
     (("\.(md|markdown)$") ("markdown" @type))
     (("\.txt$") ("text" @type))
     (("\.min$") ("min" @type))
     (("\.html?$") ("HTML" @type))
     ((true) ("unknown" @type))
   ) case 
   "This is a $1 file." (type) % echo
 ) ^display-file-info

This program defines a symbol display-file-info that takes a file name and outputs a message displaying its type if known.

Loops

The following symbols provide ways to implement common loops:

For example, consider the following program:

 (
   :n
   1 :i
   1 :f
   (i n <=)
   (
     f i * @f 
     i succ @i
   ) while
   f
 ) ^factorial

This program defines a symbol factorial that calculates the factorial of an integer iteratively using the symbol while.

Error handling

The following symbols provide ways to manage errors in min:

For example, consider the following program:

 . ls
 (
   (
     (fs.size) 
     (stack.pop 0)
   ) try
 ) map 
 1 (+) reduce

This program calculates the size in bytes of all files included in the current directory. Because the fs.size symbol throws an error if the argument provided is not a file (for example, if it is a directory), the try symbol is used to remove the error from the stack and push 0 on the stack instead.

Using the min Shell

The min executable also provide an interactive REPL (Read-Eval-Print Loop) when launched with no arguments:

$ min [/Users/h3rald/Development/min]$

Although not as advanced, the min REPL is not dissimilar from an OS system shell like Bash, and as a matter of fact, it provides many functionalities that are found in other shells or command prompts, such as:

…plus in can obviously leverage the entire min language for complex scripting.

Autocompletion and shortcuts

The min shell features smart tab autocompletion and keyboard shortcut implemented using the minline library.

The following behaviors are implemented when pressing the TAB key within:

Context Result
…a string Auto-completes the current word using file and directory names.
…a word starting with $ Auto-completes the current word using environment variable names.
…a word starting with ', @, (, ? Auto-completes the current word using symbol names.
…a word ending with . If the current word is a valid dictionary or module, auto-completes any symbol defined in the dictionary or module.

Additionally, the following common shortcuts are also available:

Key Effect
INSERT Switches between insert and replace mode.
UP Displays the previous history entry.
DOWN Displays the next history entry.
CTRL+d Terminates the min shell.
CTRL+u Clears the current line.
CTRL+b Goes to the beginning of the line.
CTRL+e Goes to the end of the line.

Tip

If you want, you can define your own keyboard shortcuts using the io.mapkey operator.

Shell configuration files

When the min interpreter is first launched, the following files are created automatically in the $HOME directory (%USERPROFILE% on Windows).

.minrc

This file is interpreted first every time min is run. By default it is empty, but it can be used to define code to execute at startup.

.min_history

This file is used to persist all commands entered in the min shell, and it is loaded in memory at startup to provide line history support.

.min_symbols

This files contains all symbol definitions in JSON format that were previously-saved using the save-symbol symbol. Symbols can be loaded using the load-symbol symbol.

Extending min

min provides a fairly complete standard library with many useful modules. However, you may feel the need to extend min in order to perform more specialized tasks.

In such situations, you basically have the following options:

Implementing new min modules using min itself

When you just want to create more high-level min operator using functionalities that are already available in min, the easiest way is to create your own reusable min modules.

To create a new module, simply create a file containing your operator definitions implemented using either the operator operator or the lambda operator

(stack.dup *)       ^pow2
(stack.dup stack.dup * *) ^pow3
(stack.dup * stack.dup *) ^pow4

Save your code to a file (e.g. quickpows.min) and you can use it in other Nim files using the require operator and the import (if you want to import the operators in the current scope):

'quickpows require :qp

2 qp.pow3 qp.pow2 puts ;prints 64

Specifying a prelude program

If you want, you can execute the min executable with the -p option to specify a prelude program that will be executed when min is started. This can be useful to specify your custom behaviors, selectively import modules, and define your own symbols, like this:

$ min -i -p:myfile.min

Embedding min in your Nim program

If you’d like to use min as a scripting language within your own program, and maybe extend it by implementing additional operators, you can use min as a Nim library.

To do so:

  1. Install min sources using Nifty as explained in the Download section.
  2. Import it in your Nim file.
  3. Implement a new proc to define the module.

The following code is taken from HastySite and shows how to define a new hastysite module containing some symbols (preprocess, postprocess, process-rules, …):

import min

proc hastysite_module*(i: In, hs1: HastySite) =
  var hs = hs1
  let def = i.define()

  def.symbol("preprocess") do (i: In):
    hs.preprocess()

   def.symbol("postprocess") do (i: In):
    hs.postprocess()

  def.symbol("process-rules") do (i: In):
    hs.interpret(hs.files.rules)

  # ...

  def.finalize("hastysite")

Then you need to:

  1. Instantiate a new min interpreter using the newMinInterpreter proc.
  2. Run the proc used to define the module.
  3. Call the interpret method to interpret a min file or string:
proc interpret(hs: HastySite, file: string) =
  var i = newMinInterpreter(file, file.parentDir)
  i.hastysite_module(hs)
  i.interpret(newFileStream(file, fmRead))

Tip

For more information on how to create new modules with Nim, have a look in the lib folder of the min repository, which contains all the min modules included in the standard library.

Module Management

The min executable includes a minimal but practical package manager that can be used to initialize, install, uninstall, update, list and search managed min modules stored in remote git repositories.

The min commands that make up this module management functionality is often referred to as mmm, for min module management.

How mmm works

mmm borrows most of its design from Nim’s Nimble, but it is mcuh simpler. Here are the basics:

The registry

The registry of mmm is a single JSON file accessible here:

https://min-lang.org/mmm.json

The registry contains the metadata of all public managed modules and it is queried when running every mmm command (see below).

Module lookup

When requiring a module in your min file using the {[require}} symbol, min will attempt to lookup the module (for example module1) checking the following files (in order):

Commands

The following sections explain how to use the mmm-related commands that are built-in into tbe min executable.

min init

Initializes a new managed min module in tbe current directory by creating a sample mmm.json file in the current folder.

min install [name version | name@version] [-g]

Install the specified managed module by specifying its name and version. By default, the module is installed in the mmm/<name>/<version> folder; if -g is specified, it is installed in $HOME/mmm/<name>/<version>.

If no version is specified, the version will be set to the HEAD branch of the git repository of the module.

If no name and no version are specified, all the managed modules (and their dependencies) specified as dependencies for the current managed module will be installed.

If the installation of one dependency fails, the installation of the module will be rolled back.

min uninstall [name version | name@version] [-g]

Uninstall the module specified by name and version either locally or globally (if -g is specified).

If no version is specified, the version will be set to the HEAD branch of the git repository of the module.

If no version is specified, all version of the module will be uninstalled (if the module is installed globally).

If no name and no version are specified, all dependencies of the current managed module (and their dependencies) will be uninstalled.

min update [name version | name@version] [-g]

Update the module specified by name and version either locally or globally (if -g is specified).

If no version is specified, the version will be set to the HEAD branch of the git repository of the module.

If no name and no version are specified, all dependencies of the current managed module (and their dependencies) will be updated.

min list

List all the installed dependencies of the current module, and their dependencies, recursively.

min search [arg1 arg2 … argN]

Search for a managed module matching the specified arguments. if no argument is specified, the metadata of all public managed modules will be printed.

Creating a managed min module

Creating a managed min module is easy. As a minimum, you need to create three files:

See min-highlight as an example.

Metadata

The mmm.json file of a managed min module must contain at least the following metadata:

Publishing

If you want to publish your module, just create a PR on the min git repository and modify this file by adding the metadata for your module.

Reference

min includes a small but powerful standard library organized into the following modules:

global Module
Defines the basic language constructs, such as control flow, type conversions, symbol definition and binding, exception handling, etc. This module is automatically imported (no need to prepend global. . to reference its symbols).
crypto Module
Provides operators to compute hashes (MD4, MD5, SHA1, SHA224, SHA256, SHA384, sha512), base64 encoding/decoding, and AES encryption/decryption.
dict Module
Defines operators for dictionaries, like dict.get, dict.dup, dict.set, etc. {#link-module](#min-operator-id-require}} symbol, min will attempt to lookup the module (for example module1) checking the following files (in order):

Commands

The following sections explain how to use the mmm-related commands that are built-in into tbe min executable.

min init

Initializes a new managed min module in tbe current directory by creating a sample mmm.json file in the current folder.

min install [name version | name@version] [-g]

Install the specified managed module by specifying its name and version. By default, the module is installed in the mmm/<name>/<version> folder; if -g is specified, it is installed in $HOME/mmm/<name>/<version>.

If no version is specified, the version will be set to the HEAD branch of the git repository of the module.

If no name and no version are specified, all the managed modules (and their dependencies) specified as dependencies for the current managed module will be installed.

If the installation of one dependency fails, the installation of the module will be rolled back.

min uninstall [name version | name@version] [-g]

Uninstall the module specified by name and version either locally or globally (if -g is specified).

If no version is specified, the version will be set to the HEAD branch of the git repository of the module.

If no version is specified, all version of the module will be uninstalled (if the module is installed globally).

If no name and no version are specified, all dependencies of the current managed module (and their dependencies) will be uninstalled.

min update [name version | name@version] [-g]

Update the module specified by name and version either locally or globally (if -g is specified).

If no version is specified, the version will be set to the HEAD branch of the git repository of the module.

If no name and no version are specified, all dependencies of the current managed module (and their dependencies) will be updated.

min list

List all the installed dependencies of the current module, and their dependencies, recursively.

min search [arg1 arg2 … argN]

Search for a managed module matching the specified arguments. if no argument is specified, the metadata of all public managed modules will be printed.

Creating a managed min module

Creating a managed min module is easy. As a minimum, you need to create three files:

See min-highlight as an example.

Metadata

The mmm.json file of a managed min module must contain at least the following metadata:

Publishing

If you want to publish your module, just create a PR on the min git repository and modify this file by adding the metadata for your module.

Reference

min includes a small but powerful standard library organized into the following modules:

global Module
Defines the basic language constructs, such as control flow, type conversions, symbol definition and binding, exception handling, etc. This module is automatically imported (no need to prepend global. . to reference its symbols).
crypto Module
Provides operators to compute hashes (MD4, MD5, SHA1, SHA224, SHA256, SHA384, sha512), base64 encoding/decoding, and AES encryption/decryption.
dict Module
Defines operators for dictionaries, like dict.get, dict.dup, dict.set, etc.
{#link-module)
Provides operators for reading and writing files, and accessing file information and properties.
http Module
Provides operators to perform HTTP requests, download files and create basic HTTP servers.
io Module
Provides operators for writing to STDOUT, reading from STDIN, capturing key presses, etc.
math Module
Provides many mathematical operators and constants such as trigonometric functions, square root, logarithms, etc.
net Module
Provides basic supports for sockets (some features are not supported on Windows systems).
stack Module
Defines combinators and stack-shufflers like stack.pop, stack.dup, stack.swap, stack.cons, etc.
store Module
Provides support for simple, persistent, in-memory JSON stores.
sys Module
Provides operators to use as basic shell commands, access environment variables, and execute external commands.
time Module
Provides a few basic operators to manage dates, times, and timestamps.
xml Module
Provides operators for parsing, creating and querying XML/HTML code using CSS selectors.

Notation

The following notation is used in the signature of all min operators:

Types and Values

No value.
null
null value
a
A value of any type.
bool
A boolean value
int
An integer value.
flt
A float value.
num
A numeric (integer or float) value.
str
A string value.
'sym
A string-like value (string or quoted symbol).
quot
A quotation (also expressed as parenthesis enclosing other values).
dict
A dictionary value.
dict:help

A help dictionary:

{
 "puts" :name
 "symbol" :kind
 "a ==>" :signature
 "Prints a and a new line to STDOUT." :description
 ;help
}
dict:url

An URL dictionary:

{
 "http" :scheme
 "h3rald" :hostname
 "" :port
 "" :username
 "" :password
 "/min" :path
 "" :anchor
 "" :query
 ;url
}
dict:timeinfo

A timeinfo dictionary:

{
 2017 :year
 7 :month
 8 :day
 6 :weekday
 188 :yearday
 15 :hour
 16 :minute
 25 :second
 true :dst
 -3600 :timezone ;UTC offset
 ;timeinfo
}
dict:error

An error dictionary:

{
 "MyError" :error
 "An error occurred" :message
 "symbol1" :symbol
 "dir1/file1.min" :filename
 3 :line
 13 :column
 ;error
}
dict:socket

A socket dictionary that must be created through the net.socket operator:

{
 "ipv4" :domain
 "stream" :type
 "tcp" :protocol
 ;socket
}
dict:rawval

A raw value dictionary obtained via the seq.get-raw or dict.dget-raw operators:

{
 "sym" :type
 "my-symbol" :str
 my-symbol :val
 ;rawval
}
dict:datastore

A datastore dictionary that must be created through the store.init or store.read operator:

{
 {} :data
 "path/to/file.json" :path
 ;datastore
}
dict:http-request

A request dictionary, representing an HTTP request to be performed through the operators exposed by the http Module:

{
 "http://httpbin.org/put" :url
 "PUT" :method
 "1.1" :version         ;optional
 "h3rald.com" :hostname ;optional
 {                      
  "it-id" :Accept-Language
  "httpbin.org" :Host
 } :headers             ;optional
 "test body" :body      ;optional
 ;http-request
}
dict:http-response

A response dictionary, representing an HTTP response returned by some of the operators exposed by the http Module:

{
  "1.1" :version ;optional
  200 :status    ;optional
  {
    "application/json" :Content-Type
  } :headers     ;optional
  "{\"test\": \"This is a test\"}" :body
  ;http-response
}
dict:xml-element

A dictionary representing an XML or HTML element, exposed by the xml Module

{
  {"https://min-lang.org" :href} :attributes
  ({"min web site" :text}) :children
  "a" :tag
  ;xml-element
}
dict:xml-comment

A dictionary representing an XML comment.

{
  "This is a comment" :text
  ;xml-comment
}
dict:xml-cdata

A dictionary representing XML CDATA text.

{
  "This is some text" :text
  ;xml-cdata
}
dict:xml-entity

A dictionary representing an XML entity.

{
  "amp" :text
  ;xml-entity
}
dict:xml-text

A dictionary representing XML text.

{
  "This is some text" :text
  ;xml-text
}
xml-node

A typealias to identify all XML dictionary types.

dict:xml-element||dict:xml-text||dict:xml-comment||dict:xml-entity||dict:xml-cdata

Suffixes

The following suffixes can be placed at the end of a value or type to indicate ordering or quantities.

1
The first value of the specified type.
2
The second value of the specified type.
3
The third value of the specified type.
4
The fourth value of the specified type.
?
Zero or one.
*
Zero or more.
+
One or more

global Module

!=

a1 a2 bool

Returns true if a1 is not equal to a2, false otherwise.

$

$str str get-env

See get-env.

$

$ get-env

See get-env.

%

% interpolate

See interpolate.

&&

&& expect-all

See expect-all.

'

'str str quotesym

See quotesym.

'

' quotesym

See quotesym.

*

num1 num2 num3

Multiplies num1 by num2.

+

num1 num2 num3

Sums num1 and num2.

-

num1 num2 num3

Subtracts num2 from num1.

->

-> dequote

See dequote.

-inf

num

Returns negative infinity.

/

num1 num2 num3

Divides num1 by num2.

:

:str str define

See define.

:

: define

See define.

::

:: operator

See operator.

<

a1 a2 bool

Returns true if a1 is smaller than a2, false otherwise.

Note

Only comparisons among two numbers or two strings are supported.

<=

a1 a2 bool

Returns true if a1 is smaller than or equal to a2, false otherwise.

Note

Only comparisons among two numbers or two strings are supported.

=%

=% apply-interpolate

See apply-interpolate.

=-=

=-= expect-empty-stack

See expect-empty-stack.

==

a1 a2 bool

Returns true if a1 is equal to a2, false otherwise.

==>

Symbol used to separate input and output values in operator signatures.

=>

=> apply

See apply.

>

a1 a2 bool

Returns true if a1 is greater than a2, false otherwise.

Note

Only comparisons among two numbers or two strings are supported.

><

>< infix-dequote

See infix-dequote.

>=

a1 a2 bool

Returns true if a1 is greater than or equal to a2, false otherwise.

Note

Only comparisons among two numbers or two strings are supported.

>>

>> prefix-dequote

See prefix-dequote.

?

?str str help

See help.

?

? help

See help.

@

@str str bind

See bind.

@

@ bind

See bind.

^

^str str lambda

See lambda.

^

^ lambda

See lambda.

all?

quot1 quot2 bool

Applies predicate quot2 to each element of quot1 and returns true if all elements of quot1 satisfy predicate quot2, false otherwise.

and

bool1 bool2 bool3

Returns true if bool1 is equal to bool2, false otherwise.

any?

quot1 quot2 bool

Applies predicate quot2 to each element of quot1 and returns true if at least one element of quot1 satisfies predicate quot2, false otherwise.

append

a quot (a* a)

Returns a new quotation containing the contents of quot with a appended.

apply

quot (a*)

Returns a new quotation obtained by evaluating each element of quot in a separate stack.

apply-interpolate

str quot str

The same as pushing apply and then interpolate on the stack.

args

quot

Returns a list of all arguments passed to the current program.

avg

quot num

Returns the average of the items of quot.

base

"dec"|"hex"|"oct"|"bin"

Sets the numeric base used to represent integers.

base?

"dec"|"hex"|"oct"|"bin"

Returns the numeric base currently used to represent integers (default: "dec").

bind

a 'sym

Binds the specified value (auto-quoted) to an existing symbol 'sym.

bitand

int1 int2 int3

Computes the bitwise and of integer int1 and int2.

bitclear

int1 quot int2

Sets the bytes specified via their position in int1 through quot to 0.

bitflip

int1 quot int2

Flips the bytes specified via their position in int1 through quot.

bitnot

int1 int2

Computes the bitwise complement of int1.

bitor

int1 int2 int3

Computes the bitwise or of integers int1 and int2.

bitparity

int1 int2

Calculate the bit parity in int1. If the number of 1-bits is odd, the parity is 1, otherwise 0.

bitset

int1 quot int2

Sets the bytes specified via their position in int1 through quot to 0.

bitxor

int1 int2 int3

Computes the bitwise xor of integers int1 and int2.

boolean

a bool

Converts a to a boolean value based on the following rules:

  • If a is a boolean value, no conversion is performed.
  • If a is null, it is converted to false.
  • If a is a numeric value, zero is converted to false, otherwise it is converted to true.
  • If a is a quotation or a dictionary, the empty quotation or dictionary is converted to false, otherwise it is converted to true.
  • If a is a string, the empty string, and "false" are converted to false, otherwise it is converted to true.

boolean?

a bool

Returns true if a is a boolean, false otherwise.

capitalize

'sym str

Returns a copy of 'sym with the first character capitalized.

case

((quot1 quot2)*) a*

This operator takes a quotation containing n different conditional branches.

Each branch must be a quotation containing two quotations, and it is processed as follows:

  • if quot1 evaluates to true, then the quot2 is executed.
  • if quot1 evaluates to false, then the following branch is processed (if any).

chr

int str

Returns the single character str obtained by interpreting int as an ASCII code.

compiled?

bool

Returns true if the current program has been compiled.

concat

quot1 quot2 quot3

Concatenates quot1 with quot2.

constructor

Symbol used to define a constructor when using the operator symbol. #

decode-url

'sym str

URL-decodes 'sym, deconding all URL-encoded characters.

define

a 'sym

Defines a new symbol 'sym, containing the specified value.

define-sigil

a 'sym

Defines a new sigil 'sym, containing the specified value (auto-quoted if not already a quotation).

defined-symbol?

'sym bool

Returns true if the symbol 'sym is defined, false otherwise.

defined-sigil?

'sym bool

Returns true if the symbol 'sym is defined, false otherwise.

delete-sigil

'sym

Deletes the specified user-defined sigil 'sym.

delete-symbol

'sym

Deletes the specified symbol 'sym.

dequote

quot a*

Pushes the contents of quotation quot on the stack.

Each element is pushed on the stack one by one. If any error occurs, quot is restored on the stack.

dev

Toggles development mode.

dev?

bool

Returns true if the current program is being executed in development mode.

dictionary?

a bool

Returns true if a is a dictionary, false otherwise.

difference

quot1 quot2 quot3

Calculates the difference quot3 of quot1 and quot2.

div

int1 int2 int3

Divides int1 by int2 (integer division).

drop

quot1 int quot2

Returns a quotation quot2 containing the remaining elements after the first n values of the input quotation quot1, or an empty quotation if int is greater than the length of quot1.

encode-url

'sym str

URL-encodes 'sym, encoding all special characters into URL-encoded characters.

escape

'sym str

Returns a copy of 'sym with quotes and backslashes escaped with a backslash.

eval

str a*

Parses and interprets str.

even?

int bool

Returns true if int is even, false otherwise.

exit

int

Exits the program or shell with int as return code.

expect

quot1 quot2

If the -d (--dev) flag is specified when running the program, validates the first n elements of the stack against the type descriptions specified in quot1 (n is quot1’s length) and if all the elements are valid returns them wrapped in quot2 (in reverse order). If the -d (--dev) flag is not specified when running the program, no validation is performed and all elements are just returned in a quotation in reverse order.

Tips

  • You can specify a typed dictionary by prepending the type name with dict:. Example: dict:socket
  • You can specify two or more matching types by separating combined together in a logical type expression, e.g.: string|quot

expect-all

quot bool

Assuming that quot is a quotation of quotations each evaluating to a boolean value, it pushes true on the stack if they all evaluate to true, false otherwise.

expect-any

quot bool

Assuming that quot is a quotation of quotations each evaluating to a boolean value, it pushes true on the stack if any evaluates to true, false otherwise.

expect-empty-stack

Raises an error if the stack is not empty.

filter

quot1 quot2 quot3

Returns a new quotation quot3 containing all elements of quot1 that satisfy predicate quot2.

find

quot1 quot2 int

Returns the index of the first element within quot1 that satisfies predicate quot2, or -1 if no element satisfies it.

first

quot a

Returns the first element of quot.

flatten

quot1 quot2

Flattens all quotations within quot1 and returns the resulting sequence quot2.

float

a flt

Converts a to a float value based on the following rules:

  • If a is true, it is converted to 1.0.
  • If a is false, it is converted to 0.0.
  • If a is null, it is converted to 0.0.
  • If a is a integer, it is converted to float value.
  • If a is a float, no conversion is performed.
  • If a is a string, it is parsed as a float value.

float?

a bool

Returns true if a is a float, false otherwise.

foreach

quot1 quot2 a*

Applies the quotation quot2 to each element of quot1.

format-error

dict:error str

Formats the error dict:error as a string.

from-bin

'sym int

Parses 'sym as a binary number.

from-dec

'sym int

Parses 'sym as a decimal number.

from-hex

'sym int

Parses 'sym as a hexadecimal number.

from-json

str a

Converts a JSON string into min data.

from-oct

'sym int

Parses 'sym as a octal number.

from-semver

str dict

Given a basic SemVer-compliant string (with no additional labels) str, it pushes a dictionary dict on the stack containing a major, minor, and patch key/value pairs.

from-yaml

str a

Converts a YAML string into min data.

Note

At present, only YAML objects containing string values are supported.

get

quot int a

Returns the nth element of quot (zero-based).

gets

str

Reads a line from STDIN and places it on top of the stack as a string.

get-env

'sym str

Returns environment variable 'sym.

harvest

quot1 quot2

Creates a new quotation quot2 containing all elements of quot1 except for empty quotations.

help

'sym

Prints the help text for 'sym, if available.

if

quot1 quot2 quot3 a*

If quot1 evaluates to true then evaluates quot2, otherwise evaluates quot3.

import

'sym

Imports the a previously-loaded module 'sym, defining all its symbols in the current scope.

in?

quot a bool

Returns true if a is contained in quot, false otherwise.

indent

'sym int str

Returns str containing 'sym indented with int spaces.

indexof

str1 str2 int

If str2 is contained in str1, returns the index of the first match or -1 if no match is found.

inf

num

Returns infinity.

infix-dequote

quot a

Dequotes quot using infix notation.

Note that no special operator preference is defined, symbols precedence is always left-to-right. However, you can use parentheses (quotes) to evaluate expressions before others.

insert

quot1 a int quot2

Inserts a as the value of the nth element quot1 (zero-based), and returns the modified copy of the quotation quot2.

integer

a int

Converts a to an integer value based on the following rules:

  • If a is true, it is converted to 1.
  • If a is false, it is converted to 0.
  • If a is null, it is converted to 0.
  • If a is an integer, no conversion is performed.
  • If a is a float, it is converted to an integer value by truncating its decimal part.
  • If a is a string, it is parsed as an integer value.

integer?

a bool

Returns true if a is an integer, false otherwise.

interpolate

str quot str

Substitutes the placeholders included in str with the values in quot.

Notes

  • If quot contains symbols or quotations, they are not interpreted. To do so, call apply before interpolating or use apply-interpolate instead.
  • You can use the $# placeholder to indicate the next placeholder that has not been already referenced in the string.
  • You can use named placeholders like $pwd, but in this case quot must contain a quotation containing both the placeholder names (odd items) and the values (even items).

intersection

quot1 quot2 quot3

Calculates the intersection quot3 of quot1 and quot2.

join

quot 'sym str

Joins the elements of quot using separator 'sym, producing str.

lambda

quot 'sym

Defines a new symbol 'sym, containing the specified quotation quot. Unlike with define, in this case quot will not be quoted, so its values will be pushed on the stack when the symbol 'sym is pushed on the stack.

Essentially, this symbol allows you to define an operator without any validation of constraints and bind it to a symbol.

lambda-bind

quot 'sym

Binds the specified quotation to an existing symbol 'sym which was previously-set via lambda.

last

quot a

Returns the last element of quot.

length

'sym int

Returns the length of 'sym.

line-info

dict

Returns a dictionary dict containing a filename, line, and column properties identifying the filename, line and column of the current symbol.

linrec

quot1 quot2 quot3 quot4 a*

Implements linear recursions as follows:

  1. Evaluates quot1.
    • If quot1 evaluates to true, then it evaluates quot2.
    • Otherwises it executes quot3 and recurses using the same four quotations.
  2. Finally, it executes quot4.

load

'sym a*

Parses and interprets the specified min file 'sym, adding .min if not specified.

load-symbol

'sym a*

Loads the contents of symbol 'sym from the .min_symbols file.

loglevel

'sym

Sets the current logging level to 'sym. 'sym must be one of the following strings or quoted symbols:

  • debug
  • info
  • notice
  • warn
  • error
  • fatal

Note

The default logging level is notice.

loglevel?

str

Returns the current log level (debug, info, notice, warn, error or fatal).

lowercase

'sym str

Returns a copy of 'sym converted to lowercase.

map

quot1 quot2 quot3

Returns a new quotation quot3 obtained by applying quot2 to each element of quot1.

map-reduce

quot1 quot2 quot3 int

Applies quot2 (map) to each element of quot1 and then applies quot3 (reduce) to each successive element of quot1. quot1 must have at least one element.

match?

str1 str2 bool

Returns true if str2 matches str1, false otherwise.

med

quot num

Returns the median of the items of quot.

mod

int1 int2 int3

Returns the integer module of int1 divided by int2.

nan

nan

Returns NaN (not a number).

not

bool1 bool2

Negates bool1.

null?

a bool

Returns true if a is null, false otherwise.

number?

a bool

Returns true if a is a number, false otherwise.

odd?

int bool

Returns true if int is odd, false otherwise.

one?

quot1 quot2 bool

Applies predicate quot2 to each element of quot1 and returns true if only one element of quot1 satisfies predicate quot2, false otherwise.

operator

quot a*

Provides a way to define a new operator (symbol, sigil, or typeclass) on the current scope performing additional checks (compared to define and define-sigil), and automatically mapping inputs and outputs.

quot is a quotation containing:

  • A symbol identifying the type of operator to define (symbol, sigil, constructor or typeclass).
  • A symbol identifying the name of the operator.
  • A quotation defining the signature of the operator, containing input and output values identified by their type and a capturing symbol, separated by the ==> symbol.
  • A quotation identifying the body of the operator.

The main additional features offered by this way of defining operators are the following:

  • If in development mode (-d or --dev flag specified at run time), both input and output values are checked against a type (like when using the expect operator and automatically captured in a symbol that can be referenced in the operator body quotation.
  • The full signature of the operator is declared, making the resulting code easier to understand at quick glance.
  • An exception is automatically raised if the operator body pollutes the stack by adding or removing elements from the stack (besides adding the declared output values).
  • It is possible to use the return symbol within the body quotation to immediately stop the evaluation of the body quotation and automatically push the output values on the stack.

opts

dict

Returns a dictionary of all options passed to the current program, with their respective values.

or

bool1 bool2 bool3

Returns true if bool1 or bool2 is true, false otherwise.

ord

str int

Returns the ASCII code int corresponding to the single character str.

parent-scope

dict1 dict2

Returns a dictionary dict2 holding a reference to the parent scope of dict1 or null if dict1 is global.

parse

str quot

Parses str and returns a quoted program quot.

parse-url

str dict:url

Parses the url str into its components and stores them into dict:url.

partition

quot1 quot2 quot3 quot4

Partitions quot1 into two quotations: quot3 contains all elements of quot1 that satisfy predicate quot2, quot4 all the others.

pred

int1 int2

Returns the predecessor of int1.

prefix

'sym1 'sym2 str

Prepends 'sym2 to 'sym1.

prefix-dequote

quot a

Dequotes quot using prefix notation (essentially it reverses quot and dequotes it).

prepend

a quot (a a*)

Returns a new quotation containing the contents of quot with a prepended.

print

a a

Prints a to STDOUT.

product

quot int

Returns the product of all items of quot. quot is a quotation of integers.

prompt

str

This symbol is used to configure the prompt of the min shell. By default, it is set to the following quotation:

("[$1]$$ " (sys.pwd) => %)

publish

'sym dict

Publishes symbol 'sym to the scope of dict.

put-env

'sym1 'sym2 str

Sets environment variable 'sym2 to 'sym1.

puts

a a

Prints a and a new line to STDOUT.

quit

Exits the program or shell with 0 as return code.

quotation?

a bool

Returns true if a is a quotation, false otherwise.

quote

a (a)

Wraps a in a quotation.

quote-map

quot1 quot2

Returns a new quotation quot2 obtained by quoting each element of quot1.

quotecmd

str (sym)

Creates a command with the value of str and wraps it in a quotation.

quoted-symbol?

a bool

Returns true if a is a quoted symbol, false otherwise.

quotesym

str (sym)

Creates a symbol with the value of str and wraps it in a quotation.

raise

dict:error

Raises the error specified via the dictionary dict:error.

raw-get

quot int dict:rawval

Returns the nth element of quot (zero-based) wrapped in a dict:rawval.

random

int1 int2

Returns a random number int2 between 0 and int1-1.

Note

You must call randomize to initialize the random number generator, otherwise the same sequence of numbers will be returned.

randomize

{{null}

Initializes the random number generator using a seed based on the current timestamp.

range

quot2 quot2

Takes a quotation quot1 of two or three integers in the form of start, end and an optional step (1 if not specified) and generates the sequence and returns the resulting quotation of integers quot2.

raw-args

quot

Returns a list of all arguments and (non-parsed) options passed to the current program.

reduce

quot1 a1 quot2 a2

Combines each successive element of quot1 using quot2. On the first iteration, the first two inputs processed by quot2 are a1 and the first element of quot1.

reject

quot1 quot2 quot3

Returns a new quotatios quot3 including all elements of quot1 that do not satisfy predicate quot2 (i.e. the opposite of filter)

remove

quot1 int quot2

Returns the nth element of quot1 (zero-based), and returns the modified copy of the quotation quot2.

remove-symbol

'sym

Removes the symbol 'sym from the .min_symbols file.

repeat

'sym int str

Returns str containing 'sym repeated int times.

replace

str1 str2 str3 str4

Returns a copy of str1 containing all occurrences of str2 replaced by str3

replace-apply

str1 str2 quot str3

Returns a copy of str1 containing all occurrences of str2 replaced by applying quot to each quotation corresponding to each match.

require

'sym dict

Parses and interprets (in a separated interpreter) the specified min module, and returns a module dictionary dict containing all the symbols defined in 'sym.

This symbol will attempt to locate the specified module in this way. Given the following min program:

 'my-module require :my-module
  1. Check for a file named my-module in the same folder as the current file (with our without a .min extension).
  2. Check for a file named index.min in the mmm/my-module/*/index.min folder relative to the current file (locally-installed managed-module).
  3. Check for a file named index.min in the $HOME/mmm/my-module/*/index.min folder (globally-installed managed-module). If multiple versions of the same module are present, the first one will be loaded.

rest

quot1 quot2

Returns a new quotation quot2 containing all elements of quot1 quotation except for the first.

return

If used within the body quotation of an operator definition, causes the interpreter to stop pushing further body elements on the stack and start pushing tbe operator output values on the stack.

If used outside of the body quotation of an operator definition, it raises an exception.

reverse

quot1 quot2

Returns a new quotation quot2 containing all elements of quot1 in reverse order.

save-symbol

'sym

Saves the contents of symbol 'sym to the .min_symbols file.

saved-symbols

(str*)

Returns a quotation containing all symbols saved in the .min_symbols file.

scope

dict

Returns a dictionary dict holding a reference to the current scope.

This can be useful to save a reference to a given execution scope to access later on.

scope-sigils

dict (str*)

Returns a list of all sigils defined in dictionary dict.

scope-symbols

dict (str*)

Returns a list of all symbols defined in dictionary dict.

seal-symbol

'sym

Seals symbol 'sym, so that it cannot be re-assigned.

seal-sigil

'sym

Seals the user-defined sigil 'sym, so that it cannot be re-defined.

sealed-symbol?

'sym bool

Returns true if the symbol 'sym is sealed, false otherwise.

sealed-sigil?

'sym bool

Returns true if the sigil 'sym is sealed, false otherwise.

search

str1 str2 quot

Returns a quotation containing the first occurrence of str2 within str1. Note that:

  • The first element of quot is the matching substring.
  • Other elements (if any) contain captured substrings.
  • If no matches are found, the quotation contains empty strings.

search-all

str1 str2 quot

Returns a quotation of quotations (like the one returned by the search operator) containing all occurrences of str2 within str1.

semver-inc-major

str1 str2

Increments the major digit of the SemVer-compliant string (with no additional labels) str1.

semver-inc-minor

str1 str2

Increments the minor digit of the SemVer-compliant string (with no additional labels) str1.

semver-inc-patch

str1 str2

Increments the patch digit of the SemVer-compliant string (with no additional labels) str1.

semver?

str bool

Checks whether str is a SemVer-compliant version or not.

set

quot1 a int quot2

Sets the value of the nth element quot1 (zero-based) to a, and returns the modified copy of the quotation quot2.

set-sym

quot1 'sym int quot2

Sets the value of the nth element quot1 (zero-based) to 'sym (treating it as a symbol), and returns the modified copy of the quotation quot2.

shl

int1 int2 int3

Computes the shift left operation of int1 and int2.

shorten

quot1 int quot2

Returns a quotation quot2 containing the first n values of the input quotation quot1.

shr

int1 int2 int3

Computes the shift right operation of int1 and int2.

sigil

Symbol used to define a sigil when using the operator symbol. #

sigil-help

'sym dict:help|null

Returns the help dictionary for the sigil 'sym, if available, null otherwise.

sigils

(str*)

Returns a list of all sigils defined in the global scope.

size

quot int

Returns the length of quot.

slice

quot1 int1 int2 quot2

Creates a new quotation quot2 obtaining by selecting all elements of quot1 between indexes int1 and int2.

sort

quot1 quot2 quot3

Sorts all elements of quot1 according to predicate quot2.

source

'sym quot

Display the source code of symbol 'sym (if it has been implemented a min quotation).

split

'sym1 'sym2 quot

Splits 'sym1 using separator 'sym2 (a Perl Compatible Regular Expression) and returns the resulting strings within the quotation quot.

string

a str

Converts a to its string representation.

string?

a bool

Returns true if a is a string, false otherwise.

stringlike?

a bool

Returns true if a is a string or a quoted symbol, false otherwise.

strip

'sym str

Returns str, which is set to 'sym with leading and trailing spaces removed.

substr

str1 int1 int2 str2

Returns a substring str2 obtained by retrieving int2 characters starting from index int1 within str1.

succ

int1 int2

Returns the successor of int1.

suffix

'sym1 'sym2 str

Appends 'sym2 to 'sym1.

sum

quot int

Returns the sum of all items of quot. quot is a quotation of integers.

symbol

Symbol used to define a symbol when using the operator symbol. #

symbol-help

'sym dict:help|null

Returns the help dictionary for the symbol 'sym, if available, null otherwise.

symbols

(str*)

Returns a list of all symbols defined in the global scope.

symmetric-difference

quot1 quot2 quot3

Calculates the symmetric difference quot3 of quot1 and quot2.

take

quot1 int quot2

Returns a quotation quot2 containing the first n values of the input quotation quot1, or quot1 itself if int is greater than the length of quot1.

tap

a quot a

Performs the following operations:

  1. Removes a from the stack.
  2. For each quotation defined in quot (which is a quotation of quotations each requiring one argument and returning one argument):
    1. Pushes a back to the stack.
    2. Dequotes the quotation and saves the result as a.
  3. Push the resulting a back on the stack.

times

quot int a*

Applies the quotation quot int times.

titleize

'sym str

Returns a copy of 'sym in which the first character of each word is capitalized.

to-bin

int str

Converts int to its binary representation.

to-dec

int str

Converts int to its decimal representation.

to-hex

int str

Converts int to its hexadecimal representation.

to-json

a str

Converts a into a JSON string.

to-oct

int str

Converts int to its octal representation.

to-semver

dict str

Given a a dictionary dict containing a major, minor, and patch key/value pairs , it pushes a basic SemVer-compliant string (with no additional labels) str on the stack.

to-yaml

a str

Converts a into a YAML string.

Note

At present, only min dictionaries containing string values are supported.

tokenize

str quot

Parses the min program str and returns a quotation quot containing dictionaries with a type symbol and a value symbol for each token.

try

(quot1 quot2? quot3?) a*

Evaluates a quotation as a try/catch/finally block.

The must contain the following elements:

  1. A quotation quot1 containing the code to be evaluated (try block).
  2. (optional) A quotation quot2 containing the code to execute in case of error (catch block).
  3. (optional) A quotation quot3 containing the code to execute after the code has been evaluated, whether an error occurred or not (finally block).

type

a str

Returns the data type of a. In cased of typed dictionaries, the type name is prefixed by dict:, e.g. dict:module, dict:socket, etc.

type?

a 'sym bool

Returns true if the data type of a satisfies the specified type expression 'sym, false otherwise.

typealias

'sym1 'sym2

Creates a type alias 'sym1 for type expression 'sym2.

typeclass

Symbol used to define a typeclass when using the operator symbol. #

union

quot1 quot2 quot3

Calculates the union quot3 of quot1 and quot2.

unless

quot1 quot2 a*

If 1 evaluates to false then evaluates 2.

unseal-sigil

'sym

Unseals sigil 'sym, so that it can be re-defined (system sigils cannot be unsealed).

unseal-symbol

'sym

Unseals the user-defined symbol 'sym, so that it can be re-assigned.

uppercase

'sym1 'sym2

Returns a copy of 'sym converted to uppercase.

version

str

Returns the current min version number.

when

quot1 quot2 a*

If quot1 evaluates to true then evaluates quot2.

while

quot1 quot2 a*

Executes quot2 while quot1 evaluates to true.

with

quot1 quot2 a*

Pushes each item of quot1 on the stack using the scope of quot2 as scope.

xor

bool1 bool2 bool3

Returns true if bool1 and bool2 are different, false otherwise.

||

|| expect-any

See expect-any.

~

~str str lambda-bind

See lambda-bind.

~

~ lambda-bind

See lambda-bind.

crypto Module

aes

'sym1 'sym2 str

Encrypts or decrypts 'sym1 using the Advanced Encryption Standard (AES) in CTR mode, using 'sym2 as password.

decode

'sym str

Decodes the Base64-encoded string 'sym.

encode

'sym str

Base64-encodes 'sym.

md4

'sym str

Returns the MD4 hash of 'sym.

md5

'sym str

Returns the MD5 hash of 'sym.

sha1

'sym str

Returns the SHA1 hash of 'sym.

sha224

'sym str

Returns the SHA224 hash of 'sym.

sha256

'sym str

Returns the SHA256 hash of 'sym.

sha384

'sym str

Returns the SHA384 hash of 'sym.

sha512

'sym str

Returns the SHA512 hash of 'sym.

dict Module

del

dict 'sym dict

Removes 'sym from dict1 and returns dict1.

dup

dict1 dict2

Returns a copy of dict1.

get

dict 'sym a

Returns the value of key 'sym from dictionary dict.

get-raw

dict 'sym dict:rawval

Returns the value of key 'sym from dictionary dict, wrapped in a dict:rawval.

has?

dict 'sym bool

Returns true if dictionary dict contains the key 'sym, false otherwise.

keys

dict (str*)

Returns a quotation containing all the keys of dictionary dict.

pick

dict1 quot dict2

Returns a new dictionary dict2 containing the elements of dict1 whose keys are included in quot.

pairs

dict (a*)

Returns a quotation containing a quotation for each value/key pair (value first, key second) of dictionary dict.

set

dict a 'sym dict

Sets the value of the 'sym of dict1 to a, and returns the modified dictionary dict.

set-sym

dict 'sym 'sym dict

Sets the value of the 'sym of dict1 to 'sym (treating it as a symbol), and returns the modified dictionary dict.

type

dict str

Returns a string set to the type of dict (empty if the dictionary has no type).

values

dict (a*)

Returns a quotation containing all the values of dictionary dict.

fs Module

absolute-path

'sym str

Returns the absolute path to 'sym.

absolute-path?

'sym bool

Returns true if 'sym is an absolute path.

append

str1 str2

Appends str1 to the end of file str2.

atime

'sym flt

Returns a timestamp corresponding to the time that file/directory 'sym was last accessed.

ctime

'sym flt

Returns a timestamp corresponding to the time that file/directory 'sym was created.

dir?

'sym bool

Returns true if the specified path 'sym exists and is a directory.

dirname

'sym str

Returns the path of the directory containing path 'sym.

exists?

'sym bool

Returns true if the specified file or directory 'sym exists.

expand-filename

'sym str

Returns the absolute path to the file name 'sym.

expand-symlink

'sym str

Returns the absolute path to the symlink 'sym (an error is raised if 'sym is not a symlink).

file?

'sym bool

Returns true if the specified path 'sym exists and is a file.

filename

'sym str

Returns the file name of path 'sym.

hidden?

'sym bool

Returns true if file/directory 'sym is hidden, false otherwise.

join-path

quot str

Joins the strings contained in quot with /.

mtime

'sym flt

Returns a timestamp corresponding to the time that file/directory 'sym was last modified.

normalized-path

'sym str

Returns the normalized path to 'sym.

permissions

'sym int

Returns the Unix permissions (expressed as a three-digit number) of file/directory 'sym.

read

str str

Reads the file str and puts its contents on the top of the stack as a string.

relative-path

'sym1 'sym2 str

Returns the path of 'sym1 relative to 'sym2.

size

'sym int

Returns the size in bytes of file/directory 'sym.

stats

'sym dict

Returns a dictionary dict containing information on file/directory 'sym.

symlink?

'sym bool

Returns true if the specified path 'sym exists and is a symbolic link.

type

'sym str

Returns the type of file/directory 'sym ("file" or "dir").

unix-path

'sym str

Converts all backslashes in 'sym to slashes.

windows-path

'sym str

Converts all slashes in 'sym to backslashes.

write

str1 str2

Writes str1 to the file str2, erasing all its contents first.

http Module

download

str1 str2

Downloads the contents of URL str1 to the local file str2.

get-content

str1 str2

Retrieves the contents of URL str1 as str2.

request

dict dict:http-response

Performs an HTTP request. Note that dict is can be a standard (untyped) dictionary but its fields will be validated like if it was a dict:http-request.

start-server

dict

Starts an HTTP server based on the configuration provided in dict.

dict is a dictionary containing the following keys:

address
The address to bind the server to (default: 127.0.0.1).
port
The port to bind the server to.
handler
A quotation with the following signature, used to handle all incoming requests: dict:http-requestdict:http-response

stop-server

Stops the currently-running HTTP server. This operator should be used within an HTTP server handler quotation.

io Module

ask

str1 str2

Prints str1 (prompt), reads a line from STDIN and places it on top of the stack as a string.

choose

((str1 quot1)+) str2 a*

Prints str2, then prints all str1 included in the quotation prepended with a number, and waits from valid input from the user.

If the user enters a number that matches one of the choices, then the corresponding quotation quot1 is executed, otherwise the choice menu is displayed again until a valid choice is made.

clear

Clears the screen.

color

bool

Enables or disabled color output in terminal (enabled by default).

column-print

quot int a

Prints all elements of quot to STDOUT, in int columns.

confirm

str bool

Prints str (prompt) appending " [yes/no]: ", reads a line from STDIN and:

  • if it matches /^y(es)?$/i, puts true on the stack.
  • if it matches /^no?$/i, puts false on the stack.
  • Otherwise, it prints Invalid answer. Please enter 'yes' or 'no': and waits for a new answer.

debug

a a

Prints a and a new line to STDOUT, if logging level is set to debug or lower.

error

a a

Prints a and a new line to STDERR, if logging level is set to error or lower.

fatal

a a

Prints a and a new line to STDERR, and exists the program with error code 100.

getchr

int

Reads single character from STDIN without waiting for ENTER key and places its ASCII code on top of the stack.

info

a a

Prints a and a new line to STDOUT, if logging level is set to info or lower.

mapkey

quot 'sym

Maps the named key/key combination 'sym to the quotation quot, so that quot is executed when key 'sym is pressed.

Notes

  • At present, only the key names and sequences defined in the minline library are supported.
  • The quotation will be executed by a copy of the min interpreter created when the mapping was defined. In other words, quotations executed by key bindings will not affect the current stack.

notice

a a

Prints a and a new line to STDOUT, if logging level is set to notice (default) or lower.

password

str

Reads a line from STDIN displaying * for each typed character, and places it on top of the stack as a string.

putchr

str a

Prints str to STDOUT without printing a new line (str must contain only one character).

unmapkey

'sym

Unmaps a previously-mapped key or key-combination 'sym, restoring the default mapping if available.

Notes

  • At present, only the key names and sequences defined in the minline library are supported.
  • At present, all the default mappings of min are those provided by the minline library.

warn

a a

Prints a and a new line to STDERR, if logging level is set to warn or lower.

math Module

abs

num1 num2

Calculates tbe absolute value of num1.

acos

num1 num2

Calculates the arc cosine of num1 (in radians).

asin

num1 num2

Calculates the arc sine of num1 (in radians).

atan

num1 num2

Calculates the arc tangent of num1 (in radians).

ceil

num int

Returns the smallest integer int that is not smaller than num.

cos

num1 num2

Calculates the cosine of num1 (in radians).

cosh

num1 num2

Calculates the hyperbolic cosine of num1 (in radians).

d2r

num1 num2

Converts num1 from degrees to radians.

e

num

Returns the value of the e constant (Euler’s number).

floor

num int

Returns the largest integer int that is not greater than num.

ln

num1 num2

Calculates the natural logarithm of num1.

log10

num1 num2

Calculates the common logarithm of num1.

log2

num1 num2

Calculates the binary logarithm of num1.

pi

num

Returns the value of the π constant.

pow

num1 num2 num3

Computes num1 to power raised of num2.

r2d

num1 num2

Converts num1 from radians to degrees.

round

num1 int num2

Rounds num1 to the intth decimal place.

sin

num1 num2

Calculates the sine of num1 (in radians).

sinh

num1 num2

Calculates the hyperbolic sine of num1 (in radians).

sqrt

num1 num2

Returns square root of num1.

tan

num1 num2

Calculates the tangent of num1 (in radians).

tanh

num1 num2

Calculates the hyperbolic tangent of num1 (in radians).

tau

num

Returns the value of the τ constant (2π).

trunc

num1 num2

Truncates num to the decimal point.

net Module

accept

dict:socket1 dict:socket2 dict:socket1

Makes dict:socket2 (server) accept a connection from dict:socket1 (client). Returns the client socket dict:socket1 from which it will be possible to receive data from.

close

dict:socket

Closes a previously-opened socket.

connect

dict:socket str int dict:socket

Connects socket dict:socket to address str and port int.

listen

dict dict:socket1 dict:socket2

Makes socket dict:socket1 listen to the specified address and port. dict can be empty or contain any of the following properties, used to specify the address and port to listen to respectively.

address
The address to listen to (default: 0.0.0.0).
port
The port to listen to (default: 80).

recv

dict:socket int str

Waits to receive int characters from dict:socket and returns the resulting data str.

recv-line

dict:socket str

Waits to receive a line of data from dict:socket and returns the resulting data str. "" is returned if dict:socket is disconnected.

send

dict:socket str

Sends str to the connected socket dict:socket.

socket

dict dict:socket

Opens a new socket.

dict can be empty or contain any of the following properties, used to specify the domain, type and protocol of the socket respectively.

domain

The socket domain. It can be set to one of the following values:

  • ipv4 (default): Internet Protocol version 4.
  • ipv6: Internet Protocol version 6.
  • unix: local Unix file (not supported on Windows systems).
type

The socket type. It can be set to one of the following values:

  • stream (default): Reliable stream-oriented service or Stream Socket.
  • dgram: Datagram service or Datagram Socket.
  • raw: Raw protocols atop the network layer.
  • seqpacket: Reliable sequenced packet service.
protocol

The socket protocol. It can be set to one of the following values:

  • tcp (default): Transmission Control Protocol.
  • udp: User Datagram Protocol.
  • ipv4: Internet Protocol version 4 (not supported on Windows systems).
  • ipv6: Internet Protocol version 6 (not supported on Windows systems).
  • raw: Raw IP Packets protocol (not supported on Windows systems).
  • icmp: Internet Control Message Protocol (not supported on Windows systems).

stack Module

clear

a

Empties the stack.

cleave

a1 (quot*) a*

Applies each quotation contained in the first element to the second element a1.

cons

a1 (a*) (a1 a*)

Prepends a1 to the quotation on top of the stack.

dip

a1 (a2) a* a1

Removes the first and second element from the stack, dequotes the first element, and restores the second element.

dup

a1 a1 a1

Duplicates the first element on the stack.

get

(a*)

Puts a quotation containing the contents of the stack on the stack.

keep

a1 quot a* a1

Removes the first element from the stack, dequotes it, and restores the second element.

nip

a1 a2 a2

Removes the second element from the stack.

over

a1 a2 a1 a2 a1

Pushes a copy of the second element on top of the stack.

pick

a1 a2 a3 a1 a2 a3 a1

Pushes a copy of the third element on top of the stack.

pop

a

Removes the first element from the stack.

rolldown

a1 a2 a3 a2 a3 a1

Moves the third element in first position, the second in third position and the the first in second position.

rollup

a1 a2 a3 a3 a2 a1

Moves the third and second element into second and third position and moves the first element into third position.

set

quot a*

Substitute the existing stack with the contents of quot.

sip

quot1 quot2 a* quot1

Saves the quot1, dequotes quot2, and restores quot1.

spread

a* (quot*) a*

Applies each quotation contained in the first element to each subsequent corresponding element.

swap

a1 a2 a2 a1

Swaps the first two elements on the stack.

swons

(a*) a1 (a1 a*)

Prepends a1 to the quotation that follows it.

store Module

delete

dict:datastore 'sym dict:datastore

Removes an item from the datastore dict:datastore. The item is uniquely identified by 'sym, which contains the collection containing the item and the item id, separated by a forward slash (/). Puts the reference to the modified datastore back on tbe stack.

get

dict:datastore 'sym dict

Retrieves item dict from datastore dict:datastore. dict is retrieved by specifying 'sym, which contains the collection containing the item and the item id, separated by a forward slash (/).

has?

dict:datastore 'sym bool

Returns true if dict:datastore has a key called 'sym (which contains the collection containing the item and the item id), false otherwise.

init

'sym dict:datastore

Initializes a bew datastore by creating the 'sym JSON file. Puts the datastore instance on the stack.

post

dict:datastore 'sym dict dict:datastore

Adds the dictionary dict to the datastore dict:datastore inside collection 'sym, generating and adding a unique id field to dict. If the collection 'sym does not exist it is created. Puts the reference to the modified datastore back on tbe stack.

put

dict:datastore 'sym dict dict:datastore

Adds the dictionary dict to the datastore dict:datastore. 'sym contains the collection where dict will be placed and the id of dict, separated by a forward slash (/). If the collection 'sym does not exist it is created. Puts the reference to the modified datastore back on tbe stack.

query

dict:datastore 'sym quot (dict*)

Retrieves a quotation of dictionaries from the collection 'sym of datastore dict:datastore obtained by applying quot as a filter to each item of the collection, picking only the elements that match the filter.

read

'sym dict:datastore

Reads the previously-created datastore from the file 'sym and puts the resulting datastore instance on the stack.

write

dict:datastore dict:datastore

Writes the contents of the datastore dict:datastore to the filesystem.

sys Module

admin?

bool

Returns true if the program is being run with administrative privileges.

cd

'sym

Change the current directory to 'sym.

chmod

'sym int

Sets the permissions of file or directory 'sym to int. int is a three-digit representation of user, group and other permissions. See the Unix Permissions Calculator for examples and conversions.

cp

'sym1 'sym2

Copies the file or directory 'sym1 to 'sym2.

cpu

str

Returns the host CPU. It can be one of the following strings i386, alpha, powerpc, powerpc64, powerpc64el, sparc, amd64, mips, mipsel, arm, arm64.

env?

'sym bool

Returns true if environment variable 'sym exists, false otherwise.

hardlink

'sym1 'sym2

Creates hardlink 'sym2 for file or directory 'sym1.

ls

'sym quot

Returns a quotation quot containing all children (files and directories) of the directory 'sym.

ls-r

'sym quot

Returns a quotation quot containing all children (files and directories) of the directory 'sym, recursively.

mkdir

'sym

Creates the specified directory 'sym.

mv

'sym1 'sym2

Moves the file or directory 'sym1 to 'sym2.

os

str

Returns the host operating system. It can be one of the following strings: windows, macosx, linux, netbsd, freebsd, openbsd, solaris, aix, standalone.

parent-dir

str

Returns the full path to the parent directory.

pwd

str

Returns the full path to the current directory.

rm

'sym

Deletes the specified file 'sym.

rmdir

'sym

Deletes the specified directory 'sym and all its subdirectories recursively.

run

'sym dict

Executes the external command 'sym in the current directory without displaying its output. Returns a dictionary containing the command output and return code (in keys output and code respectively).

sleep

int

Halts program execution for int milliseconds.

symlink

'sym1 'sym2

Creates symlink 'sym2 for file or directory 'sym1.

system

'sym int

Executes the external command 'sym in the current directory and pushes its return code on the stack.

unzip

'sym1 'sym2

Decompresses zip file 'sym1 to directory 'sym2 (created if not present).

which

'sym str

Returns the full path to the directory containing executable 'sym, or an empty string if the executable is not found in $PATH.

zip

quot 'sym

Compresses files included in quotation quot into zip file 'sym.

time Module

datetime

int str

Returns an ISO 8601 string representing the combined date and time in UTC of timestamp int.

format

int str str

Formats timestamp int using string str.

Tip

For information on special characters in the format string, see the format nim method.

info

int dict:timeinfo

Returns a timeinfo dictionary from timestamp int.

now

flt

Returns the current time as Unix timestamp with microseconds.

stamp

int

Returns the current time as Unix timestamp.

to-timestamp

dict:timeinfo int

Converts the timeinfo dictionary dict:timeinfo to the corresponding Unix timestamp.

xml Module

cdata

'sym dict:xml-cdata

Returns a dict:xml-cdata representing an XML CDATA section.

comment

'sym dict:xml-comment

Returns a dict:xml-comment representing an XML comment.

element

'sym dict:xml-element

Returns a dict:xml-element representing an XML element (it will be an empty element with no attributes or children).

entity

'sym dict:xml-entity

Returns a dict:xml-entity representing an XML entity.

entity2utf8

dict:xml-entity str

Returns the UTF-8 symbol corresponding to the specified XML entity.

escape

'sym str

Converts any <, >, &, ', and " present in 'sym into the corresponding XML entities.

from-html

'sym xml-node

Returns an xml-node representing an HTML string (wrapped in a <document> tag unless a valid HTML document is provided as input).

from-xml

'sym xml-node

Returns an xml-node representing an XML string (element or fragment).

query

dict:xml-element 'sym dict:xml-element

Returns an dict:xml-element representing the first element matching CSS the selector 'sym.

query-all

dict:xml-element 'sym dict:xml-element

Returns a list of dict:xml-element dictionaries representing all the elements matching CSS the selector 'sym.

text

'sym dict:xml-text

Returns a dict:xml-text representing an XML text node.

to-xml

xml-node str

Returns a str representing an XML node.