on master help sign in
Various fixes and improvements.
commit3437290d54721cb3e4742f01132afa45c5237b99 authorC. Guy Yarvin <cgyarvin@gmail.com> dateFri 22 Apr 2016, 19:14 (11 years ago) parent5b312f9
19 files changed+832−46
docs/about/overview.md+4−2 docs/programming.md+4−4 docs/programming/arvo.md+1−1 docs/programming/hoon.md+1−1 docs/programming/hoon/concepts.md+21−13 docs/programming/hoon/demo.md+2−2 docs/programming/hoon/exercises.md+1−1 docs/programming/hoon/philosophy.md → docs/programming/hoon/mission.md+13−15 docs/programming/nock.md+1−1 docs/programming/nock/interpreter.md → docs/programming/nock/definition.md+3−3 docs/programming/nock/implementations.md+8 docs/programming/nock/implementations/c.md+211 docs/programming/nock/implementations/clojure.md+124 docs/programming/nock/implementations/haskell.md+62 docs/programming/nock/implementations/hoon.md+53 docs/programming/nock/implementations/python.md+94 docs/programming/nock/implementations/ruby.md+138 docs/programming/nock/implementations/scala.md+85 docs/programming/runtime.md+6−3
docs/about/overview.md+4−2
@@ -5,7 +5,7 @@ title: System overview
55navhome: /main
66---
77
8−# System Overview
8+# System overview
99
1010<div class="row"><div class="col-md-8">
1111
@@ -31,7 +31,9 @@ Instead, the top-level event function defines an I/O protocol.
3131It maps an input event and the current state to a list of output
3232actions and the subsequent state. In Hoon:
3333
34− $+([event state] [(list action) state])
34+```
35+$-([event state] [(list action) state])
36+```
3537
3638### Nock
3739
docs/programming.md+4−4
@@ -4,9 +4,9 @@ sort: 3
44
55# Programming
66
7−Most people should start by learning Hoon. If you're a madman
8−and just want something fun fast, skim the Hoon docs, then go to
9−[Arvo systems programming](arvo/system). If you're interested in
10−the theory, learn Nock first; otherwise, learn it last.
7+Most people should start by [learning Hoon](programming/hoon). If you're a
8+madman and just want something fun fast, skim the Hoon docs, then go to [Arvo
9+systems programming](programming/arvo/system). If you're interested in the
10+theory, learn [Nock](programming/nock) first; otherwise, learn it last.
1111
1212<kids/>
docs/programming/arvo.md+1−1
@@ -1,5 +1,5 @@
11---
2−sort: 3
2+sort: 2
33title: Arvo
44---
55
docs/programming/hoon.md+1−1
@@ -1,5 +1,5 @@
11---
2−sort: 2
2+sort: 1
33title: Hoon
44---
55
docs/programming/hoon/concepts.md+21−13
@@ -19,10 +19,9 @@ ones, which mean almost the same things. But why?
1919Hoon has no close relatives. The normal jargon of programming
2020maps poorly onto its semantics. For example, although Hoon is a
2121typed language, the term "type" is not formally defined in Hoon.
22−"Type" is a great word, but Hoon has three quite separate
23−concepts which could comfortably claim it. We say "type" all the
24−time; we mean `span`, or `mold`, or `mark`, or possibly all
25−three.
22+"Type" is a great word, but Hoon has three separate concepts
23+which could comfortably claim it. We say "type" all the time; we
24+mean `span`, or `mold`, or `mark`, or possibly all three.
2625
2726Other common programming concepts used only informally in Hoon
2827are "function," "object," "event," "expression," "variable,"
@@ -30,17 +29,21 @@ are "function," "object," "event," "expression," "variable,"
3029more. We do use these words informally, but we're always making
3130an analogy whose precision depends on context.
3231
33−## Overview
32+Hoon has concepts *like* all these abstractions, but they remain
33+*false cognates*. The closer an inexact cognate, the more
34+unsettling it feels when the abstractions don't match. Learning
35+a few new words is a small price for avoiding this pain point.
3436
35−This document is a quick overview of Hoon, structured as a
36−glossary of a few major concepts: `noun` (data), `nock`
37−(interpreter), `mint` (compiler), `span` (type), `twig`
38−(expression), `gate` (function), `mold` (constructor), `core`
39−(object), `mark` (protocol).
37+## Concepts
38+
39+A few major Hoon concepts: `noun` (data), `nock` (interpreter),
40+`mint` (compiler), `span` (type), `twig` (expression), `gate`
41+(function), `mold` (constructor), `core` (object), `mark`
42+(protocol).
4043
4144### `noun` (data value)
4245
43−A value in Hoon is called a [`noun`](noun). A noun is either a
46+A value in Hoon is called a `noun`. A noun is either a
4447unsigned integer of any size (`atom`), or an ordered pair of any
4548two nouns (`cell`). Nouns are like Lisp S-expressions, but
4649simpler (Lisp atoms effectively have dynamic type bits).
@@ -62,14 +65,19 @@ One common operation on nouns is `slot`, a tree addressing
6265scheme which maps an atom to a subtree. The whole noun is slot
6366`1`; the left child of `n` is `2n`, the right child `2n+1`.
6467
68+Nothing in Nock, Hoon or Urbit can create cycles in a noun or
69+detect pointer equivalence. Nouns are generally implemented
70+with reference counting, and have a lazy short Merkle hash to
71+help with equality testing and associative containers.
72+
6573### `nock` (interpreter)
6674
67−Hoon compiles itself to the [Nock](../nock) VM. Nock is a
75+Hoon compiles itself to the [Nock](../../nock) VM. Nock is a
6876Turing-complete, non-lambda combinator function. The function
6977takes a cell `{subject formula}`, and produces a noun `product`.
7078
7179To program in Hoon, this is all you need to know about Nock. But
72−it's still fun and useful to [learn more](../nock).
80+it's still bfun and useful to [learn more](../../nock).
7381
7482## Compilation concepts
7583
docs/programming/hoon/demo.md+2−2
@@ -19,11 +19,11 @@ line is commented with its number:
1919:cons :: 7
2020 :if =(0 (mod count 15)) :: 8
2121 "FizzBuzz" :: 9
22− :if =(0 (mod count 5)) :: 10
22+ :if =(0 (mod count 5)) :: 10
2323 "Fizz" :: 11
2424 :if =(0 (mod count 3)) :: 12
2525 "Buzz" :: 13
26− (text :wrap(count)) :: 14
26+ (pave :wrap(count)) :: 14
2727:moar(count (add 1 count)) :: 15
2828```
2929
docs/programming/hoon/exercises.md+1−1
@@ -27,7 +27,7 @@ and they are intended to form a sort of primer to Hoon.
2727 "Fizz"
2828 ?: =(0 (mod count 3))
2929 "Buzz"
30− (text !>(count))
30+ (pave !>(count))
3131 $(count (add 1 count))
3232 ```
3333
docs/programming/hoon/philosophy.md → docs/programming/hoon/mission.mdrenamed+13−15
@@ -1,13 +1,13 @@
11---
22sort: 2
33next: true
4−title: Philosophy
4+title: Mission
55---
66
7−# Mission statement
7+# Mission
88
99Hoon is a strict, typed functional language which compiles itself
10−to the Nock VM (whose spec fits on a T-shirt).
10+to Nock, a combinator interpreter whose spec fits on a T-shirt.
1111
1212Hoon's design goal is to support higher-order typed functional
1313programming without category theory, formal logic, or other
@@ -20,9 +20,8 @@ But good Hoon style isn't good Haskell style. Hoon encourages
2020coders to use higher-order programming as little as possible --
2121again, simply for UI reasons. For example, multiple arguments
2222are curried by default in Haskell and tupled by default in Hoon.
23−The house style has been described as "procedural programming in
24−a functional language." The power of Haskell, or close, is there
25−when we really need it. But we try not to swat flies with it.
23+The Hoon style has been described as "procedural programming in
24+a functional language."
2625
2726Hoon is objectively simple: its complexity is bounded by the size
2827of the compiler, about 3000 lines of Hoon. This is split evenly
@@ -35,12 +34,11 @@ This ratio reflects the belief that our brains are better than
3534everyone thinks at learning languages (symbols and/or grammars),
3635and worse at learning abstractions (proofs and/or algorithms).
3736At first glance, Hoon may look gnarly (though its squiggles are
38−more structured than most ASCII-heavy languages). But there's
39−less than you might expect under the hood.
40−
41−Keeping the Hoon-to-Nock mapping straightforward is a priority.
42−Very roughly, Hoon is to Haskell as C is to Pascal. Pascal tries
43−to conceal its implementation beneath a layer of abstract
44−concepts; C, an "advanced macro assembler," tries to provide a
45−similar user experience with few abstract ideas as possible.
46−
37+more structured than most ASCII-heavy languages). But under the
38+hood, there's much less complexity than you might expect.
39+
40+Keeping the Hoon-to-Nock mapping simple and transparent is a
41+priority. In a sense, Hoon is to Haskell as C is to Pascal.
42+There is no opaque high-level abstraction of Hoon's semantics;
43+the language is what the compiler does. This design only works
44+when the compilation process is trivial or nearly so.
docs/programming/nock.md+1−1
@@ -1,5 +1,5 @@
11---
2−sort: 1
2+sort: 3
33title: Nock
44---
55
docs/programming/nock/interpreter.md → docs/programming/nock/definition.mdrenamed+3−3
@@ -1,10 +1,10 @@
11---
22sort: 1
33next: true
4−title: Interpreter
4+title: Definition
55---
66
7−# Interpreter: `nock`
7+# Definition
88
99The Nock VM is a Turing-complete function that maps a cell
1010`{subject formula}` to a noun `product`, where `subject` is the
@@ -128,7 +128,7 @@ true and `1` is false.
128128`[8 b c]` produces the product of formula `c`, against
129129a subject whose head is the product of formula `b` with the
130130original subject, and whose tail is the original subject. (Think
131−of `8` as a ``variable declaration'' or ``stack push.'')
131+of `8` as a "variable declaration" or "stack push.")
132132
133133`[9 b c]` computes the product of formula `c` with the current
134134subject; from that product `d` it extracts a formula `e` at tree
docs/programming/nock/implementations.mdnew file+8
@@ -0,0 +1,8 @@
1+---
2+sort: 4
3+title: Implementations
4+---
5+
6+# Implementations
7+
8+<list src="."></list>
docs/programming/nock/implementations/c.mdnew file+211
@@ -0,0 +1,211 @@
1+---
2+title: C
3+sort: 6
4+next: true
5+---
6+
7+# C
8+
9+The actual production interpreter. Note gotos for tail-call elimination,
10+and manual reference counting. More about the C environment can be found
11+in the [runtime system documentation](../../../runtime).
12+
13+```
14+/* nock(): produce .*(bus fol). Do not virtualize.
15+*/
16+static u3_noun
17+nock(u3_noun bus, u3_noun fol)
18+{
19+ u3_noun hib, gal;
20+
21+ while ( 1 ) {
22+ hib = u3h(fol);
23+ gal = u3t(fol);
24+
25+ if ( c3y == u3r_du(hib) ) {
26+ u3_noun poz, riv;
27+
28+ poz = nock(u3k(bus), u3k(hib));
29+ riv = nock(bus, u3k(gal));
30+
31+ u3a_lose(fol);
32+ return u3i_cell(poz, riv);
33+ }
34+ else switch ( hib ) {
35+ default: return u3m_bail(c3__exit);
36+
37+ case 0: {
38+ if ( c3n == u3r_ud(gal) ) {
39+ return u3m_bail(c3__exit);
40+ }
41+ else {
42+ u3_noun pro = u3k(u3at(gal, bus));
43+
44+ u3a_lose(bus); u3a_lose(fol);
45+ return pro;
46+ }
47+ }
48+ c3_assert(!"not reached");
49+
50+ case 1: {
51+ u3_noun pro = u3k(gal);
52+
53+ u3a_lose(bus); u3a_lose(fol);
54+ return pro;
55+ }
56+ c3_assert(!"not reached");
57+
58+ case 2: {
59+ u3_noun nex = nock(u3k(bus), u3k(u3t(gal)));
60+ u3_noun seb = nock(bus, u3k(u3h(gal)));
61+
62+ u3a_lose(fol);
63+ bus = seb;
64+ fol = nex;
65+ continue;
66+ }
67+ c3_assert(!"not reached");
68+
69+ case 3: {
70+ u3_noun gof, pro;
71+
72+ gof = nock(bus, u3k(gal));
73+ pro = u3r_du(gof);
74+
75+ u3a_lose(gof); u3a_lose(fol);
76+ return pro;
77+ }
78+ c3_assert(!"not reached");
79+
80+ case 4: {
81+ u3_noun gof, pro;
82+
83+ gof = nock(bus, u3k(gal));
84+ pro = u3i_vint(gof);
85+
86+ u3a_lose(fol);
87+ return pro;
88+ }
89+ c3_assert(!"not reached");
90+
91+ case 5: {
92+ u3_noun wim = nock(bus, u3k(gal));
93+ u3_noun pro = u3r_sing(u3h(wim), u3t(wim));
94+
95+ u3a_lose(wim); u3a_lose(fol);
96+ return pro;
97+ }
98+ c3_assert(!"not reached");
99+
100+ case 6: {
101+ u3_noun b_gal, c_gal, d_gal;
102+
103+ u3x_trel(gal, &b_gal, &c_gal, &d_gal);
104+ {
105+ u3_noun tys = nock(u3k(bus), u3k(b_gal));
106+ u3_noun nex;
107+
108+ if ( 0 == tys ) {
109+ nex = u3k(c_gal);
110+ } else if ( 1 == tys ) {
111+ nex = u3k(d_gal);
112+ } else return u3m_bail(c3__exit);
113+
114+ u3a_lose(fol);
115+ fol = nex;
116+ continue;
117+ }
118+ }
119+ c3_assert(!"not reached");
120+
121+ case 7: {
122+ u3_noun b_gal, c_gal;
123+
124+ u3x_cell(gal, &b_gal, &c_gal);
125+ {
126+ u3_noun bod = nock(bus, u3k(b_gal));
127+ u3_noun nex = u3k(c_gal);
128+
129+ u3a_lose(fol);
130+ bus = bod;
131+ fol = nex;
132+ continue;
133+ }
134+ }
135+ c3_assert(!"not reached");
136+
137+ case 8: {
138+ u3_noun b_gal, c_gal;
139+
140+ u3x_cell(gal, &b_gal, &c_gal);
141+ {
142+ u3_noun heb = nock(u3k(bus), u3k(b_gal));
143+ u3_noun bod = u3nc(heb, bus);
144+ u3_noun nex = u3k(c_gal);
145+
146+ u3a_lose(fol);
147+ bus = bod;
148+ fol = nex;
149+ continue;
150+ }
151+ }
152+ c3_assert(!"not reached");
153+
154+ case 9: {
155+ u3_noun b_gal, c_gal;
156+
157+ u3x_cell(gal, &b_gal, &c_gal);
158+ {
159+ u3_noun seb = nock(bus, u3k(c_gal));
160+
161+ if ( c3n == u3r_ud(b_gal) ) {
162+ return u3m_bail(c3__exit);
163+ }
164+ else {
165+ u3_noun nex = u3k(u3at(b_gal, seb));
166+
167+ u3a_lose(fol);
168+ bus = seb;
169+ fol = nex;
170+ continue;
171+ }
172+ }
173+ }
174+ c3_assert(!"not reached");
175+
176+ case 10: {
177+ u3_noun p_gal, q_gal;
178+
179+ u3x_cell(gal, &p_gal, &q_gal);
180+ {
181+ u3_noun zep, hod, nex;
182+
183+ if ( c3y == u3r_du(p_gal) ) {
184+ u3_noun b_gal = u3h(p_gal);
185+ u3_noun c_gal = u3t(p_gal);
186+ u3_noun d_gal = q_gal;
187+
188+ zep = u3k(b_gal);
189+ hod = nock(u3k(bus), u3k(c_gal));
190+ nex = u3k(d_gal);
191+ }
192+ else {
193+ u3_noun b_gal = p_gal;
194+ u3_noun c_gal = q_gal;
195+
196+ zep = u3k(b_gal);
197+ hod = u3_nul;
198+ nex = u3k(c_gal);
199+ }
200+
201+ u3a_lose(zep);
202+ u3a_lose(hod);
203+
204+ return nock(bus, nex);
205+ }
206+ }
207+ c3_assert(!"not reached");
208+ }
209+ }
210+}
211+```
docs/programming/nock/implementations/clojure.mdnew file+124
@@ -0,0 +1,124 @@
1+---
2+title: Clojure
3+sort: 5
4+next: true
5+---
6+
7+# Clojure
8+
9+From [Matt Earnshaw](https://github.com/mattearnshaw/anock/blob/master/src/anock/core.clj):
10+
11+```
12+(ns anock.core
13+ (:import anock.NockException))
14+
15+(declare atom? cell? cell)
16+
17+(defn noun?
18+ "A noun is an atom or a cell."
19+ [noun & ns]
20+ (if ns false
21+ (or (atom? noun) (cell? noun))))
22+
23+(defn atom?
24+ "An atom is a natural number."
25+ [noun & ns]
26+ (if ns false
27+ (and (integer? noun) (>= noun 0))))
28+
29+(defn cell?
30+ "A cell is an ordered pair of nouns."
31+ [noun]
32+ (cond
33+ (atom? noun) false
34+ (nil? noun) false
35+ (not= 2 (count noun)) false
36+ :else (and (noun? (first noun))
37+ (noun? (second noun)))))
38+
39+(defn tis
40+ "= (pronounced 'tis') tests a cell for equality."
41+ [noun]
42+ (if (atom? noun) (throw (anock.NockException. "Cannot tis an atom."))
43+ (let [[a b] noun]
44+ (if (= a b) 0 1))))
45+
46+(defn wut
47+ "? (pronounced 'wut') tests whether a noun is a cell."
48+ [noun]
49+ (cond
50+ (atom? noun) 1
51+ (cell? noun) 0
52+ :else (throw (anock.NockException. "Invalid noun."))))
53+
54+(defn lus
55+ "+ (pronounced 'lus') adds 1 to an atom."
56+ [noun]
57+ (if (atom? noun) (inc noun)
58+ (throw (anock.NockException. "Can only lus atoms."))))
59+
60+(defn fas
61+ "/ (pronounced 'fas') is a tree address function."
62+ [noun]
63+ (if (atom? noun) (throw (anock.NockException. "Cannot fas an atom."))
64+ (let [[a b] (cell noun)]
65+ (assert (and (pos? a) (atom? a)) "Subject of fas must be a positive atom.")
66+ (if (and (not (coll? b)) (or (= 2 a) (= 3 a)))
67+ (throw (anock.NockException. (str "Cannot fas noun: " noun))))
68+ (cond
69+ (= 1 a) b
70+ (= 2 a) (first b)
71+ (= 3 a) (second b)
72+ (even? a) (fas [2 (fas [(/ a 2) b])])
73+ (odd? a) (fas [3 (fas [(/ (dec a) 2) b])])))))
74+
75+(defn tar
76+ "* (pronounced 'tar') means Nock"
77+ [noun]
78+ (if (atom? noun) (throw (anock.NockException. "Cannot tar an atom."))
79+ (try
80+ (let [noun (cell noun) [x [y z]] noun]
81+ (cond
82+ (cell? y) (cell (tar [x y]) (tar [x z]))
83+ (zero? y) (fas [z x])
84+ (= 1 y) z
85+ (= 3 y) (wut (tar [x z]))
86+ (= 4 y) (lus (tar [x z]))
87+ (= 5 y) (tis (tar [x z]))
88+ :else (let [[p q] z]
89+ (cond
90+ (= 2 y) (tar [(tar [x p]) (tar [x q])])
91+ (= 6 y) (tar [x 2 [0 1] 2 [1 (first q) (second q)]
92+ [1 0] 2 [1 2 3] [1 0] 4 4 p])
93+ (= 7 y) (tar [x 2 p 1 q])
94+ (= 8 y) (tar [x 7 [[7 [0 1] p] 0 1] q])
95+ (= 9 y) (tar [x 7 q 2 [0 1] 0 p])
96+ (= 10 y) (if (cell? p)
97+ (tar [x 8 (second p) 7 [0 3] q])
98+ (tar [x q]))))))
99+ (catch RuntimeException e
100+ (throw (anock.NockException. (str "Cannot tar the noun " noun)))))))
101+
102+(def nock tar)
103+
104+; Some convenience functions
105+(defn apply* [f x]
106+ (if (and (= 1 (count x)) (coll? (first x)))
107+ (apply f x)
108+ (f x)))
109+
110+(defn bracket
111+ "[a b c] -> [a [b c]]"
112+ [[a & b :as c]]
113+ (let [b (vec b)]
114+ (cond
115+ (and (noun? a) (apply noun? b)) (vec c)
116+ (apply noun? b) (apply vector (bracket a) b)
117+ (noun? a) [a (apply* bracket b)]
118+ :else [(bracket a) (apply* bracket b)])))
119+
120+(defn cell [& nouns]
121+ (if (apply atom? nouns)
122+ (throw (anock.NockException. "Cannot convert atom to cell."))
123+ (apply* bracket nouns)))
124+```
docs/programming/nock/implementations/haskell.mdnew file+62
@@ -0,0 +1,62 @@
1+---
2+title: Haskell
3+sort: 3
4+next: true
5+---
6+
7+# Haskell
8+
9+From [Steve Dee](https://github.com/mrdomino/hsnock/blob/master/Language/Nock5K/Spec.hs):
10+
11+```
12+module Language.Nock5K.Spec where
13+import Control.Monad.Instances
14+
15+wut (a :- b) = return $ Atom 0
16+wut a = return $ Atom 1
17+
18+lus (a :- b) = Left "+[a b]"
19+lus (Atom a) = return $ Atom (1 + a)
20+
21+tis (a :- a') | a == a' = return $ Atom 0
22+tis (a :- b) = return $ Atom 1
23+tis a = Left "=a"
24+
25+fas (Atom 1 :- a) = return a
26+fas (Atom 2 :- a :- b) = return a
27+fas (Atom 3 :- a :- b) = return b
28+fas (Atom a :- b) | a > 3 = do x <- fas $ Atom (a `div` 2) :- b
29+ fas $ Atom (2 + (a `mod` 2)) :- x
30+fas a = Left "/a"
31+
32+tar (a :- (b :- c) :- d) = do x <- tar (a :- b :- c)
33+ y <- tar (a :- d)
34+ return $ x :- y
35+
36+tar (a :- Atom 0 :- b) = fas $ b :- a
37+tar (a :- Atom 1 :- b) = return b
38+tar (a :- Atom 2 :- b :- c) = do x <- tar (a :- b)
39+ y <- tar (a :- c)
40+ tar $ x :- y
41+tar (a :- Atom 3 :- b) = tar (a :- b) >>= wut
42+tar (a :- Atom 4 :- b) = tar (a :- b) >>= lus
43+tar (a :- Atom 5 :- b) = tar (a :- b) >>= tis
44+
45+tar (a :- Atom 6 :- b :- c :- d) = tar (a :- Atom 2 :- (Atom 0 :- Atom 1) :-
46+ Atom 2 :- (Atom 1 :- c :- d) :-
47+ (Atom 1 :- Atom 0) :- Atom 2 :-
48+ (Atom 1 :- Atom 2 :- Atom 3) :-
49+ (Atom 1 :- Atom 0) :- Atom 4 :-
50+ Atom 4 :- b)
51+tar (a :- Atom 7 :- b :- c) = tar (a :- Atom 2 :- b :- Atom 1 :- c)
52+tar (a :- Atom 8 :- b :- c) = tar (a :- Atom 7 :-
53+ ((Atom 7 :- (Atom 0 :- Atom 1) :- b) :-
54+ Atom 0 :- Atom 1) :- c)
55+tar (a :- Atom 9 :- b :- c) = tar (a :- Atom 7 :- c :- Atom 2 :-
56+ (Atom 0 :- Atom 1) :- Atom 0 :- b)
57+tar (a :- Atom 10 :- (b :- c) :- d) = tar (a :- Atom 8 :- c :- Atom 7 :-
58+ (Atom 0 :- Atom 3) :- d)
59+tar (a :- Atom 10 :- b :- c) = tar (a :- c)
60+
61+tar a = Left "*a"
62+```
docs/programming/nock/implementations/hoon.mdnew file+53
@@ -0,0 +1,53 @@
1+---
2+title: Hoon
3+sort: 7
4+---
5+
6+# Hoon
7+
8+```
9+|= {sub/* fol/*}
10+^- *
11+?< ?=(@ fol)
12+?: ?=(^ -.fol)
13+ [$(fol -.fol) $(fol +.fol)]
14+?+ fol
15+ !!
16+ {$0 b/@}
17+ ?< =(0 b.fol)
18+ ?: =(1 b.fol) sub
19+ ?< ?=(@ sub)
20+ =+ [now=(cap b.fol) lat=(mas b.fol)]
21+ $(b.fol lat, sub ?:(=(2 now) -.sub +.sub))
22+::
23+ {$1 b/*}
24+ b.fol
25+::
26+ {$2 b/{^ *}}
27+ =+ ben=$(fol b.fol)
28+ $(sub -.ben, fol +.ben)
29+::
30+ {$3 b/*}
31+ =+ ben=$(fol b.fol)
32+ .?(ben)
33+::
34+ {$4 b/*}
35+ =+ ben=$(fol b.fol)
36+ ?> ?=(@ ben)
37+ +(ben)
38+::
39+ {$5 b/*}
40+ =+ ben=$(fol b.fol)
41+ ?> ?=(^ ben)
42+ =(-.ben +.ben)
43+::
44+ {$6 b/* c/* d/*}
45+ $(fol =>(fol [2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]))
46+::
47+ {$7 b/* c/*} $(fol =>(fol [2 b 1 c]))
48+ {$8 b/* c/*} $(fol =>(fol [7 [[0 1] b] c]))
49+ {$9 b/* c/*} $(fol =>(fol [7 c 0 b]))
50+ {$10 @ c/*} $(fol c.fol)
51+ {$10 {b/* c/*} d/*} =+($(fol c.fol) $(fol d.fol))
52+==
53+```
docs/programming/nock/implementations/python.mdnew file+94
@@ -0,0 +1,94 @@
1+---
2+title: Python
3+sort: 1
4+next: true
5+---
6+
7+# Python
8+
9+From [James Tauber](https://github.com/jtauber/pynock/blob/master/nock.py):
10+
11+```
12+#!/usr/bin/env python3
13+
14+# []
15+def l(*lst):
16+ if len(lst) == 1:
17+ return(lst[0], 0)
18+ if len(lst) == 2:
19+ return lst
20+ else:
21+ return (lst[0], l(*lst[1:]))
22+
23+# *
24+def nock(noun):
25+ return tar(noun)
26+
27+# ?
28+def wut(noun):
29+ if isinstance(noun, int):
30+ return 1
31+ else:
32+ return 0
33+
34+
35+# +
36+def lus(noun):
37+ if isinstance(noun, int):
38+ return 1 + noun
39+ else:
40+ return noun
41+
42+
43+# =
44+def tis(noun):
45+ if noun[0] == noun[1]:
46+ return 0
47+ else:
48+ return 1
49+
50+
51+# /
52+def slot(noun):
53+ if noun[0] == 1:
54+ return noun[1]
55+ elif noun[0] == 2:
56+ return noun[1][0]
57+ elif noun[0] == 3:
58+ return noun[1][1]
59+ elif noun[0] % 2 == 0:
60+ return slot((2, slot((noun[0] // 2, noun[1]))))
61+ elif noun[0] % 2 == 1:
62+ return slot((3, slot(((noun[0] - 1) // 2, noun[1]))))
63+
64+
65+def tar(noun):
66+ if isinstance(noun[1][0], int):
67+ if noun[1][0] == 0:
68+ return slot((noun[1][1], noun[0]))
69+ elif noun[1][0] == 1:
70+ return noun[1][1]
71+ elif noun[1][0] == 2:
72+ return nock((nock((noun[0], noun[1][1][0])), nock((noun[0], noun[1][1][1]))))
73+ elif noun[1][0] == 3:
74+ return wut(nock((noun[0], noun[1][1])))
75+ elif noun[1][0] == 4:
76+ return lus(nock((noun[0], noun[1][1])))
77+ elif noun[1][0] == 5:
78+ return tis(nock((noun[0], noun[1][1])))
79+ elif noun[1][0] == 6:
80+ return nock(l(noun[0], 2, (0, 1), 2, l(1, noun[1][1][1][0], noun[1][1][1][1]), (1, 0), 2, l(1, 2, 3), (1, 0), 4, 4, noun[1][1][0]))
81+ elif noun[1][0] == 7:
82+ return nock(l(noun[0], 2, noun[1][1][0], 1, noun[1][1][1]))
83+ elif noun[1][0] == 8:
84+ return nock(l(noun[0], 7, l(l(7, (0, 1), noun[1][1][0]), 0, 1), noun[1][1][1]))
85+ elif noun[1][0] == 9:
86+ return nock(l(noun[0], 7, noun[1][1][1], l(2, (0, 1), (0, noun[1][1][0]))))
87+ elif noun[1][0] == 10:
88+ if isinstance(noun[1][1][0], int):
89+ return nock((noun[0], noun[1][1][1]))
90+ else:
91+ return nock(l(noun[0], 8, noun[1][1][0][1], 7, (0, 3), noun[1][1][1][0]))
92+ else:
93+ return (nock((noun[0], noun[1][0])), nock((noun[0], noun[1][1])))
94+```
docs/programming/nock/implementations/ruby.mdnew file+138
@@ -0,0 +1,138 @@
1+---
2+title: Ruby
3+sort: 2
4+next: true
5+---
6+
7+# Ruby
8+
9+From [T.J. Corcoran](https://github.com/TJamesCorcoran/nock/blob/master/nock.rb):
10+
11+```
12+def str_to_tree(str)
13+ arr = []
14+ str.scan(/\+|\=|\?|\/|\*|\[|\]|\d+/).each do |token|
15+ end
16+end
17+
18+def max_depth(arr)
19+ ret = arr.is_a?(Array) ? [max_depth(arr[0]), max_depth(arr[1])].max + 1 : 1
20+ ret
21+end
22+
23+def pp(arr)
24+ depth = max_depth(arr)
25+ space = 128
26+ 1.up_to(8) do |depth|
27+ space = space / 2
28+ min = 2 ** (depth - 1)
29+ max = (2 ** depth) - 1
30+ min.upto(max) { |axis|
31+ end
32+
33+end
34+
35+def norm(arr)
36+ return arr unless arr.is_a?(Array)
37+ while arr.size > 2
38+ size = arr.size
39+ arr[size - 2] = [ arr[size - 2], arr.pop ]
40+ end
41+ arr = arr.map { |x| norm(x) }
42+end
43+
44+def wut(arr)
45+ arr.is_a?(Array) ? YES : NO
46+end
47+
48+def lus(atom)
49+ raise "not an atom" unless atom.is_a?(Fixnum)
50+ atom + 1
51+end
52+
53+def tis(arr)
54+ raise "not pair" unless arr.is_a?(Array) && arr.size == 2
55+ ( arr[0] == arr[1] ) ? YES : NO
56+end
57+
58+def slot(axis, arr, allow_error = true)
59+ raise "axis on atom" unless arr.is_a?(Array)
60+ return arr if axis == 1
61+ return arr[0] if axis == 2
62+ return arr[1] if axis == 3
63+ return slot(2, slot(axis/2, arr)) if (axis %2) == 0
64+ return slot(3, slot(axis/2, arr))
65+end
66+
67+
68+def nock(arr)
69+ raise "error: nocking an atom" unless arr.is_a?(Array)
70+
71+ oper = slot(4, arr)
72+ a = slot(2, arr)
73+ b = slot(5, arr)
74+
75+ if oper.is_a?(Array)
76+ return [ nock( [ a, [b, c]]), nock( [a, d]) ]
77+ end
78+
79+
80+ case oper
81+ when 0 then
82+ slot(b,a )
83+
84+ when 1 then
85+ b
86+
87+ when 2 then
88+ b_prime = slot(2, b)
89+ c = slot(3,b)
90+ nock( [ nock([a, b_primce]), nock([a, c]) ])
91+
92+ when 3 then
93+ wut(nock([a, b]))
94+
95+ when 4 then
96+ lus(nock([a, b]))
97+
98+ when 5 then
99+ tis(nock([a, b]))
100+
101+ when 6 then
102+ b_prime = slot(2, b)
103+ c = slot(6,b)
104+ d = slot(7,b)
105+ nock( norm([a, 2, [0, 1], 2, [1, c, d], [1, 0], 2, [1, 2, 3], [1, 0], 4, 4, b]) )
106+
107+ when 7 then
108+ b_prime = slot(2, b)
109+ c = slot(3,b)
110+ nock( norm ([a, 2, b_prime, 1, c]))
111+
112+ when 8 then
113+ b_prime = slot(2, b)
114+ c = slot(3,b)
115+ nock( norm ([a, 7, [[7, [0, 1], b_prime], 0, 1], c]))
116+
117+ when 9 then
118+ b_prime = slot(2, b)
119+ c = slot(3,b)
120+ nock( norm ([a, 7, c, 2, [0, 1], 0, b_prime]))
121+
122+ when 10 then
123+ if wut(slot(2,b)) == TRUE
124+ b_prime = slot(4, b)
125+ c = slot(5, b)
126+ d = slot(3, b)
127+ c = slot(3,b)
128+ nock( norm ([a, 8, c, 7, [0, 3], d]))
129+ else
130+ b_prime = slot(2, b)
131+ c = slot(3, b)
132+ nock( norm ([a, 10, [b, c]]))
133+ end
134+ else
135+ raise "error: unknown opcode #{oper.inspect}"
136+ end
137+end
138+```
docs/programming/nock/implementations/scala.mdnew file+85
@@ -0,0 +1,85 @@
1+---
2+title: Scala
3+sort: 4
4+next: true
5+---
6+
7+# Scala
8+
9+From [Steve Randy Waldman](https://github.com/swaldman/nnnock/blob/master/src/main/scala/com/mchange/sc/v1/nnnock/package.scala):
10+
11+```
12+package object nnnock {
13+
14+ sealed trait Noun;
15+ case class Atom( value : Int ) extends Noun;
16+ case class Cell( head : Noun, tail : Noun ) extends Noun;
17+ implicit def toAtom( value : Int ) : Atom = Atom( value );
18+ implicit def toInt( atom : Atom ) : Int = atom.value;
19+
20+ def nock( a : Noun ) : Noun = *(a)
21+
22+ object Cell {
23+ private def apply( nl : List[Noun] ) : Cell = {
24+ nl match {
25+ case a :: b :: Nil => Cell(a, b);
26+ case a :: b :: c :: Nil => Cell(a, Cell(b, c));
27+ case a :: b :: c :: tail => Cell(a, this.apply( b :: c :: tail ) );
28+ }
29+ }
30+ def apply(a : Noun, b : Noun, tail : Noun*) : Cell = apply( a :: b :: tail.toList );
31+ }
32+
33+ def ?( noun : Noun ) : Noun = noun match {
34+ case _ : Cell => 0;
35+ case _ : Atom => 1;
36+ }
37+
38+ @tailrec def plus( noun : Noun ) : Noun = noun match {
39+ case a : Atom => 1 + a;
40+ case c : Cell => plus( c ); //intentional endless spin
41+ }
42+
43+ def heq( noun : Noun ) : Atom = noun match {
44+ case Cell( a : Atom, b : Atom ) => if ( a == b ) 0 else 1;
45+ case Cell( a : Cell, b : Atom ) => 1;
46+ case Cell( a : Atom, b : Cell ) => 1;
47+ case Cell( a : Cell, b : Cell ) => if ((heq( Cell( a.head, b.head ) ) | heq( Cell( a.tail, b.tail ) )) == 0) 0 else 1;
48+ case a : Atom => heq( a ); //intentional endless spin
49+ }
50+
51+ def /( noun : Noun ) : Noun = noun match {
52+ case Cell(Atom(1), a) => a;
53+ case Cell(Atom(2), Cell(a, b)) => a;
54+ case Cell(Atom(3), Cell(a, b)) => b;
55+ case Cell(Atom(value), b ) => {
56+ val a = value / 2;
57+ val num = if ( value % a == 0 ) 2 else 3;
58+ /(Cell(num, /(Cell(a, b))));
59+ }
60+ case a => /( a ); //intentional endless spin
61+ }
62+
63+ def *( noun : Noun ) : Noun = noun match {
64+ case Cell( a, Cell(Cell(b, c), d) ) => Cell( *(Cell(a,b,c)), *(Cell(a,d)) );
65+ case Cell( a, Cell(Atom(value), tail) ) => {
66+ (value, tail) match {
67+ case (0, b) => /( Cell(b, a) );
68+ case (1, b) => b;
69+ case (2, Cell(b, c)) => *( Cell( *( Cell(a,b) ), *( Cell(a,c) ) ) );
70+ case (3, b) => ?( *( Cell(a,b) ) );
71+ case (4, b) => plus( *( Cell(a,b) ) );
72+ case (5, b) => heq( *( Cell(a,b) ) );
73+ case (6, Cell(b, Cell(c, d))) => *( Cell(a,2,Cell(0,1),2,Cell(1,c,d),Cell(1,0),2,Cell(1,2,3),Cell(1,0),4,4,b) ); //wtf?
74+ case (7, Cell(b, c)) => *( Cell(a,2,b,1,c) );
75+ case (8, Cell(b, c)) => *( Cell(a,7,Cell(Cell(7,Cell(0,1),b),0,1),c) ); //wtf2
76+ case (9, Cell(b, c)) => *( Cell(a,7,c,2,Cell(0,1),0,b) );
77+ case (10, Cell(Cell(b,c),d)) => *( Cell(a,8,c,7,Cell(0,3),d) );
78+ case (10, Cell(b, c)) => *( Cell(a,c) );
79+ case _ => *( noun ); //intentional endless spin
80+ }
81+ }
82+ case a => *( a ); //intentional endless spin
83+ }
84+}
85+```
docs/programming/runtime.md+6−3
@@ -1,10 +1,13 @@
11---
22sort: 4
3−title: Runtime
3+title: Runtime system
44---
55
6−## Runtime
6+## Runtime system
77
8−The C code
8+Nock, though a conceptually simple interpreter, is executed by a
9+fairly interesting noun-specific, single-threaded runtime system.
10+All functions in the noun system proper (`noun` in the
11+interpreter tree) start with the `u3_` prefix.
912
1013<list src="."></list>