small,
`___` embeddable
(O,O) and
\) ) purely
---"-"--- functional!
O t u s L i s p
Based on Aki Helin's Owl-Lisp
Otus Lisp (Ol in short) is a purely functional dialect of Lisp.
Ol implements an extended subset of the R7RS Scheme (PDF), including but not limited to some SRFIs. It's tiny (~ 64KB), embeddable, and cross-platform; provides a portable, high-level interface to call code written in another language (c, python, lua, etc).
You can use Ol on Linux, Windows, macOS, Android, Chromebook*, (Open/Free/Net) BSD, Solaris and other operating systems based on various hardware architectures (intel, arm, ppc, mips, etc).
Also, Ol is ported to the web (in WebAssembly form) and can be used in Chrome, Safari, Firefox, Edge, Opera, etc.
Ubuntu (and it's descendants such as Mint, Pop!_OS, Xubuntu, etc.) users may use the official project ppa.
$ sudo add-apt-repository ppa:yuriy-chumak/ol
$ sudo apt update
$ sudo apt install ol
CentOS, Debian, openSUSE, RHEL, SL, SLE, Ubuntu, Univention precompiled packages: OpenSUSE Build Service.
Some additional libraries can be installed using 'kiss' package manager. Usage instruction available at ol-packages repository.
Q. Some folders are empty (i.e. "libraries/OpenGL"), is it ok?
A. Yes, it's ok. Some parts of Ol project are separated into their own independent repositories.
Use git clone --recursive
to get a full project. Or git submodule init; git submodule update
to update existing one.
Q. Why no arrow keys processing and a history in Ol command line?
A. For the gods of simplicity. I recommend to use an rlwrap tool
(run as rlwrap ol
in terminal, or add an alias ol="rlwrap /usr/bin/env ol"
line to your ~/.bashrc and run as just ol
).
Q. .. fatal error: stdlib.h: No such file or directory.
Q. .. fatal error: bits/libc-header-start.h: No such file or directory.
A. Install gcc multilib
, i.e. sudo apt install gcc-multilib.
Q. You reference to licenses MIT and LGPL. Can I freely choose between these two licenses?
A. Yes, you are free to choose an MIT or LGPL license.
Q. I want to run Ol in a venv (Virtual ENVironment). Can I?
A. Yes. Use --home=yours-venv-folder
command line option (more about venv).
Additionally, you can embed such a venv into the Ol executable itself (the portable form).
Q. Anything else interesting?
A. Yes, Ol provides simplest HTTP web-server for sharing a local folder over an inter/intra-net.
Just type echo ,load http/server| ol
in command line (or ,l http/server
inside Ol session),
change ol
to ol - --port 8080
to use the custom port.
Q. Why do you call the characters not "characters" but "runes"?
A. Because they are runes - letters in a wide set of alphabets :)
Q. Do you have something like "sleep mode"?
A. You can store the current REPL session with ,save "filename"
, just run later ol filename
to continue saved session.
Q. I'm lost in prefix math notation, can you help me?
A. Ol has a special math library that provides infix math notation. Use the (math infix-notation)
library.
> (import (math infix-notation))
> (print (infix-notation
1 + 2 * 3 - sqrt(4)
))
5
; '\\' is a short for infix-notation
> (print (\\ 1 + 2 * 3 - sqrt(4) ))
5
; you can view result of transformations with ",expand"
> ,expand (\\ 1 + 2 * 3 - sqrt(4) )
(- (+ 1 (* 2 3)) (sqrt 4))
Join the online gitter.im chat. Alternatively the Libera.Chat #otus-lisp (alternate lightweight web-client) channel is available (the previous Freenode channel is closed).
The Issues github page waiting for your bug reports and issues.
$ make
Advanced build instructions: doc/BUILD.md
$ ./ol
Welcome to Otus Lisp 2.6
type ',help' to help, ',quit' to end session.
>
The Ol binary includes a rich set of features (lists, vectors and bytevectors, ansi and unicode strings, infinite precision math, associative arrays aka "ff"s, i/o streams, lazy evaluations, regular expressions, continuations, exceptions, lexer parsers, async functions and actors, etc.) and can be used as a completely standalone.
$ sudo make install
Note: by default we use /usr/bin/ol for Ol binary, and /usr/lib/ol/ folder for Ol libraries.
$ sudo make uninstall
doc/CHANGELOG.md <img align="right" src="https://img.shields.io/twitter/url/https/twitter.com/otus_lisp.svg?style=social&label=Follow%20the%20%40otus_lisp%20development%20process%20on%20Twitter" alt="Follow the @otus_lisp development process on Twitter.">
The Otus Lisp language is based on Scheme R7RS (PDF) with minor changes and useful extensions.
You can find working Ol examples at:
For example:
"LogicWire" and "Digital rain" examples demonstrates native libraries direct usage (the OpenGL):
"Pacman" sample demonstrates embedding Ol scripts in native "C" code - https://github.com/yuriy-chumak/ol/tree/master/examples/pacman
The most important differences are:
integer?
for inexact numbers always returns #false in Ol.set!
in Ol (Ol is purely functional!),
define
instead.set-car!
, set-cdr!
, and set-ref!
functions are provided.(scheme dynamic-bindings)
library.write-char
, otherwise you'll write a number.substring
are valid in Ol (means "from the end of string").case
(with vectors support),if
(with then
and else
keywords,The full list can be read in doc/R7RS-DIFFERENCES.md.
Some Ol limitations:
apply
arguments count is limited to 256 in Ol (use fold
otherwise).cond-expand
, builtincase-lambda
, builtin(let* ((a b (values..
, builtin<=
in case
, builtinol-2.4`` changed to
ol-2.5`.(system args port...)
changed to (execvp args port...)
. New (system command)
introduced.(OpenGL version-X.Y)
libraries changed to (OpenGL X.Y)
.fft-size-t
changed to fft-size_t
.HAS_...
build variables changed to convenient HAVE_...
.(ilist ...)
is deprecated. Use (cons* ...)
instead.(interact ...)
from (owl (await (mail ...))
instead.(fork ...)
, (fork-named ...)
, (fork-server ...)
is deprecated. Use (async ...)
, (async 'name ...)
, (actor ...)
instead.Ol contains built-in tool for inspecting the Otus Lisp language.
You can use the REPL ,expand
command to expand high-level Ol instructions into low-level (core) Otus Lisp.
> ,expand (assert (+ 1 2) = 3)
'(ifeq (equal? ((lambda (g1) g1) (+ 1 2)) 3) #true #true (runtime-error "assertion error:" (cons (quote (+ 1 2)) (cons "must be" (cons (quote 3) '())))))
You can use the REPL ,disassembly
(or ,dis
, or ,d
) command to disassemble Otus Lisp functions to the Ol virtual machine instructions.
> ,dis (lambda () 1)
type: bytecode
code: (11 1 0 5 14 1 4 24 4 17)
disassembly '(length command . args):
(4 JAF 1 0 5)
(3 LD 1 4)
(2 RET 4)
(1 ARITY-ERROR)
> ,dis (lambda (x y) (+ x y))
type: procedure
code: #((11 3 0 7 1 1 2 6 2 6 3 17) #<+>)
disassembly '(length command . args):
(4 JAF 3 0 7)
(4 REFI 1 2 6)
(3 GOTO 6 3)
(1 ARITY-ERROR)
You can use basic Ol functionality without any installation - just copy the ol
(ol.exe
for Windows) binary to any user-accessible path.
Basic functionality includes a rich set of features: lists, vectors and bytevectors, numbers math with unlimited accuracy, strings, associative arrays (named ff
), i/o streams and files, lazy calculations, regular expressions, asyncs and actors, etc.
Advanced functionality (i.e. OpenGL support) requires a complete installation of the Ol package:
Ol command line is:
ol [options] [filename] [arguments]
echo '(print *vm-args*)' | ol - arg1 arg2
echo '(print *vm-args*)' > --version; ol -- --version arg1 arg2 arg3
Olvm command line options available:
-v
: print olvm version then exit--version
: print olvm version and licensing information then exitOl command line options available:
-v
: print ol version then exit--version
: print ol version and licensing information then exit--version=...
: overwrite ol version string--home=...
: overwrite path where to search for the ol libraries--sandbox
: enable execution in the sandbox (if OS supports)--sandbox=...
: execution in the sandbox with "..." Megs of memory preallocated--interactive
: force REPL interactive mode--non-interactive
: disable REPL interactive mode--embed
: run special reduced REPL for embed usage--
: end-of-options signOl can be executed interactively or in the unattended mode.
$ ol
Welcome to Otus Lisp 2.2,
type ',help' to help, ',quit' to end session.
; now you in REPL and can play with in
> (+ 1 2 3)
6
; or let's make some factorial calculations?
> (let factorial ((n 17))
(if (= n 0)
1
(* n (factorial (- n 1)))))
355687428096000
; this ends interactive session
> ,quit
bye bye :/
GNU/Linux, Unixes, *BSDs, macOS, ...
$ ol scriptname.ol # text script
$ ol scriptname.bl # binary (compiled) script
$ echo '(print (+ 1 2 3))' | ol
Windows:
> ol scriptname.ol
> ol scriptname.bl
> echo (print (+ 1 2 3)) | ol
OL can execute precompiled scripts. You can compile your script using this code:
(define (main . args)
(print "hello !")) ; anything you want to compile
(fasl-save main "out.bl")
where "out.bl" is your binary output file name. This code creates binary script that can be executed directly by ol or vm:
$ ./vm out.bl
hello !
$ ./ol out.bl
hello !
:exclamation: Note: Since version 2.2.1 Ol supports "constructors" - functions that are automatically executed when loading the source. This is experimental feature with no name yet, but feature is tested and will be presented as a normal feature in the next build.
Constructors are called in "use" order. The order of independent constructors is undefined. If you want to specify the order of such constructors, create a function that uses them as variables in the correct order.
So, starting from version 2.2.1 you should do:
(define (main . args)
(print "hello !")) ; anything you want to compile
(fasl-save (vm:new 63 main) "out.bl")
A virtual environment is an Ol environment such that the libraries and scripts installed into it are isolated from those installed in other virtual environments and your operating system.
Use --home=folder
or --home=folder1:folder2:...:folderN
Ol command line option, where ':' is a folder divider. Folder names '.' and '..' are allowed.
These folders are linked to the Ol's *path*
global symbol and can be used and changed at runtime freely.
repl
- the compiled ol binary interpreter/compiler (olvm bytecode)src/olvm.c
- the ol virtual machine source code (C)includes/ol/ol.h
- the common ol header (C, not required, just for use as embed)includes/ol/vm.h
- the ol virtual machine header (C, not required, just for use as embed)extensions/ffi.c
- FFI implementation (C)lang/*.scm
- ol repl and compiler source codes (Lisp)libraries/**.scm
- various OL libraries (Lisp):
libraries/scheme/core.scm
- r7rs core implementationlibraries/owl/*.scm
- legacy basic librarieslibraries/lib/*.scm
- external native library mappingstests/**
- some basic automation tests (Lisp, C, Txt)tests/rosettacode/*.scm
- additional automation tests (Lisp), described at the Rosetta Code programming chrestomathy site.Please refer to the embedding sample README.
Please refer to the project page or check the source codes - libraries/scheme/core.scm
Otus Lisp is available under 2 licenses: MIT License and GNU (L)GPLv3 License.
Copyright (c) 2011-2014 Aki Helin
Copyright (c) 2014-2024 Yuriy Chumak
Grew out of the Owl Lisp by Aki Helin: https://gitlab.com/owl-lisp/owl
Thanks to:
Resources: