About min
min is an concatenative, fully-homoiconic, functional, interpreted programming language.
This basically means that:
- It is based on a somewhat obscure and slightly unintuitive programming paradigm, think of Forth, Factor and Joy but with parethesis for an extra Lispy flavor.
- Programs written in min are actually written using quotations, i.e. lists.
- It comes with map, filter, find, map-reduce and loads of other functional goodies. See the
seq
Module for more. - It is probably slower than the average production-ready programming language.
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.
Also, I wanted it to be fully self-contained, cross platform, and tiny. About 1MB (depending on the platform) is not really tiny, 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 am currently building a static site generator called HastySite, that 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.
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.
Getting Started
You can download one of the following pre-built min binaries:
- min v0.12.0 for macOS (x64)
- min v0.12.0 for Windows (x64)
- min v0.12.0 for Linux (x64)
- min v0.12.0 for Linux (x86)
- min v0.12.0 for Linux (arm)
Building from Source
Alternatively, you can build min from source as follows:
- Download and install nim.
- Download and build Nifty, and put the nifty executable somewhere in your $PATH.
- Clone the min repository.
- Navigate to the min repository local folder.
- Run nifty install to download min’s dependencies.
- Run nim c -d:release min.nim.
Running then min Shell
To start min shell, run min -i. You will be presented with a prompt displaying the path to the current directory:
[/Users/h3rald/test]$
You can type min code and press ENTER to evaluate it immediately:
[/Users/h3rald/test]$ 2 2 + {1} -> 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]$ dup * {1} -> 16 [/Users/h3rald/test]$
To exit min shell, press CTRL+C or type exit and press ENTER.
Executing a min Program
To execute a min script, you can:
- Run
min -e:"... program ..."
to execute a program inline. - Run
min myfile.min
to execute a program contained in a file.
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
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) (dup *) map
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:
- First a list containing the first five integer is pushed on the stack.
- Then, another list containing two symbols (
dup
and*
) is pushed on the stack. This constitutes a quoted program which, when executed duplicates (dup
) the first element on the stack and then multiplies (*
) the two elements together. - 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:
- There are no variable assignments.
- elements are pushed on the stack one by one.
- Parentheses are grouped together one or more elements, so that they are treated as a single element and they are not evaluated immediately.
- Symbols can be used to perform operations on the whole stack.
Unlike more traditional programming languages, in a concatenative programming language there is no inherent need of variables or named parameters, as symbols acts as stack operators that consume elements that are placed in order on top of a stack.
Data Types
The type system of min is very simple – only the following data types are available:
- integer
- An integer number like 1, 27 or -15.
- float
- A floating-point number like 3.14 or -56.9876.
- string
- A series of characters wrapped in double quotes: “Hello, World!”.
- quotation
- A list of elements, which may also contain symbols. Quotations can be 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).
Additionally, quotations structured in a particular way can be used as dictionaries, and a few operators are available to manage them more easily (dhas?
, dget
, ddel
and dset
). A dictionary is a quotation containing zero or more quotations of two elements, the first of which is a symbol that has not already be used in any of the other inner quotations.
The logic
Module provides predicate operators to check if an element belong to a particular data type or pseudo-type (boolean?
, number?
, integer?
, float?
, string?
, quotation?
, dictionary?
).
Note
Most of the operators defined in the num
Module are able to operate on both integers and floats.
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:
. ls (ftype "file" ==) filter '> sort
The symbol 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:
- The
.
symbol is pushed on the stack, and it is immediately evaluated to the full path to the current directory. - The
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. - The quotation
(ftype 'file ==)
is pushed on the stack. It is treated exactly like a list of data and it is not evaluated. - 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 ((ftype "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. '>
is pushed on the stack. The'
sigil can be used instead of thequote
symbol to quote a single symbol,<
in this case. In other words, it is instantly evaluated to the quotation(>)
.- The symbol
sort
is pushed on the stack. This symbol, likefilter
, 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 programs 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 synbol dequote
or its alias ->
can be used to dequote a quotation by pushing all its element on the main stack, while the symbol apply
can be used to dequote a quotation by pushing its element on a separate stack.
Operators
Every min program needs operators to:
- Manipulate elements on the stack
- Perform operations on data
- Provide side effects (read/print to standard input/output/files, etc.)
There are two types of operators: symbols and sigils.
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 dup
or .
or defined by the user. User-defined symbols must:
- Start with a letter or an underscore (_).
- Contain zero or more letters, numbers and/or any of the following characters:
/ ! ? + * . _ -
It is possible to define symbols using the define
symbol. The following min program defines a new symbol called square that duplicates the first element on the stack and multiplies the two elements:
(dup *) "square" define
Besides symbols, min provides a set of predefined sigils for commonly-used symbols. For example, the previous definition could be rewritten as follows using sigils:
(dup *) :square
A sigil like :
can be prepended to a single-word string instead of using the corresponding symbol. Essentially, sigils are nothing more than syntactic sugar. Currently min provides the following sigils:
- +
- Alias for
module
. - ~
- Alias for
delete
. - '
- Alias for
quote
. - :
- Alias for
define
. - ^
- Alias for
call
. - @
- Alias for
bind
. - >
- Alias for
save-symbol
. - <
- Alias for
load-symbol
. - =
- Alias for
quote-bind
. - #
- Alias for
quote-define
. - /
- Alias for
dget
. - %
- Alias for
dset
. - ?
- Alias for
dhas?
. - !
- Alias for
system
. - &
- Alias for
run
. - $
- Alias for
get-env
.
{#link-learn||quotations||Quotations#}
Definitions
Being a concatenative language, min does not really need named parameters or variables: simbols just pop elements off the main stack in order, and that’s normally enough. There is however one small problem witht the traditional concatenative paradigm; consider the following program for example:
dup dup
"\.zip$" match
swap fsize 1000000 > and
swap 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 how. 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 dup
and {#link-operator||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 literals of course.
Consider the following program:
:filepath
filepath "\.zip$" match
filepath fsize 1000000 >
filepath mtime 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#Lexical_scope_vs._dynamic_scope) to resolve symbols.
Consider the following program:
4 :a
(
a 3 + :a
(
a 1 + :a
(a 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 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 programs 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 dup * @a) dequote ;The value of a is now 64
) dequote
) dequote
quote-define and quote-bind
So far, we saw how to use the define
and bind
operator (or better, their shorthand sigils :
and @
) to define new symbols or bind values to existing ones.
Consider the following example:
(1 2 3 4 5) :my-list
my-list (dup *) map
If run the program above in min shell by pasting the first and then the second line in it, you’ll get an error similar to the following:
(!) <repl>(1,19) [map]: Incorrect values found on the stack:
- expected: {top} quot quot {bottom}
- got: {top} quot int {bottom}
<repl>(1,19) in symbol: map
This error says that when the map
operator was evaluated, there were incorrect values on the stack. Two quotations were expected, but instead a quotation and an integer were found. How did this happen?
Basically, when my-list
was pushed on the stack, it pushed all its item on top of the stack. If you run get-stack
, it will return the following list:
(1 2 3 4 5 (dup *))
This happens because by default min assumes that when you define a quotation you want to define a new operator rather than a list. The following program works as expected, and it returns a list containing the squares of the first five integer numbers:
(dup *) :square
(1 2 3 4 5) (square) map
To avoid this behavior – i.e. whenever you want to define a list of items rather than an operator that will be immediately evaluated when pushed on the stack, you have to use the quote-define
and the quote-bind
or their respective sigils #
and =
:
(1 2 3 4 5) #my-list
my-list (dup *) map ;Returns (1 4 9 16 25)
Sealing symbols
Finally, symbols can be sealed to pervent 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 defned in the root scope. However, note that the folliwng code will not return an error:
(5 :quote quote 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
operator can be used to effectively un-seal a previously-sealed symbol. Use with caution!
Control Flow
The lang
Module provide some symbols that can be used for the most common control flow statements. Unlike most programming language, 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:
format-error
raise
- {#link-operator||lang||try#}
For example, consider the following program:
. ls
(
(
(fsize)
(pop 0)
) try
) map
1 (+) reduce
This program calculates the size in bytes of all files included in the current directory. Because the fsize
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 the -i
flag:
$ min -i [/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:
- Auto-completion
- Persistent line history
- A customizable prompt
- Access to environment variables
…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 nimline 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 ! or & |
Auto-completes the current word using executable file 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. |
Additionally, at least some of the following systems should also be available, depending on your operating system:
Key | Effect |
---|---|
INSERT |
Switches between insert and replace mode. |
UP |
Displays the previous history entry. |
DOWN |
Displays the next history entry. |
CTRL+c |
Terminates min shell. |
CTRL+x |
Clears the current line. |
CTRL+b |
Goes to the beginning of the line. |
CTRL+e |
Goes to the end of the line. |
Shell configuration files
When the min interpreter is first launched, the following files are created automatically in the $HOME directory (%HOMEPROFILE% 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 three options:
- Implement new min modules in min
- Embed min in your Nim program
- Implemet min modules as dynamic libraries in Nim
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.
The module
(and the + sigil) allows you to create a new min module:
(
(dup *) :pow2
(dup dup * *) :pow3
(dup dup dup * * *) :pow4
) +quickpows
Save your code to a file (e.g. quickpows.min) and you can use it in other nim files using the load
operator and the import
:
'quickpows load
'quickpows import
2 pow3 pow2 puts ;prints 64
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:
- Install min sources using Nifty as explained in the Download section.
- Import it in your Nim file.
- 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 packages/min/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:
- Instantiate a new min interpreter using the
newMinInterpreter
proc. - Run the
proc
used to define the module. - 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.
Implementing min modules as dynamic libraries
Warning
This technique is currently experimental, it has not been tested extensively and it may not even work on Windows.
If you just want to add a new module to min providing functinalities that cannot be built natively with min operators, you can also implement a min module in Nim and compile it to a dynamic library which can be linked dynamically when min is started.
In order to do this, you don’t even need to download the whole min source code, you just need to download the mindyn.nim file and import it in your Nim program.
The following code shows how to create a simple min module called dyntest containing only a single operator dynplus, which essentially returns the sum of two numbers:
import mindyn
proc dyntest*(i: In) {.dynlib, exportc.} =
let def = i.define()
def.symbol("dynplus") do (i: In):
let vals = i.expect("num", "num")
let a = vals[0]
let b = vals[1]
if a.isInt:
if b.isInt:
i.push newVal(a.intVal + b.intVal)
else:
i.push newVal(a.intVal.float + b.floatVal)
else:
if b.isFloat:
i.push newVal(a.floatVal + b.floatVal)
else:
i.push newVal(a.floatVal + b.intVal.float)
def.finalize("dyntest")
Note that the mindym.nim
file contains the signatures of all the proc
s that are commonly used to define min modules, but not their implementation. Such proc
s will become available at run time when the dynamic library is linked to the min executable.
You can compile the following library by running the following command:
$ nim c –app:lib -d:release –noMain dyntest.nim
If you are using clang to compile Nim code, you may need to run the following command instead:
$ nim c –app:lib -d:release –noMain -l:“-undefined dynamic_lookup” dyntest.nim
Now you should have a libdyntest.so|dyn|dll
file. To make min load it and link it automatically when it starts, just run:
$ min –install:libdyntest.dyn
This command will copy the library file to $HOME/.minlibs/
(%HOMEPATH%\.minlibs\
on Windows). min looks for dynamic libraries in this folder when it starts.
Notes
- The dynamic library file must have the same name as the module it defines (dyntest in this case).
- At startup, min links all your installed dynamic libraries but does not import the modules automatically.
If you wish to uninstall the library, run the following command instead:
$ min –uninstall:libdyntest.dyn
Reference
min includes a small but powerful standard library organized into the following modules:
lang
Module- Defines the basic language constructs, such as control flow, type conversions, symbol definition and binding, exception handling, etc.
stack
Module- Defines combinators and stack-shufflers like dip, dup, swap, cons, etc.
seq
Module- Defines operators for quotations and dictionaries, like map, filter, reduce, etc.
io
Module- Provides operators for reading and writing files as well as printing to STDOUT and reading from STDIN.
fs
Module- Provides operators for accessing file information and properties.
logic
Module- Provides comparison operators for all min data types and other boolean logic operators.
str
Module- Provides operators to perform operations on strings, use regular expressions, interpolation, etc..
sys
Module- Provides operators to use as basic shell commands, access environment variables, and execute external commands.
num
Module- Provides operators to perform simple mathematical operations on integer and floating point numbers.
time
Module- Provides a few basic operators to manage dates, times, and timestamps.
crypto
Module- Provides operators to compute hashes (MD5, SHA1, SHA224, SHA256, SHA384, sha512), base64 encoding/decoding, and AES encryption/decryption.
math
Module- Provides many mathematical operators and constants such as trigonometric functions, square root, logarithms, etc.
Notation
The following notation is used in the signature of all min operators:
Types and Values
- ∅
- No value.
- a
- A value of any type.
- bool
- A boolean value
- int
- An integer value.
- float
- A float value.
- num
- A numeric (integer or float) value.
- string
- 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.
- tinfo
- A timeinfo dictionary:
( (“year” 2017) (“month” 7) (“day” 8) (“weekday” 6) (“yearday” 188) (“hour” 15) (“minute” 16) (“second” 25) (“dst” true) (“timezone” -3600) )
- err
- An error dictionary:
( (“error” “MyError”) (“message” “An error occurred”) (“symbol” “symbol1”) (“filename” “dir1/file1.min”) (“line” 3) (“column” 13) )
- true
- true (boolean type).
- false
- false (boolean type)
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
lang
Module
'
'string ⇒ string quote
See quote.
'
' ⇒ quote
See quote.
:
:string ⇒ string define
See define.
:
: ⇒ define
See define.
~
~string ⇒ string delete
See delete.
+
+string ⇒ string module
See module.
^
^string ⇒ string call
See call.
^
^ ⇒ call
See call.
@
@string ⇒ string bind
See bind.
@
@ ⇒ bind
See bind.
>
>string ⇒ string save-symbol
See save-symbol.
<
<string ⇒ string load-symbol
See load-symbol.
->
-> ⇒ dequote
See dequote.
=>
=> ⇒ apply
See apply.
#
#string ⇒ string quote-define
See quote-define.
=
=string ⇒ string quote-bind
See quote-bind.
quot ⇒ (a*)
Returns a new quotation quot obtained by evaluating each element of quot in a separate stack.
∅ ⇒ quot
Returns a list of all arguments passed to the current program.
a 'sym ⇒ ∅
Binds the specified value (auto-quoted) to an existing symbol 'sym.
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 a non-zero numeric value, it is converted to true, otherwise it is converted to false.
- If a is a non-empty quotation, it is converted to true, otherwise it is converted to false.
- If a is a non-empty string or not
"false"
, it is converted to true, otherwise it is converted to false.
quot 'sym ⇒ a*
Calls operator 'sym defined in scope quot.
((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).
∅ ⇒ ∅
Toggles debug mode.
∅ ⇒ bool
Returns true if debug mode is on, false otherwise.
a 'sym ⇒ ∅
Defines a new symbol 'sym, containing the specified value (auto-quoted if not already a quotation).
'sym ⇒ bool
Returns true if 'sym is defined, false otherwise.
'sym ⇒ ∅
Deletes the specified symbol 'sym.
quot ⇒ a*
Pushes the contents of quotation quot on the stack.
string ⇒ a*
Parses and interprets string.
int ⇒ ∅
Exits the program or shell with int as return code.
quot1 ⇒ quot2
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).
a ⇒ float
Converts a to an integer 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 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.
quot1 quot2 ⇒ a*
Applies the quotation quot2 to each element of quot1.
err ⇒ string
Formats the error err as a string.
string ⇒ a*
Converts a JSON string into min data.
quot1 quot2 quot3 ⇒ a*
If quot1 evaluates to true then evaluates quot2, otherwise evaluates quot3.
'sym ⇒ ∅
Imports the a previously-loaded module 'sym, defining all its symbols in the current scope.
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 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.
quot1 quot2 quot3 quot4 ⇒ a*
Implements linear recursions as follows:
- Evaluates quot1.
- If quot1 evaluates to true, then it evaluates quot2.
- Otherwises it executes quot3 and recurses using the same four quotations.
- Finally, it executes quot4.
'sym ⇒ a*
Parses and interprets the specified min file, adding .min if not specified.
'sym ⇒ a*
Loads the contents of symbol 'sym from the .min_symbols file.
'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.
quot 'sym ⇒ ∅
Creates a new module 'sym based on quotation quot.
quot ⇒ (string*)
Returns a list of all sigils defined in module quot.
quot ⇒ (string*)
Returns a list of all symbols defined in module quot.
∅ ⇒ dict
Returns a dictionary of all options passed to the current program, with their respective values.
∅ ⇒ string
This symbol is used to configure the prompt of the min shell. By default, it is set to the following quotation:
([$1]$$ " (.) => %)
Unlike other predefined symbols, this symbol is unsealed, which means it can be modified.
'sym quot ⇒ ∅
Publishes symbol 'sym to the scope of quot.
a ⇒ (a)
Wraps a in a quotation.
a 'sym ⇒ ∅
Quotes a and binds the quotation to the existing symbol 'sym.
a 'sym ⇒ ∅
Quotes a and assigns the quotation to the symbol 'sym, creating it if not already defined.
err ⇒ ∅
Raises the error specified via the dictionary err.
'sym ⇒ ∅
Removes the symbol 'sym from the .min_symbols file.
'sym ⇒ ∅
Saves the contents of symbol 'sym to the .min_symbols file.
'sym ⇒ ∅
Seals symbol 'sym, so that it cannot be re-assigned.
∅ ⇒ (string*)
Returns a list of all sigils defined in the ROOT scope.
'sym ⇒ quot
Display the source code of symbol 'sym (if it has been implemented a min quotation).
∅ ⇒ (string*)
Returns a quotation containing all symbols stored in the .min_symbols file.
a ⇒ string
Converts a to its string representation.
∅ ⇒ (string*)
Returns a list of all symbols defined in the ROOT scope.
a quot ⇒ a
Performs the following operations:
- Removes a from the stack.
- For each quotation defined in quot (which is a quotation of quotations each requiring one argument and returning one argument):
- Pushes a back to the stack.
- Dequotes the quotation and saves the result as a.
- Push the resulting a back on the stack.
a quot ⇒ a
Performs the following operations:
- Removes a from the stack.
- For each quotation defined in quot (which is a quotation of quotations each requiring one argument and returning one argument):
- Pushes a back to the stack.
- Dequotes the quotation and saves the result as a.
quot int ⇒ a*
Applies the quotation quot int times.
quot ⇒ string
Converts quot into a JSON string string.
(quot1 quot2? quot3?) ⇒ a*
Evaluates a quotation as a try/catch/finally block.
The must contain the following elements:
- A quotation quot1 containing the code to be evaluated (try block).
- (optional) A quotation quot2 containing the code to execute in case of error (catch block).
- (optional) A quotation quot3 containing the code to execute after the code has been evaluated, whether an error occurred or not (finally block).
quot1 quot2 ⇒ a*
If 1 evaluates to false then evaluates 2.
'sym ⇒ ∅
Unseals symbol 'sym, so that it can be re-assigned.
∅ ⇒ string
Returns the current min version number.
quot1 quot2 ⇒ a*
If quot1 evaluates to true then evaluates quot2.
quot1 quot2 ⇒ a*
Executes quot2 while quot1 evaluates to true.
quot1 quot2 ⇒ a*
Applies quotation quot1 within the scope of quot2.
stack
Module
∅ ⇒ ∅
Empties the stack.
a1 (quot*) ⇒ a*
Applies each quotation contained in the first element to the second element a1.
a1 (a*) ⇒ (a1 a*)
Prepends a1 to the quotation on top of the stack.
a1 (a2) ⇒ a* a1
Removes the first and second element from the stack, dequotes the first element, and restores the second element.
a1 ⇒ a1 a1
Duplicates the first element on the stack.
∅ ⇒ (a*)
Returns a quotation containing the contents of the stack.
∅ ⇒ ∅
Does nothing.
a1 quot ⇒ a* a1
Applies each quotation contained in the first element to each subsequent corresponding element.
a1 a2 ⇒ a2
Removes the second element from the stack.
a1 a2 ⇒ a1 a2 a1
Pushes a copy of the second element on top of the stack.
a1 a2 a3 ⇒ a1 a2 a3 a1
Pushes a copy of the third element on top of the stack.
a ⇒ ∅
Removes the first element from the stack.
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.
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.
quot ⇒ a*
Substitute the existing stack with the contents of quot.
a1 (a2) ⇒ a* a1
Saves the a1, dequotes a2, and restores a1.
a* (quot*) ⇒ a*
Applies each quotation contained in the first element to each subsequent corresponding element.
a1 a2 ⇒ a2 a1
Swaps the first two elements on the stack.
(a*) a1 ⇒ (a1 a*)
Prepends a1 to the quotation that follows it.
seq
Module
/
/string ⇒ string dget
See dget.
?
?string ⇒ string dhas?
See dhas?.
%
%string ⇒ string dset
See dset.
quot1 quot2 ⇒ bool
Applies predicate quot2 to each element of quot1 and returns true if all elements of quot1 satisfy predicate quot2, false otherwise.
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.
a quot ⇒ (a* a)
Returns a new quotation containing the contents of quot with a appended.
quot int ⇒ a
Returns the nth element of quot (zero-based).
quot1 quot2 ⇒ quot3
Concatenates quot1 with quot2.
dict1 'sym ⇒ dict2
Returns a copy of dict1 without the element with key 'sym.
dict 'sym ⇒ a
Returns the value of key 'sym from dictionary dict.
dict 'sym ⇒ bool
Returns true if dictionary dict contains the key 'sym, false otherwise.
dict ⇒ (string*)
Returns a quotation containing all the keys of dictionary dict.
dict1 quot ⇒ dict2
Returns a new dictionary dict2 containing the elements of dict1 whose keys are included in quot.
dict1 a 'sym ⇒ dict2
Sets the value of the 'sym of dict1 to a, and returns the modified copy of the dictionary dict2.
dict1 ⇒ dict2
Returns a new dictionary dict2 containing all elements of dict1 sorted by key in ascending order.
dict ⇒ (a*)
Returns a quotation containing all the values of dictionary dict.
quot1 quot2 ⇒ quot3
Returns a new quotation quot3 containing all elements of quot1 that satisfy predicate quot2.
quot1 quot2 ⇒ int
Returns the index of the first element within quot1 that satisfies predicate quot2.
quot ⇒ a
Returns the first element of quot.
quot1 ⇒ quot2
Flattens all quotations within quot1 and returns the resulting sequence quot2.
quot1 ⇒ quot2
Creates a new quotation quot2 containing all elements of quot1 except for empty quotations.
quot a ⇒ bool
Returns true if a is contained in quot, false otherwise.
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.
quot ⇒ a
Returns the last element of quot.
quot1 quot2 ⇒ quot3
Returns a new quotation quot3 obtained by applying quot2 to each element of quot1.
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.
quot1 quot2 ⇒ quot3 quot4
Partitions quot1 into two quotations: quot3 contains all elements of quot1 that satisfy predicate quot2, quot4 all the others.
a quot ⇒ (a a*)
Returns a new quotation containing the contents of quot with a prepended.
quot1 a quot2 ⇒ int
Combines each successive element of quot1 using quot2. On the first iteration, the first two inputs processed by quot2 are a and the first element of quot1.
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
)
quot1 int ⇒ quot2
Returns the nth element of quot1 (zero-based), and returns the modified copy of the quotation quot2.
quot1 ⇒ quot2
Returns a new quotation quot2 containing all elements of quot1 quotation except for the first.
quot1 ⇒ quot2
Returns a new quotation quot2 containing all elements of quot1 in reverse order.
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.
quot1 int ⇒ quot2
Returns a quotation quot2 containing the first n values of the input quotation quot1.
quot ⇒ int
Returns the length of quot.
quot1 a1 a2 ⇒ quot2
Creates a new quotation quot2 obtaining by selecting all elements of quot1 between indexes a1 and a2.
quot1 quot2 ⇒ quot3
Sorts all elements of quot1 according to predicate quot2.
io
Module
string1 ⇒ string2
Prints string1 (prompt), reads a line from STDIN and places it on top of the stack as a string.
((string1 quot1)+) string2 ⇒ a*
Prints string2, then prints all string1 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.
quot int ⇒ a
Prints all elements of quot to STDOUT, in int columns.
string ⇒ bool
Prints string (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.
a ⇒ a
Prints a and a new line to STDOUT, if logging level is set to debug or lower.
a ⇒ a
Prints a and a new line to STDERR, if logging level is set to error or lower.
string1 string2 ⇒ ∅
Appends string1 to the end of file string2.
a ⇒ a
Prints a and a new line to STDERR, and exists the program with error code 100
.
string ⇒ string
Reads the file string and puts its contents on the top of the stack as a string.
string1 string2 ⇒ ∅
Writes string1 to the file string2, erasing all its contents first.
∅ ⇒ string
Reads a line from STDIN and places it on top of the stack as a string.
a ⇒ a
Prints a and a new line to STDOUT, if logging level is set to info or lower.
∅ ⇒ ∅
Prints a new line to STDOUT.
a ⇒ a
Prints a and a new line to STDOUT, if logging level is set to notice (default) or lower.
∅ ⇒ string
Reads a line from STDIN displaying * for each typed character, and places it on top of the stack as a string.
a ⇒ a
Prints a to STDOUT.
a ⇒ ∅
Prints a to STDOUT and removes a from the stack.
a ⇒ a
Prints a and a new line to STDOUT.
a ⇒ ∅
Prints a and a new line to STDOUT, removing a from the stack.
a ⇒ a
Prints a and a new line to STDERR, if logging level is set to warning or lower.
fs
Module
'sym ⇒ float
Returns a timestamp corresponding to the time that file/directory 'sym was last accessed.
'sym ⇒ float
Returns a timestamp corresponding to the time that file/directory 'sym was created.
'sym ⇒ int
Returns the Unix permissions (expressed as a three-digit number) of file/directory 'sym.
'sym ⇒ int
Returns the size in bytes of file/directory 'sym.
'sym ⇒ dict
Returns a dictionary dict containing information on file/directory 'sym.
'sym ⇒ string
Returns the type of file/directory 'sym ("file"
or "dir"
).
hidden?
'sym ⇒ bool
Returns true if file/directory 'sym is hidden, false otherwise.
'sym ⇒ float
Returns a timestamp corresponding to the time that file/directory 'sym was last modified.
logic
Module
a1 a2 ⇒ bool
Returns true if a1 is greater than a2, false otherwise.
Note
Only comparisons among two numbers or two strings are supported.
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.
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.
a1 a2 ⇒ bool
Returns true if a1 is equal to a2, false otherwise.
a1 a2 ⇒ bool
Returns true if a1 is not equal to a2, false otherwise.
bool1 bool2 ⇒ bool3
Returns true if bool1 is equal to bool2, false otherwise.
a ⇒ bool
Returns true if a is a boolean, false otherwise.
a ⇒ bool
Returns true if a is a dictionary, false otherwise.
a ⇒ bool
Returns true if a is a float, false otherwise.
bool1 bool2 ⇒ bool3
Returns true if bool1 or bool2 is true, false otherwise.
a ⇒ bool
Returns true if a is an integer, false otherwise.
bool1 ⇒ bool2
Negates bool1.
a ⇒ bool
Returns true if a is a number, false otherwise.
a ⇒ bool
Returns true if a is a quotation, false otherwise.
bool1 bool2 ⇒ bool3
Returns true if bool1 and bool2 are different, false otherwise.
str
Module
%
% ⇒ interpolate
See interpolate.
=~
=~ ⇒ regex
See regex.
'sym ⇒ string
Returns a copy of 'sym with the first character capitalized.
'sym int ⇒ string
Returns string containing 'sym indented with int spaces.
string1 string2 ⇒ int
If string2 is contained in string1, returns the index of the first match or -1 if no match is found.
string quot ⇒ string
Substitutes the placeholders included in string with the values in quot.
Note
If quot contains symbols or quotations, they are not interpreted. To do so, call apply
before interpolating.
quot 'sym ⇒ string
Joins the elements of quot using separator 'sym, producing string.
'sym ⇒ int
Returns the length of 'sym.
'sym ⇒ string
Returns a copy of 'sym converted to lowercase.
string1 string2 ⇒ bool
Returns true if string2 matches string1, false otherwise.
Tip
string2 can be a sgregex.-compatible regular expression.
'sym int ⇒ string
Returns string containing 'sym repeated int times.
string1 string2 string3 ⇒ string4
Returns a copy of string1 containing all occurrences of string2 replaced by string3
Tip
string2 can be a sgregex.-compatible regular expression.
string1 string2 ⇒ quot
Performs a search and/or a search-and-replace operation using pattern string2.
string2 can be one of the following patterns:
- /search-regex/modifiers
- s/search-regex/replacemenet/modifiers
quot is always a quotation containing:
- One or more strings containing the first match and captures (if any), like for the
search
operator. - A string containing the resuling string after the search-and-replace operation.
Tip
- search-regex can be a sgregex.-compatible regular expression.
- modifiers are optionals can contain one or more of the following characters, in any order:
- i: case-insensitive match.
- m: multi-line match.
- s: dot character includes newlines.
string1 string2 ⇒ quot
Returns a quotation containing the first occurrence of string2 within string2. Note that:
- The first element of quot is the matching substring.
- Other elements (if any) contain captured substrings.
Tip
string2 can be a sgregex.-compatible regular expression.
'sym1 'sym2 ⇒ quot
Splits 'sym1 using separator 'sym2 and returns the resulting strings within the quotation quot.
'sym ⇒ string
Returns string, which is set to 'sym with leading and trailing spaces removed.
'sym ⇒ string
Returns a copy of 'sym in which the first character of each word is capitalized.
'sym1 ⇒ 'sym2
Returns a copy of 'sym converted to uppercase.
sys
Module
$
$string ⇒ string get-env
See get-env.
$
$ ⇒ get-env
See get-env.
!
!string ⇒ string system
See system.
!
! ⇒ system
See system.
&
&string ⇒ string run
See run.
&
& ⇒ run
See run.
∅ ⇒ string
Returns the full path to the current directory.
∅ ⇒ string
Returns the full path to the parent directory.
'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.
'sym ⇒ ∅
Change the current directory to {'sym.
'sym1 'sym2 ⇒ ∅
Copies the file or directory 'sym1 to 'sym2.
∅ ⇒ string
Returns the host CPU. It can be one of the following strings i386, alpha, powerpc, powerpc64, powerpc64el, sparc, amd64, mips, mipsel, arm, arm64.
'sym ⇒ bool
Returns true if environment variable 'sym exists, false otherwise.
'sym ⇒ bool
Returns true if the specified path 'sym exists and is a directory.
'sym ⇒ string
Returns the path of the directory containing path 'sym.
'sym ⇒ bool
Returns true if the specified file or directory 'sym exists.
'sym ⇒ bool
Returns true if the specified path 'sym exists and is a file.
'sym ⇒ string
Returns the file name of path 'sym.
'sym ⇒ string
Returns environment variable 'sym.
'sym1 'sym2 ⇒ ∅
Creates hardlink 'sym2 for file or directory 'sym1.
'sym ⇒ quot
Returns a quotation quot containing all children (files and directories) of the directory 'sym.
'sym ⇒ quot
Returns a quotation quot containing all children (files and directories) of the directory 'sym, recursively.
'sym ⇒ ∅
Creates the specified directory 'sym.
'sym1 'sym2 ⇒ ∅
Moves the file or directory 'sym1 to 'sym2.
∅ ⇒ string
Returns the host operating system. It can be one of the following strings: windows, macosx, linux, netbsd, freebsd, openbsd, solaris, aix, standalone.
'sym1 'sym2 ⇒ string
Sets environment variable 'sym2 to 'sym1.
'sym ⇒ ∅
Deletes the specified file 'sym.
'sym ⇒ ∅
Deletes the specified directory 'sym and all its subdirectories recursively.
'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).
int ⇒ ∅
Halts program execution for int milliseconds.
'sym1 'sym2 ⇒ ∅
Creates symlink 'sym2 for file or directory 'sym1.
'sym ⇒ bool
Returns true if the specified path 'sym exists and is a symbolic link.
'sym ⇒ ∅
Executes the external command 'sym in the current directory.
'sym ⇒ ∅
Decompresses zip file 'sym.
'sym ⇒ string
Returns the full path to the directory containing executable 'sym, or an empty string if the executable is not found in $PATH.
'sym quot ⇒ ∅
Compresses files included in quotation quot into zip file 'sym.
num
Module
num1 num2 ⇒ num3
Sums num1 and num2.
num1 num2 ⇒ num3
Subtracts num2 from num1.
∅ ⇒ num
Returns negative infinity.
num1 num2 ⇒ num3
Multiplies num1 by num2.
num1 num2 ⇒ num3
Divides num1 by num2.
int ⇒ bool
Returns true if int is even, false otherwise.
a1 a2 ⇒ a3
Divides a1 by a2 (integer division).
∅ ⇒ num
Returns infinity.
a1 a2 ⇒ a3
Returns the integer module of a1 divided by a2.
∅ ⇒ nan
Returns NaN (not a number).
int ⇒ bool
Returns true if int is odd, false otherwise.
a1 ⇒ a2
Returns the predecessor of a1.
a1 ⇒ a2
Returns a random number a2 between 0 and a1-1.
a1 ⇒ a2
Returns the successor of a1.
quot ⇒ int
Returns the sum of all items of quot. quot is a quotation of integers.
time
Module
∅ ⇒ float
Returns the current time as Unix timestamp with microseconds.
∅ ⇒ int
Returns the current time as Unix timestamp.
int ⇒ tinfo
Returns a timeinfo dictionary from timestamp int.
tinfo ⇒ int
Converts the timeinfo dictionary tinfo to the corresponding Unix timestamp.
int ⇒ string
Returns an ISO 8601 string representing the combined date and time in UTC of timestamp int.
int string ⇒ string
Formats timestamp int using string string.
Tip
For information on special characters in the format string, see the format nim method.
crypto
Module
'sym ⇒ string
Returns the MD5 hash of 'sym.
'sym ⇒ string
Returns the SHA1 hash of 'sym.
'sym ⇒ string
Returns the SHA224 hash of 'sym.
'sym ⇒ string
Returns the SHA256 hash of 'sym.
'sym ⇒ string
Returns the SHA384 hash of 'sym.
'sym ⇒ string
Returns the SHA512 hash of 'sym.
'sym ⇒ string
Base64-encodes 'sym.
'sym ⇒ string
Decodes the Base64-encoded string 'sym.
'sym1 'sym2 ⇒ string
Encrypts or decrypts 'sym1 using the Advanced Encryption Standard (AES), using 'sym2 as password.
math
Module
num1 ⇒ num2
Calculates the arc cosine of num1 (in radians).
num1 ⇒ num2
Calculates the arc sine of num1 (in radians).
num1 ⇒ num2
Calculates the arc tangent of num1 (in radians).
num ⇒ int
Returns the smallest integer int that is not smaller than num.
num1 ⇒ num2
Calculates the cosine of num1 (in radians).
num1 ⇒ num2
Calculates the hyperbolic cosine of num1 (in radians).
num1 ⇒ num2
Converts num1 from degrees to radians.
∅ ⇒ num
Returns the value of the e constant (Euler’s number).
num ⇒ int
Returns the largest integer int that is not greater than num.
num1 ⇒ num2
Calculates the natural logarithm of num1.
num1 ⇒ num2
Calculates the common logarithm of num1.
num1 ⇒ num2
Calculates the binary logarithm of num1.
∅ ⇒ num
Returns the value of the π constant.
num1 num2 ⇒ num3
Computes num1 to power raised of num2.
num1 ⇒ num2
Converts num1 from radians to degrees.
num1 int ⇒ num2
Rounds num1 to the intth decimal place.
num1 ⇒ num2
Calculates the sine of num1 (in radians).
num1 ⇒ num2
Calculates the hyperbolic sine of num1 (in radians).
num1 ⇒ num2
Returns square root of num1.
num1 ⇒ num2
Calculates the tangent of num1 (in radians).
num1 ⇒ num2
Calculates the hyperbolic tangent of num1 (in radians).
∅ ⇒ num
Returns the value of the τ constant (2π).
num1 ⇒ num2
Truncates num to the decimal point.