nix-lisp
A lisp implementation written in Nix.
Features
- No IFD. Just plain Nix.
- Macros (non-hygienic)
- Nix interop
- Shares most of its data types with Nix
- Contains syntax support and helpers to use Nix lists and attrsets
- Can call Nix functions seamlessly
- Can export functions that can be called from Nix
Example
(import ./default.nix).eval {} '' (define nixpkgs (fetchTarball 'url "https://github.com/nixos/nixpkgs/archive/a39ee95a86b1fbdfa9edd65f3810b23d82457241.tar.gz" 'sha256 "11sk5hz51189g6a5ahq3s1y65145ra8kcgzfjkmrjp1jzn7h68q8")) (define pkgs (import nixpkgs (attrs))) ((pkgs 'haskellPackages 'ghcWithPackages) (lambda (ps) (vector (ps 'relude) (ps 'pipes)))) ''
Current state
It's kinda-sorta working. It can use Nix values and call Nix functions. It is probably not very performant, and is easy to hit the stack limit. There standard library is pretty minimal, but since it's easy to use Nix builtins and nixpkgs functions, I do not expect it to be the biggest problem. PR's very welcome.
Docs
Standard library
See stdlib.nixlisp. It is also the best place look for examples.
Defining a function
(defun myDouble (x) (define two 2) (+ x two))
defun
is a macro; the above function expands to:
(define myDouble (lambda (x) (begin (define two 2) (+ x two))))
Defining a macro
(defmacro cond args (defun go (xs) (if (nil? xs) 'nil (begin (define clause (car xs)) (define condition (car clause)) (define value (car (cdr clause))) (list 'if condition value (go (cdr xs)))))) (go args))
Defining an attribute set
(attrs 'firstKey "foo" 'anotherKey 12 'yetAnotherKey (vector 1 2 3))
Types
Nix | Nixlisp |
---|---|
int | int |
string | string |
bool | bool |
null | nil |
function | nix-function |
attrs | attrs |
list | vector |
- | lambda |
- | symbol |
- | cons |
- | macro |
float | (not implemented yet) |
path | (not implemented yet) |
Nix compatibility
- Types that are unique to Nixlisp are implemented as attribute sets with a special tag on Nix side. They are not meant to be accessed, but you can pass them back to Nixlisp.
- Nixlisp lambda's can be called as normal functions from the Nix side, but they have to have at least one named parameter, and can not have variable numbero of arguments. Macros can not be called from Nix.
- nix-function's can be called just as lambda's within Nixlisp. Since they are curried by default, all of the parameters will be passed to them one after another.
- Attribute sets behave like functions, where you can pass them strings or symbols and they can do a lookup.
- Beware that a Nixlisp "list" (a nil-terminated cons-list) is not a Nix "list". A Nix list is called a "vector", and you can use the
vector
, orlist->vector
functions to construct them.
Thanks
from Hacker News https://ift.tt/yXNoqRM
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.