The kcats Programming Language Lexicon

Table of Contents

1. Standard library source and documentation

1.1. Comparison

Words that help compare one item to another, with concepts of equal, greater, less etc.

[= [[spec [[item item] [boolean]]]
    [examples [[[1 2 =] [[]]]
               [[1 1 =] [yes]]
               [[1 1.0 =] [yes]]
               [[[1] [] =]  [[]]]
               [[[1 [[]]] [1 [[]]] =] [yes]]
               [[[1.0 ["foo"]] [1.0 ["foo"]] =]  [yes]]
               [["hi" "hi" =] [yes]]
               [["hi" "there" =] [[]]]
               [[\h \h =] [yes]]
               [[\h \i =] [[]]]
               [["hi" encode "hi" encode =] [yes]]
               [["hi" encode "there" encode =] [[]]]

               [[[] yes =] [[]]]
               [[[1.0 ["foo"]] [1.0 ["bar"]] =]  [[]]]
               [[[] [] =]  [yes]]
               [[[] [] association =] [yes]]
               [[[] [] set =] [yes]]
               [[[[a b]] [[a b]] association =] [[]]]
               [[[1 2 3] set [3 1 2] set =] [yes]]]]]]

[compare [[spec [[item item] [word]]]
          [examples [[["a" "b" compare] [[less] unwrap]]
                     [["a" "a" compare] [[equal] unwrap]]
                     [[1 1 compare] [[equal] unwrap]]
                     [[2 1 compare] [[greater] unwrap]]
                     [[1 [foo] unwrap compare] [[less] unwrap]]
                     [[1 "foo" encode compare] [[less] unwrap]]
                     [[[foo] unwrap "foo" encode compare] [[less] unwrap]]
                     [["foo" encode "foo" compare] [[less] unwrap]]
                     [[[] [[]] unwrap compare] [[equal] unwrap]]
                     [[[] [1] rest compare] [[equal] unwrap]]
                    ]]]]

;; TODO these should be in terms of compare and not limited to numbers
[< [[spec [[number number] [boolean]]]
    [examples [[[1 2 <] [yes]]
               [[2.2 1.1 <] [[]]]
               [[1 2.2 <] [yes]]
               [[1.1 1.1 <] [[]]]]]]]

[> [[spec [[number number] [boolean]]]
    [examples [[[2 1 >] [yes]]
               [[1.1 2.2 >] [[]]]
               [[2.2 1 >] [yes]]
               [[1.1 1.1 >] [[]]]]]]]

[<= [[spec [[number number] [boolean]]]
     [examples [[[1 2 <=] [yes]]
                [[2.2 1.1 <=] [[]]]
                [[1 2.2 <=] [yes]]
                [[1.1 1.1 <=] [yes]]]]]]

[>= [[spec [[number number] [boolean]]]
     [examples [[[2 1 >=] [yes]]
                [[1.1 2.2 >=] [[]]]
                [[2.2 1 >=] [yes]]
                [[1.1 1.1 >=] [yes]]]]]]
[min [[spec [[number number] [number]]]
      [definition [[<] [] [swap] if drop]]
      [examples [[[2 3 min] [2]]
                 [[-5 -3 min] [-5]]
                 [[0.3 0.2 min] [0.2]]]]]]

[max [[spec [[number number] [number]]]
      [definition [[>] [] [swap] if drop]]
      [examples [[[2 3 max] [3]]
                 [[-5 -3 max] [-3]]
                 [[0.3 0.2 max] [0.3]]]]]]

1.2. Stack Ops

[drop [[spec [[item] []]]
       [examples [[[1 2 3 drop] [1 2]]
                  [[1 2 3 [a b c] drop] [1 2 3]]]]]]

[clone [[spec [[[item a]]
               [[item a] [item a]]]]
        [examples [[[1 2 3 clone] [1 2 3 3]]]]]]

[evert [[spec [[list] [list *]]]
        [examples [[[1 2 3 [4 5 6] evert] [6 5 4 [3 2 1]]]]]]]
[clonedown [[spec [[[item a] [item b]]
                   [[item a] [item b] [item b]]]]
            [definition [swap clone float]]
            [examples [[[1 2 3 clonedown] [1 2 2 3]]]]]]

[clonedeep [[spec [[[item a] [item b] [item c]]
                   [[item a] [item b] [item c] [item c]]]]
            [definition [[clonedown] dip]]
            [examples [[[1 2 3 4 clonedeep] [1 2 2 3 4]]]]]]

[over [[spec [[[item a] [item b]]
              [[item b] [item a] [item b]]]]
       [definition [clonedown swap]]
       [examples [[[1 2 3 over] [1 2 3 2]]]]]]

[under [[spec [[[item a] [item b]]
               [[item a] [item b] [item a]]]]
        [definition [clone sink]]
        [examples [[[1 2 3 under] [1 3 2 3]]]]]]

[dropdown [[spec [[[item a] [item b]] [[item b]]]]
           [definition [swap drop]]
           [examples [[[1 2 3 dropdown] [1 3]]]]]]

[dropdeep [[spec [[[item a] [item b] [item c]] [[item a] [item b]]]]
           [definition [float drop]]
           [examples [[[1 2 3 dropdeep] [2 3]]]]]]

[snapshot [[spec [[] [list]]]
           [doc "Save the whole stack as a list on the stack"]
           [definition [[] evert clone evert unwrap]]
           [examples [[[1 2 3 snapshot] [1 2 3 [3 2 1]]]
                      [[snapshot] [[]]]]]]]

[restore [[spec [[list] [*]]]
          [definition [evert drop]]
          [examples [[["x" "y" [1 2 3] restore] [3 2 1]]
                     [[[] restore] []]]]]]

1.2.1. Motion

These words change the order of items on the stack.

[swap [[spec [[[item a] [item b]]
              [[item b] [item a]]]]
       [examples [[[1 2 3 swap] [1 3 2]]]]]]

[swapdown [[spec [[[item a] [item b] [item c]]
                  [[item a] [item c] [item b]]]]
           [examples [[[1 2 3 swapdown] [2 1 3]]]]]]

[float [[spec [[[item a] [item b] [item c]]
               [[item c] [item a] [item b]]]]
        [examples [[[1 2 3 float] [2 3 1]]]]]]

[sink [[spec [[[item a] [item b] [item c]]
              [[item b] [item c] [item a]]]]
       [examples [[[1 2 3 sink] [3 1 2]]]]]]

[flip [[spec [[[item a] [item b] [item c]]
               [[item c] [item b] [item a]]]]
        [definition [float swapdown]]
        [examples [[[1 2 3 flip] [3 2 1]]]]]]

1.3. Program execution

[execute [[spec [[program] [*]]]
          [examples [[[[1 2 +] execute] [3]]
                     [[2 [+] 4 swap execute] [6]]]]]]

[branch [[spec [[[program no-branch]
                 [program yes-branch]
                 [item condition]]
                [*]]]
         [examples [[[5 yes [3 *] [4 +] branch] [15]]
                    [[6 [] [3 *] [4 +] branch] [10]]]]]]

[recur [[spec [[[program rec2]
                [program rec1]
                [program yes-branch]
                [program pred]]
               [*]]]
        [examples [[[3
                     [1 <=] [] [clone dec] [execute *]
                     recur]
                    [6]]]]]]

[loop [[spec [[program [item flag]] [*]]]
       [examples [[[10 yes [-2 * clone 50 <] loop] [160]]]]]]


[dip [[spec [[program [item a]] [[item a] *]]]
      [examples [[[1 8 [inc] dip] [2 8]]
                 [[1 2 [dec] unwrap
                   [+] dip] [3 [dec] unwrap]]]]]]

;; TODO: This depends on `if` so might need to move elsewhere, maybe Methods?
[decide [[spec [[[list test-expr-pairs]] [*]]]
         [doc "Takes a list of choices (pairs of test, program) and
                executes the first program whose test passes. if none
                pass, returns 'nothing'. Stack is reset between
                testing conditions."]
         [examples [[[5 [[[3 =] ["three"]]
                         [[5 =] ["five"]]
                         [[7 =] ["seven"]]
                         [[yes] ["something else"]]]
                      decide]
                     [5 "five"]]

                    [[9 [[[3 =] ["three"]]
                         [[5 =] ["five"]]
                         [[7 =] ["seven"]]
                         [[yes] ["something else"]]]
                      decide]

                     [9 "something else"]]
                    [[9 [[[3 =] ["three"]]
                         [[5 =] ["five"]]
                         [[7 =] ["seven"]]]
                      decide]
                     [9 []]]]]]]

[decorate [[spec [[list program] [program]]]
           [definition [[[wrap] dip put] step]]
           [examples [[[[1 inc] [foo bar] decorate] [[[[1 inc] foo] bar]]]]]]]

[decorated [[spec [[list program] [*]]]
            [definition [decorate execute]]
            [examples [[[1 2 [+] [bail shield] decorated] [1 2 3]]]]]]

;; TODO: implement as axiom (which would depend on 'restore' which should also be axiom?)
[shield [[spec [[program]
                [item]]]
         [doc "Runs program keeping top of stack produced but protects existing items from being consumed."]
         [definition [[snapshot] dip inject first]]
         [examples [[[1 2 3 [=] shield] [1 2 3 []]]]]]]

[shielddown [[spec [[program item]
                    [item]]]
             [definition [shield dropdown]]
             [examples [[[1 2 3 [=] shielddown] [1 2 []]]]]]]

[shielddeep [[spec [[[program p] [item consumed] [item consumed]]
                    [[item result]]]]
             [definition [shield [drop drop] dip]]
             [examples [[[1 2 3 [+ +] shielddeep] [1 6]]]]]]

[if [[spec [[[program no-branch]
             [program yes-branch]
             [program condition]]
            [*]]]
     [definition [[shield] dipdown branch]]
     [examples [[[5 [5 =] [3 *] [4 +] if] [15]]
                [[6 [5 =] [3 *] [4 +] if] [10]]]]]]

[when [[spec [[[program yes-branch]
               [program condition]]
              [*]]]
       [definition [[] if]]
       [examples [[[3 [odd?] [inc] when] [4]]
                  [[3 [even?] [inc] when] [3]]]]]]

;; TODO: drop dependency on 'decorated'
[dipdown [[spec [[program
                  [item a]
                  [item b]]
                 [[item a] [item b] *]]]
          [definition [[dip dip] decorated]]
          [examples [[[1 2 3 [inc] dipdown] [2 2 3]]]]]]

[dipdeep [[spec [[program
                  [item a]
                  [item b]
                  [item c]]
                 [[item a] [item b] [item c] *]]]
          [definition [[dipdown dip] decorated]]
          [examples [[[1 2 3 4 [inc] dipdeep] [2 2 3 4]]]]]]

[dive [[spec [[program [item a]] [item [item a] *]]]
       [definition [dip swap]]
       [examples [[[4 5 6 [+] dive] [6 9]]]]]]

[divedown [[spec [[program [item a] [item b]]
                  [item [item a] [item b] *]]]
           [definition [dipdown float]]
           [examples [[[5 6 7 8 [+] divedown] [7 8 11]]]]]]

[divedeep [[spec [[program [item a] [item b] [item c]]
                  [item [item a] [item b] [item c] *]]]
           [definition [wrap [divedown] join dip swap]]
           [examples [[[4 5 6 7 8 [+] divedeep] [6 7 8 9]]]]]]

[inject [[spec [[program list]
                [list]]]
         [doc "Inject the quoted program into the list below
                     it (runs the program with the list as its
                     stack).  Does not affect the rest of the stack."]
         [definition [swap evert take dip evert]]
         [examples [[[1 2 3 [4 5 6] [* +] inject] [1 2 3 [26]]]]]]]

[while [[spec [[[program body]
                [program pred]]
               [*]]]
        [definition [swap [shield] decorate ;; add shield to the pred program
                     clone dipdown ;; run it on the previous ToS
                     join loop]]
        [examples [[[3 [0 >] [clone dec] while] [3 2 1 0]]]]]]

[until [[spec [[[program body]
                [program pred]]
               [*]]]
        [definition [swap ;; pred body
                     [not] join ;; reverse logic
                     [shield] decorate ;; add shield to the pred program -> pred body
                     join ;; [body ..  pred]
                     yes swap ;; run at least once
                     loop]]
        [examples [[[2 [even?] [inc] until] [4]]]]]]

[prime [[spec [[[program body]
                [program pred]
                [program init]]
               [*]]]
        [definition [[clone [execute] dip] dipdown float join while]]
        [examples []]]]

[times [[spec [[[integer howmany]
                [program body]]
               [*]]]
        [definition [swap
                     [dec] swap put [dip] join ;; build [dec body dip]
                     [0 >] swap
                     while
                     drop]]
        [examples [[[[5] 3 times] [5 5 5]]
                   [[1 1 [inc swap] 3 times] [3 2]]]]]]

[primrec [[spec [[[program rec1]
                  [program exit]
                  [number data]]
                 [*]]]
          [definition [[execute] swap join ;; add execute to rec1 to be recurs rec2
                       [[drop] swap join] dip ;; add drop to exit condition
                       [[zero?]] dipdown  ;; put the condition on bottom
                       [[clone dec]] dip ;; add the r1
                       recur]] ;; now its generic recur
          [examples [[[5 [1] [*] primrec] [120]]]]]]

[bail [[spec [[program] [*]]]
       [definition [[swap] [execute] [drop] if]]
       [examples [[[[] [inc] bail] [[]]]
                  [[1 [inc] bail] [2]]]]]]

1.4. Collections

[join [[spec [[sized sized] [sized]]]
       [examples [[[["a" "b"] ["c" "d"] join] [["a" "b" "c" "d"]]]
                  [["ab" "cd" join] ["abcd"]]
                  [["ab" encode "cd" encode join "abcd" encode =] [yes]]
                  [[[[a b] [c d]] association [[e f] [a g]] join] [[[a g] [c d] [e f]] association]]
                  [[[[e f] [a g]] [[a b] [c d]] association  join] [[[a b] [e f] [c d]] association]]
                  [["" "" join] [""]]
                  [["" [1 2 3] join] [[1 2 3]]]]]]]

[put [[spec [[item receptacle] [receptacle]]]
      [examples [[[[] 1 put] [[1]]]
                 [[[1 2 3] 4 put] [[1 2 3 4]]]
                 [["foo" \d put] ["food"]]
                 [["foo" encode 32 put string] ["foo "]]]]]]

[count [[spec [[sized]
               [number]]]
        [examples [[[["a" "b" "cd"] count] [3]]
                   [["abcd" count] [4]]
                   [["abcd" encode count] [4]]
                   [[[[a b] [c d]] association count] [2]]]]]]

[first [[spec [[ordered] [item]]]
        [examples [[[[4 5 6] first] [4]]
                   [["foo" first] [\f]]
                   [[[] first] [[]]]]]]]

[second [[spec [[ordered] [item]]]
         [examples [[[[4 5 6] second] [5]]
                    [["foo" second [\o]]]
                    [[[] second] [[]]]]]]]

[last [[spec [[ordered] [item]]]
       [examples [[[[3 4 5 6] last] [6]]
                  [["foo" last [\o]]]
                  [[[] last] [[]]]]]]]

[step [[spec [[program dispenser] [*]]]
       [examples [[[1 [2 3 4] [*] step] [24]]
                  [[1 [] [*] step] [1]]]]]]

[take [[spec [[dispenser] [item dispenser]]]
       [examples [[[["a" "b" "c"] take] [["b" "c"] "a"]]
                  [[[1 2 3] take dropdown] [1]]]]]]

[pop [[spec [[ordered] [item ordered]]]
      [examples [[[["a" "b" "c"] pop] [["a" "b"] "c"]]
                 [[[1 2 3] pop dropdown] [3]]]]]]

[wrap [[spec [[item] [list]]]
       [examples [[[1 wrap] [[1]]]
                  [[[1 2] wrap] [[[1 2]]]]]]]]

[unwrap [[spec [[list] [*]]]
         [examples [[[[1] unwrap] [1]]
                    [[[1 2 3] unwrap] [1 2 3]]]]]]

[reverse [[spec [[ordered] [ordered]]]
          [examples [[[[1 2 3] reverse] [[3 2 1]]]
                     [["123" reverse] ["321"]]]]]]

[slice [[spec [[integer integer ordered] [ordered]]]
        [examples [[["foobar" 0 3 slice] ["foo"]]
                   [["foobar" 0 7 slice] [[]]]
                   [["foobar" encode 0 3 slice] ["foo" encode]]
                   [[[a b c d e] 0 3 slice] [[a b c]]]]]]]

[cut [[spec [[integer sized] [list]]]
      [definition [[[[[count] dive] shield slice]
                    [0 swap slice]]
                   [execute] map
                   [drop drop] dip unwrap]]
      [examples [[["abcdefghijklmnopqrstuvwxyz" 5 cut] ["fghijklmnopqrstuvwxyz" "abcde"]]]]]]

[empty [[spec [[sized] [sized]]]
        [examples [[["foo" empty] [""]]
                   [["foo" encode empty] ["" encode]]
                   [[[1 2 3] empty] [[]]]
                   [[[[a b] [c d]] association empty] [[] association]]
                   [[[1 2 3] set empty] [[] set]]]]]]

[range [[spec [[integer integer integer] [list]]]
        [examples [[[1 5 1 range] [[1 2 3 4]]]
                   [[3 13 3 range] [[3 6 9 12]]]]]]]

[empty? [[spec [[item] [boolean]]]
         [examples [[[[] empty?] [yes]]
                    [[1 empty?] [[]]]
                    [[[] empty?] [yes]]]]]]

[pad [[spec [[[item padding] [integer newsize] sized] [sized]]]
      [definition [[[[count] shield] dive -] dip
                   swap repeat
                   swap join]]
      [examples [[[[1 2 3] 5 0 pad] [[0 0 1 2 3]]]]]]]

[list? [[spec [[item] [boolean]]]
        [examples [[[[1] list?] [yes]]
                   [[[] list?] [yes]]
                   [[5 list?] [[]]]]]]]
[something? [[spec [[item] [boolean]]]
             [definition [empty? not]]
             [examples [[[1 something?] [yes]]
                        [[[] something?] [[]]]
                        [[[] something?] [[]]]]]]]

[rest [[spec [[sized] [sized]]]
       [definition [take drop]]
       [examples [[[[1 2 3] rest] [[2 3]]]]]]]

[butlast [[spec [[sized] [sized]]]
          [definition [pop drop]]
          [examples [[[[1 2 3] butlast] [[1 2]]]]]]]

[prepend [[spec [[item list]
                 [list]]]
          [definition [wrap swap join]]
          [examples [[[[1 2] 3 prepend] [[3 1 2]]]]]]]

[every? [[spec [[program sized] [boolean]]]
         [definition [[swap]
                      [[take] dip clone [float [shielddown] dive] dive
                       []
                       [drop every?]
                       [dropdown dropdown] if]
                      [drop drop yes] if]]
         [examples [[[[2 4 6] [even?] every?] [yes]]
                    [[[2 4 5] [even?] every?] [[]]]
                    [[[] [even?] every?] [yes]]
                    [[[2 4 6] [] every?] [yes]]
                    [[11 [2 4 6] [+ odd?] every?] [11 yes]]
                    [[12 [[even?] [positive?] [3 mod 0 =]] [execute] every?] [12 yes]]]]]]

[any? [[spec [[program sized] boolean]]
       [definition [[swap]
                    [[take] dip clone [float [shielddown] dive] dive
                     []
                     [dropdown dropdown]
                     [drop any?] if]
                    [drop drop []] if]]
       [examples [[[[2 4 6] [even?] any?] [yes]]
                  [[[3 5 7] [even?] any?] [[]]]
                  [[[] [even?] any?] [[]]]
                  [[[2 4 6] [] any?] [2]]
                  [[11 [3 5 6] [+ odd?] any?] [11 yes]]
                  [[-15 [[even?] [positive?] [3 mod 0 =]] [execute] any?] [-15 yes]]]]]]

[map [[spec [[program sized] [list]]]
      [definition [[] sink ;; put empty results below list
                   [shielddown dip] decorate ;; run map fn shielded and dipped under result
                   [swap] unwrap prepend ;; start by swapping the result back to the top
                   [swap put] join ;; end by adding this result to result list
                   step]]

      [examples [[[[1 2 3] [inc] map] [[2 3 4]]]

                 [[1 [1 2 3] [+] map] [1 [2 3 4]]]
                 [[7 9 [1 2 3] [+ *] map] [7 9 [70 77 84]]]
                 [[7 9 [1 2 3] [drop drop] map] [7 9 [7 7 7]]]

                 [[[1 2 3] [drop 1 inc] map] [[2 2 2]]]
                 [[7 9 [+] [] map] [7 9 [+]]]]]]]

[filter [[spec [[program sized] [list]]]
         [definition [[] sink ;; put empty results below list
                      [shield dip] decorate ;; run map fn shielded and dipped under result
                      [swap] unwrap prepend ;; start by swapping the result back to the top
                      [ swap [] [drop swap put] [drop dropdown] if] join ;; end by checking pred, add to result
                      step]]
         [examples [[[[1 2 3] [odd?] filter] [[1 3]]]
                    [[[2 4 6] [odd?] filter] [[]]]
                    [[33 [1 2 3] [33 + odd?] filter] [33 [2]]]]]]]

[sort [[spec [[program sized] [list]]]
       [definition [[clone] swap join
                    [pair] join
                    map sort-indexed]]
       [examples [[[[1 3 2] [] sort] [[1 2 3]]]
                  [[["Carol" "Alice" "bob"] [] sort] [["Alice" "Bob" "Carol"]]]
                  [[["Charlie" "Alice" "bob"] [count] sort] [["Bob" "Alice" "Charlie"]]]]]]]

[repeat [[spec [[[integer howmany]
                 item]
                [list]]]
         [definition [[] sink [wrap [put] join] dip times]]
         [examples [[["hi" 3 repeat] [["hi" "hi" "hi"]]]]]]]

[indexed [[spec [[list] [list]]]
          [definition [[count] shield [0] dip 1 range swap zip]]
          [examples [[[[a b c] indexed] [[[0 a] [1 b] [2 c]]]]]]]]

[interpose [[spec [[item ordered] [ordered]]]
            [definition [[] flip
                         [swap pair join [pop] shield] step
                         drop pop drop]]
            [examples [[[[foo bar baz] "hi" interpose] [[foo "hi" bar "hi" baz]]]
                       [[[] "hi" interpose] [[]]]
                       [[[foo] "hi" interpose] [[foo]]]]]]]

[starts? [[spec [[ordered ordered] [boolean]]]
          [definition [zip [unwrap =] every?]]
          [examples [[["abcd" "ab" starts?] [yes]]
                     [["abcd" "" starts?] [yes]]
                     [["abcd" "bb" starts?] [[]]]
                     [[[1 2 3 4] [1 2] starts?] [yes]]]]]]

[ends? [[spec [[ordered ordered] [boolean]]]
        [definition [[reverse] both starts?]]
        [examples [[["abcd" "cd" ends?] [yes]]
                   [["abcd" "" ends?] [yes]]
                   [["abcd" "bb" ends?] [[]]]
                   [[[1 2 3 4] [3 4] ends?] [yes]]]]]]

[pair [[spec [[item item] [list]]]
       [definition [[wrap] dip put]]
       [examples [[[1 2 pair] [[1 2]]]
                  [[["hi"] ["there" "foo"] pair] [[["hi"] ["there" "foo"]]]]]]]]

[pair? [[spec [[item] [boolean]]]
        [definition [[count 2 =] [drop drop []] recover]]
        [examples [[["ab" pair?] [yes]]
                   [[[a b] pair?] [yes]]
                   [["abc" pair?] [[]]]
                   [[[] pair?] [[]]]]]]]

[triplet [[spec [[item item] [list]]]
          [definition [[pair] dip put]]
          [examples [[[1 2 3 triplet] [[1 2 3]]]
                     [[["hi"] ["there" "foo"] ["bar"] triplet] [[["hi"] ["there" "foo"] ["bar"]]]]]]]]

[both? [[spec [[program item item] [boolean]]]
        [definition [sink pair swap every?]]
        [examples [[[1 2 [odd?] both?] [[]]]
                   [[1 3 [odd?] both?] [yes]]]]]]

[both [[spec [[program [item a] [item b]] [item item]]]
       [definition [[pair] dip step]]]]


[sort-indexed [[spec [[sized] [sized]]]]]

1.4.1. Associations

[get [[spec [[item sized] [item]]]
      [examples [[[[[a 3] [c 2]] [a] unwrap get] [3]]
                 [[[10 11 12 13] 1 get] [11]]
                 [["foobar" 3 get] [\b]]
                 [["foobar" encode 3 get] [98]]]]]]

[assign [[spec [[[item value]
                 [list keys]
                 sized]
                [association]]]
         [examples [[[[[a b] [c d]] [a] 5 assign]
                     [[[a 5] [c d]] association]]

                    [[[[a b] [c d]] [e] 5 assign]
                     [[[a b] [c d] [e 5]] association]]

                    [[[[a b] [c [[d e]]]] [c d] 5 assign]
                     [[[a b] [c []]] [c] [[d 5]] association assign]]

                    [[[[a b] [c [[d e]]]] [1 1 0] 5 assign]
                     [[[a b] [c [5]]]]]

                    [[[1 2 3] [1 0 0] "foo" assign]
                     [[1 [["foo"]] 3]]]

                    [[[[a [1 2 3]]] [a 0] 10 assign]
                     [[[a [10 2 3]]] association]]

                    [[[1 2 3] [1 2] "foo" assign]
                     [[1 [[] [] "foo"] 3]]]]]]]

[unassign [[spec [[[item key] [sized into-association]] [association]]]
           [examples [[[[[a b] [c d]] [a] unassign]
                       [[[c d]] association]]

                      [[[[a b] [c d]] [e] unassign]
                       [[[a b] [c d]] association]]

                      [[[[a [[b c] [d e]]]] [a d] unassign]
                       [[] association [a b] [c] unwrap assign]]

                      [[[0 1 2 [[a b] [c d]]] [3 c] unassign]
                       [[0 1 2] [[a b]] association put]]]]]]

[association? [[spec [[item] [boolean]]]
               [examples [[[[[a b] [c d]] association association?] [yes]]
                          [[[[a b] [c d]] association?] [[]]]
                          [[1 association?] [[]]]
                          [[[] association?] [[]]]
                          [[[] association association?] [yes]]
                          [[[] [a] 1 assign association?] [yes]]
                          [[[] [a] 1 assign association?] [yes]]]]]]

[association [[spec [[item] [association]]]
              [examples [[[[[a b] [c d]] association
                           [[c d] [a b]] association =]
                          [yes]]

                         [[[[a b] [c d]]
                           [[c d] [a b]] association =]
                          [[]]]

                         [[[[a b] [c d]]
                           [[a b] [c d]] association =]

                          [[]]]]]]]
;; Associative words
[update [[spec [[program [list keys] [sized into-association]]
                [association]]]
         [definition [[[lookup] shield] dip ;; m ks v p
                      shielddown
                      assign]]
         [examples [[[[[a 1] [b 2]] [b] [inc] update]
                     [[[a 1] [b 3]] association]]

                    [[[[a [[c 3] [d 5]]] [b 2]]
                      [a c] [inc] update
                      [a c] lookup]
                     [4]]

                    [[[[a [1 3 5 7]] [b 2]]
                      [a 2] [inc] update]
                     [[[a [1 3 6 7]] [b 2]] association]]

                    [[[[a [[c 3] [d 5]]] [b 2]]
                      [a c] [drop 10 15] update
                      [a c] lookup]
                     [15]]

                    [[[[a 1] [b 2]] [d] [5] update]
                     [[[a 1] [b 2] [d 5]] association]]

                    [[[[a [[c 3] [d 5]]] [b 2]]
                      [a e] [5 6 +] update
                      [a e] lookup]
                     [11]]]]]]

[lookup [[spec [[[list keys] sized] [item]]]
         [definition [[something?] ;; keylist not empty
                      [take swap [get] dip] ;; extract the first key and lookup
                      while
                      drop]]
         [examples [[[[[a b] [c d]] [a] lookup] [[b] unwrap]]
                    [[[[a b] [c d]] [e] lookup] [[]]]
                    [[[[outer [[a b] [c d]]]] [outer c] lookup] [[d] unwrap]]]]]]

;; TODO: fix the case where you just want a value [[type foo]] - only
;; one item but you want the value, not key
[type [[spec [[item] [item]]]
       [definition [[[[empty?] [[nothing] unwrap]]
                     [[word?] [[word] unwrap]]
                     [[number?] [[number] unwrap]]
                     [[string?] [[string] unwrap]]
                     [[bytes?] [[bytes] unwrap]]
                     [[pipe?] [[pipe] unwrap]]
                     [[error?] [[error] unwrap]]
                     [[association?] [[[[type] lookup]
                                       [[count 1 =]
                                        [[first [type] unwrap =]
                                         [first second]
                                         [first first]
                                         if]
                                        [[]]
                                        if]
                                       [[association] unwrap]]
                                      [execute] any?]]
                     [[list?] [[list] unwrap]]]
                    decide dropdown]]
       [examples [[[[[foo 1]] association type] [[foo] unwrap]]
                  [[1 type] [[number] unwrap]]
                  [[1.0 type] [[number] unwrap]]
                  [[[] type] [[nothing] unwrap]]
                  [["foo" encode type] [[bytes] unwrap]]
                  [["foo" type] [[string] unwrap]]
                  [[[[type foo]] association type] [[foo] unwrap]]
                  [[[[type foo] [attr "blah"]] association type] [[foo] unwrap]]
                  [[[[attr1 foo] [attr2 "blah"]] association type] [[association] unwrap]]
                  [[[[type url] [value "http://foo.com"]] association type] [[url] unwrap]]]]]]

[value [[spec [[[sized into-association]] [item]]]
        [definition [[count 1 =] ;; if it's a single item
                     [first second] ;; the value is the value of that first item
                     [[value] lookup] ;; otherwise look up the key 'value'
                     if]]
        [examples [[[[[foo 1]] value] [1]]

                   [[[[type url] [value "http://foo.com"]] value]
                    ["http://foo.com"]]]]]]
[zip [[spec [[[dispenser values] [dispenser keys]] [list]]]
      [definition [[[]] dipdown ;; add empty result below ToS
                   [[take wrap] ;; take the next key, wrap it
                    ;; to make a "pair" (adding
                    ;; value later)
                    dip ;; run that underneath the current value
                    put ;; the value into the "pair" we created earlier
                    swap [put] dip] ;; add the new pair to the results
                   step ;; through all the values
                   drop]] ;; the now-empty list of keys
      [examples [[[[a b c] [1 2 3] zip] [[[a 1] [b 2] [c 3]]]]]]]]

[label [[spec [[[sized labels]] [association]]]
        [definition [[] swap ;; labels acc
                     [wrap float assign] step]]
        [examples [[["Alice" 23 "123 Main St" [address age name] label]
                    [[[address "123 Main St"]
                      [age 23]
                      [name "Alice"]] association]]]]]]

[definition [[spec [[list] [program]]]
             [definition [[definition] join dictionary swap lookup]]
             [examples [[[1 2 3 [flip] definition execute] [3 2 1]]]]]]

1.4.2. Sets

;; TODO add 'set' type for spec?
[[set [[spec [[item] [item]]]
       [examples [[[[1 2 3 1 2 3] set] [[1 2 3] set]]]]]]

 [set? [[spec [[item] [boolean]]]
        [examples [[[[1 2 3] set set?] [yes]]
                   [[[1 2 3] set?] [[]]]]]]]

 [contains? [[spec [[item [item container]] [boolean]]]
             [examples [[[[1 2 3] 3 contains?] [yes]]
                        [[[1 2 3 3 5] set 3 contains?] [yes]]
                        [[[1 2 3] 4 contains?] [[]]]]]]]

 [intersection [[spec [[sized sized] [sized]]]
                [examples [[[[1 2 3] [2 3 4] intersection] [[2 3] set]]]]]]]
join

1.4.3. Generators

;; infinite sequence (generators) functions

[[generate [[spec [[program item] [program item]]]
            [definition [clone [execute] dive]]
            [examples [[[1 [inc clone] generate] [2 [inc clone] 2]]]]]]

 [liberate [[spec [[] [program]]]
            [definition [[take]]]]]

 [assemble [[spec [[[program generators] dispenser] [sized]]]
            [definition [[[take] pair] dip join [collect] join shield]]
            [examples [[[[1 2 3 4 5] [[odd?] keep] assemble] [[1 3 5]]]]]]]

 [into [[spec [[sized program] [list]]]
        [definition [[generate] dip ;; n
                     swap clone ;; n n r
                     [put ;; r
                      [generate] dip ;; r n
                      swap clone]  ;; n n r
                     loop drop]]
        [examples [[[[[\a \b \c \d] [take] "" into] shield]
                    ["abcd"]]
                   [[[0 10 1 range [take]
                      5 dropper
                      [10 *] each
                      [] into]
                     shield]
                    [[50 60 70 80 90]]]]]]]

 [collect [[spec [[program] [list]]]
           [definition [[] into]]
           [examples [[[[[1 2 3 4] [take] collect] shield]
                       [[1 2 3 4]]]
                      [[[0 10 1 range [take]
                         5 dropper
                         [10 *] each
                         collect]
                        shield]
                       [[50 60 70 80 90]]]]]]]

 [each [[spec [[program] [program]]]
        [definition [[generate] swap
                     [bail shielddown] decorate
                     join]]
        [examples [[[[1 2 3 4]
                     [[clone *] each]
                     assemble]

                    [[1 4 9 16]]]]]]]

 [joiner [[spec [[] [program]]]
          [definition [[generate [] swap
                        []
                        [join
                         [generate] dive]
                        while drop]]]
          [examples [[[[[1 2 3] [4 5 6] [7 8 9]]
                       [joiner]
                       assemble]

                      [[[1 2 3 4 5 6 7 8 9]]]]]]]]

 [taker [[spec [[] [program]]]
         [definition [[[positive?] [dec [generate] dive] [[]] if]]]
         [examples [[[[1 2 3 4 5]
                      [3 taker]
                      assemble]

                     [[1 2 3]]]]]]]

 [catcher [[spec [[] [program]]]
           [definition [[[generate] dive
                         [[[clone] dive execute] bail not]
                         [drop []]
                         when]]]
           [examples [[[[1 2 3 -4 5]
                        [[positive?] catcher]
                        assemble]

                       [[1 2 3]]]]]]]

 [dropper [[spec [[] [program]]]
           [definition [[[[positive?]
                          [[generate drop] dip dec]
                          while
                          [generate swap] dip float]
                         bail]]]
           [examples [[[[1 2 3 4 5]
                        [3 dropper]
                        assemble]

                       [[4 5]]]]]]]

 [skipper [[spec [[] [program]]]
           [definition [[] ;; the state (whether threshold reached)
                        [[] ;; condition - whether we've finished dropping or not
                         [[generate] divedown] ;; true - pass everything else through
                         ;; false - generate, check pred, repeat
                         [[[generate] divedown] ;; prime init
                          [[[clone] divedown execute] bail] ;; bring pred up and exec it
                          [drop] ;; if pred passes drop the value
                          prime ;; after this should have value on top
                          [drop true] dip]
                         if]]]
           [examples [[[[1 2 -3 4 5]
                        [[positive?] skipper]
                        assemble]

                       [[-3 4 5]]]]]]]

 [keep [[spec [[program] [program]]]
        [definition [[not] join
                     [something?] swap pair wrap [[execute] every?] join ;; pred that also checks for nothing first
                     [clone
                      [[generate] dip ;; pred 1
                       [drop generate]
                       while]
                      dive]]]
        [examples [[[[1 2 3 4 5]
                     [[odd?] keep]
                     assemble]

                    [[1 3 5]]]]]]]

 [group [[spec [[[program group-by]] [association]]]
         [definition [wrap
                      [shield ;; k v state
                       wrap swap  ;;  v k state
                       wrap [put] join update] join
                      [] association ;; state f
                      swap cram]]
         [examples [[[[[1 2 3 4] liberate [odd?] group] shield]
                     [[[yes [1 3]] [[] [2 4]]] association]]]]]]

 [split [[spec [[sized] [program sized sized]]]
         [definition [[empty] [divedown shield] decorated
                      [[[generate] divedown [clone [put] dip] bail]
                       [[[] [drop swap ends? not]] [execute] every?]
                       [drop] prime
                       drop
                       [swap ends?]
                       [[[count] shield] dive
                        [[count] shield] dive swap - [0] dip slice]
                       when
                       [empty] shield swap]]]
         [examples [[["abcabc" ["b" split] assemble]
                     [["a" "ca" "c"]]]
                    [[[1 2 3 4 2 5] [[2] split] assemble]
                     [[[1] [3 4] [5]]]]]]]]


 [partition [[spec [[] [program]]]
             [definition [[]
                          [[take-chunk [[taker collect
                                         dropdown dropdown] ; drop the used-up taker generator
                                        join divedeep]]
                           [shift [[[count <=]
                                    [swap 0 slice]
                                    [[]] if] shield swap]]]
                          [[]
                           [over wrap take-chunk [join shift] bail]
                           [[over] dive wrap take-chunk swap drop shift]
                           if]
                          let]]
             [examples [[[[1 2 3 4 5 6 7] [2 2 partition] assemble]
                         [[[1 2] [3 4] [5 6] [7]]]]]]]]

 [combinations [[spec [[] [program]]]
                [definition [[count] shield -1 ;; l idx i
                             [[[swap count =] dive] [drop drop take 0 swap] when
                              [[wrap lookup] dive [pair] bail] shield [inc] dipdown]]]
                [examples [[[[1 2 3] [combinations] assemble] [[[1 2] [1 3] [2 3]]]]]]]]

 [frequencies [[spec [[] [association]]]
               [definition [[] association
                            [wrap [[] [inc] [1] if] update]
                            cram]]
               [examples [[[["Hello there!" [take] frequencies] shield]
                           [[[\space 1]
                             [\! 1]
                             [\H 1]
                             [\e 3]
                             [\h 1]
                             [\l 2]
                             [\o 1]
                             [\r 1]
                             [\t 1]] association]]]]]]

 [fold [[spec [[[program reducing-function] [program generator]] [item]]]
        [definition [[clone] join ;; -> [+ clone] to build the 'then' branch
                     ;; build the loop body
                     [[generate] dive []] swap put [when] join
                     ;; generate the first item under the loop body
                     [generate clone] dip
                     loop]]
        [examples [[[[integers 1 dropper 10 taker [+] fold] shield] [55]]]]]]

 [cram [[spec [[[program reducing-function]
                [item initial-value]
                [program generator]] [item]]]
        [definition [[[generate] dive]
                     []
                     float prime drop]]
        [examples [[[[integers 1 dropper 10 taker 0 [+] cram] shield] [55]]]]]]

 [pairwise [[spec [[program] [*]]]
            [definition [[[] evert ;; capture stack
                          [2 2 partition] assemble] dip ;; pair up stack items
                         inject ;; run the program on the pairs
                         [joiner] assemble ;; unpair the items
                         unwrap [] swap evert drop]] ;; restore as the stack
            [examples [[[1 2 3 4 5 [swap] pairwise] [1 4 5 2 3]]
                       [[1 2 3 4 5 [float] pairwise] [2 3 4 5 1]]
                       [[1 2 3 4 5 [[[+] inject] both] pairwise] [1 5 9]]]]]]

 [integers [[spec [[] [program]]]
            [definition [-1 [inc clone]]]]]]
join

1.5. Dictionary modules

[dictionary [[spec [[] [list]]]]]

[cache [[spec [[item bytes] [bytes]]]]]

[decache [[spec [[item] [bytes]]]]]

[hashbytes [[spec [[bytes] [bytes]]]
            [examples [[[["foo" encode hashbytes] 2 times =] [yes]]
                       [["foo" encode hashbytes
                         "fop" encode hashbytes
                         =]
                        [[]]]]]]]

[dictmerge [[spec [[[dictionary module] [dictionary original] [bytes hash]] [dictionary]]]]]
[updates [[spec [[[sized word-updates]] [[program single-update]]]]
          [definition [[[take]
                        [[0] [wrap] update ;; wrap the word name to get a path to update
                         [update] join] each
                        joiner generate] shielddown]]]]

[entry [[spec [[[program definition]] [[association full-entry]]]]
        [definition [[definition] label]]]]

; [draft [[spec [[[sized bindings]] [[program dictionary-updater]]]]
;         [definition [[entry] map updates]]
;         [examples [[[[[swap [5]]]
;                      ["a" "b" "c" swap]
;                      draft]
;                     ["a" "b" "c" 5]]

;                    [[[[swap [5]]]
;                      [["hi"] 3 times swap]
;                      draft]
;                     ["hi" "hi" "hi" 5]]

;                    [[[[swap [5 swap]]]
;                      [["hi"] 3 times swap]
;                      draft ]
;                     ["hi" "hi" 5 "hi"]]

;                    [[[[foo ["foo"]]]
;                      [foo
;                       [[foo ["bar" put]]]
;                       [foo]
;                       revise]
;                      draft]
;                     ["foo" "bar"]]]]]]  

; [using [[spec [[program [list namespaces]] [*]]]
;         [definition [resolve execute]]]]

[module [[spec [[[item wrapped-module-alias-or-hash]] [program]]]
         [doc "reads a cached stdlib module from disk and puts it on the stack as a program"]
         [definition [decache string read first]]
         [examples [[["123" encode [crypto] stdmod [hash] confine]
                     [#b64 "pmWkWSBCL51Bfkhn79xPuKBKHz//H6B+mY6G9/eieuM="]]]]]]

[inscribe [[spec [[[program module]] [dictionary]]]
           [definition [dictionary swap shield dictmerge]]]]

[draft [[spec [[[sized definitions]] [[program dictionary-updater]]]]
        [definition [[[1] [entry] update] map ;; create full entries for each definition
                     wrap [join] join]]]]  ;; add 'join' to join the entries with the existing dictionary

[let [[spec [[[program p]
              [program dictionary-modifier]] [*]]]
      [definition [[draft dictionary swap [emit encode hashbytes] shield
                    [shield] dip
                    sink [dictmerge] shielddeep] dip ;; under the let program ;; prog dict hash
                   [wrap] dipdown ;; wrap the hash to make a list of 1 namespace

                   [program dictionary resolver] label environment ;; creates closure
                   ;; when the closure executes, capture the outer stack first
                   wrap
                   [[stack] [snapshot] divedown assign evaluate [stack] lookup restore] join] ] 
      [examples [[[[[times5 [5 *]]
                    [doubledec [dec dec]]]
                   [3 times5 doubledec] let execute] [13]]
                 [[[[swap [5]]]
                   ["a" "b" "c" swap]
                   let execute]
                  ["a" "b" "c" 5]]]]]]

1.6. Math

[+ [[spec [[number number] [number]]]
    [examples [[[1 2 +] [3]]
               [[1.1 2.2 + 3.3 0.001 within?] [yes]]
               [[1 2.2 +] [3.2]]]]]]

[- [[spec [[number number] [number]]]
    [examples [[[2 1 -] [1]]
               [[1.1 2.2 - -1.1 0.00001 within?] [yes]]
               [[2.2 1 - 1.2 0.00001 within?] [yes]]]]]]

[* [[spec [[number number] [number]]]
    [examples [[[4 3 *] [12]]
               [[10 1.5 * 15 0.0001 within?] [yes]]
               [[5 0 *] [0]]
               [[5 -1 *] [-5]]]]]]

[/ [[spec [[number number] [number]]]
    [examples [[[12 3 /] [4]]
               [[15 1.5 /] [10.0]]
               [[0 1 /] [0]]
               [[1 0 / handle [reason] lookup] [1 0 "division by zero"]]]]]]

[quot [[spec [[number number] [number]]]
       [examples [[[16 5 quot] [3]]]]]]

[rem [[spec [[number number] [number]]]
      [examples [[[17 5 rem] [2]]]]]]

[mod [[spec [[number number] [number]]]
      [examples [[[17 5 mod] [2]]]]]]

[exp [[spec [[number number] [number]]]
      [examples [[[2 5 exp] [32]]]]]]

[log [[spec [[number number] [number]]]
      [examples [[[32 2 log] [5]]]]]]

[floor [[spec [[number] [number]]]
        [examples [[[2.1 floor] [2]]]]]]

[ceiling [[spec [[number] [number]]]
          [examples [[[2.1 ceiling] [3]]]]]]

[round [[spec [[number] [number]]]
        [examples [[[2.1 round] [2]]]]]]

[sqrt [[spec [[number] [number]]]
       [examples [[[9 sqrt] [3]]
                  [[81 sqrt] [9]]]]]]

[inc [[spec [[number] [number]]]
      [examples [[[1 inc] [2]]
                 [[-1 inc] [0]]
                 [[99 inc] [100]]]]]]

[dec [[spec [[number] [number]]]
      [examples [[[2 dec] [1]]
                 [[0 dec] [-1]]
                 [[100 dec] [99]]]]]]

[abs [[spec [[number] [integer]]]
      [examples [[[2.1 abs] [2.1]]
                 [[-0.2 abs] [0.2]]
                 [[-2 abs] [2]]
                 [[0 abs] [0]]]]]]

[odd? [[spec [[number] [boolean]]]
       [examples [[[1 odd?] [yes]]
                  [[-1 odd?] [yes]]
                  [[4 odd?] [[]]]]]]]

[even? [[spec [[number] [boolean]]]
        [examples [[[2 even?] [yes]]
                   [[-2 even?] [yes]]
                   [[3 even?] [[]]]]]]]

[zero? [[spec [[number] [boolean]]]
        [examples [[[0 zero?] [yes]]
                   [[0.0 zero?] [yes]]
                   [[-0.00001 zero?] [[]]]
                   [[1.1 zero?] [[]]]]]]]

[number? [[spec [[item] [boolean]]]
          [examples [[[[1] number?] [[]]]
                     [[[] number?] [[]]]
                     [[5 number?] [yes]]
                     [[5.01 number?] [yes]]]]]]
[positive? [[spec [[number] [boolean]]]
            [definition [0 >]]]]

[negative? [[spec [[number] [boolean]]]
            [definition [0 <]]]]

[within? [[spec [[number number] [boolean]]]
          [definition [[- abs] dip <]]
          [examples [[[1.0 2.0 + 3 0.001 within?] [yes]]]]]]


1.7. Serialization

[read [[spec [[string] [item]]]
       [examples [[["[1 [2] 3]" read] [[1 [2] 3]]]]]]]

[emit [[spec [[item] [string]]]
       [examples [[[[1 [2] 3] emit] ["1 [2] 3"]]]]]]

[autoformat [[spec [[string] [string]]]
             [examples [[["[[foo bar] [baz [[quux floop] [toop zoop]]]]" autoformat]
                         ["[[foo bar]\n [baz [[quux floop]\n       [toop zoop]]]]"]]]]]]

1.8. Boolean logic

[yes [[spec [[] [word]]]]] ;; self-inserts

[and [[spec [[item item] [item]]]
      [examples [[[1 odd? 2 even? and] [yes]]
                 [[2 3 and] [3]]
                 [[[] 3 and] [[]]]
                 [["" 3 and] [[]]]]]]]

[or [[spec [[item item] [item]]]
     [examples [[[1 odd? 3 even? or] [yes]]
                [[1 2 or] [1]]
                [[[] 2 or] [2]]
                [[[] [] or] [[]]]]]]]

[not [[spec [[item] [boolean]]]
      [examples [[[1 even? not] [yes]]
                 [[[] not] [yes]]
                 [[yes not] [[]]]
                 [[[] not] [yes]]]]]]

1.9. Byte encoding and decoding

[encodestring [[spec [[string] [bytes]]]
               [examples [[["foo" encodestring] [#b64 "Zm9v"]]
                          [["" encodestring] [#b64 ""]]]]]]

[encodenumber [[spec [[number] [bytes]]]
               [examples [[[12 encodenumber] [#b64 "AAAAAAAAAAw="]]
                          [[12.3 encodenumber] [#b64 "QCiZmZmZmZo="]]]]]]

[decodejson [[spec [[string] [item]]]
             [examples [[["12" decodejson] [12]]
                        [["12.01" decodejson] [12.01]]
                        [["\"foo\"" decodejson] ["foo"]]
                        [["{\"foo\": 12, \"bar\": \"baz\"}" decodejson] [[["foo" 12] ["bar" "baz"]] association]]
                        [["[1,\"foo\"]" decodejson] [[1 "foo"]]]]]]]

[encodejson [[spec [[item] [string]]]
             [examples [[[12 encodejson] ["12"]]
                        [[12.01 encodejson] ["12.01"]]
                        [["foo" encodejson] ["\"foo\""]]
                        [[[["foo" 12] ["bar" "baz"]] association encodejson decodejson] [[["foo" 12] ["bar" "baz"]] association]]
                        [[[1 "foo"] encodejson] ["[1,\"foo\"]"]]]]]]

[bytes? [[spec [[item] [boolean]]]
         [examples [[["foo" bytes?] [[]]]
                    [[#b64 "Zm9v" bytes?] [yes]]
                    [[[#b64 "Zm9v"] bytes?] [[]]]
                    [["foo" encode bytes?] [yes]]]]]]

[xor [[spec [[item] [item]]]
      [examples [[[10 12 xor] [6]] ;; 10 = 01010, 12 = 01100, 00110, 6
                 [["foo" encode "bar" encode xor] [#b64 "BA4d"]]]]]]

[bits [[spec [[item] [sized]]]
       [definition [encode [[2 radix 8 0 pad] each joiner] assemble unwrap]]
       [examples [[["foo" bits] [[0 1 1 0 0 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0 1 1 1 1]]]]]]]
[[encode [[spec [[item] [bytes]]]
          [definition [[[[bytes?] []]
                        [[string?] [encodestring]]
                        [[number?] [encodenumber]]
                        [[true] [emit encode]]]
                       decide]]
          [examples [[[12 encode] [#b64 "AAAAAAAAAAw="]]
                     [["foo" encode] [#b64 "Zm9v"]]
                     [["foo" encode encode] [#b64 "Zm9v"]]
                     [["" encode] [#b64 ""]]]]]]

 [radix [[spec [[integer integer] [list]]]
         [definition [[[/] shield swap
                       [*] shielddown
                       swapdown -
                       swap [prepend] dip]
                      swap prepend
                      [[] swap [positive?]] dip
                      while drop]]
         [examples [[[7 2 radix] [[1 1 1]]]
                    [[9 3 radix] [[1 0 0]]]
                    [[255 16 radix] [[15 15]]]]]]]]
join

1.10. Strings

[string [[spec [[item] [string]]]
         [examples [[[1 string] ["1"]]
                    [[[1 2 3] string] ["[1 2 3]"]]
                    [[[] string] [""]]]]]]

[format [[spec [[list string] [string]]]
         [examples [[["foo {} bar {} baz" ["abc" "def"] format] ["foo abc bar def baz"]]]]]]

[string? [[spec [[item] [boolean]]]
          [examples [[["hi" string?] [yes]]
                     [["" string?] [yes]]
                     [[["hi"] string?] [[]]]
                     [[yes string?] [[]]]]]]]

;; Don't really belong here but good enough for now
[word? [[spec [[item] [boolean]]]
        [examples [[[[foo] unwrap word?] [yes]]
                   [[yes word?] [yes]]
                   [[1 word?] [[]]]
                   [["yes" word?] [[]]]]]]]

[inspect [[spec [[item] [string]]]]]

1.11. Error handling

[error? [[spec [[item] [boolean]]]]]

;; handle is a special word only used to unwind the program on
;; error, if there's no error and we end up reaching this word, we
;; ignore it.
[handle [[spec [[] []]]
         [definition []]]]

[fail [[spec [[sized] [*]]]]]
[[assert [[spec [[program]
                 [*]]]
          [definition [snapshot ;; save stack to print in err message
                       [shield] dive ;; run the assertion under the saved stack
                       [drop] ;; if passes, drop the saved stack, dont need
                       [string ["assertion failed "] dip join fail] ;; else throw err
                       branch]]]]

 [recover [[spec [[program program] [*]]]
           [definition [[[handle] join] dip ;; add handle to the end of test
                        [snapshot] dipdown ;; rec test ss
                        sink inject ;; res rec
                        [first error?] ;; err? res rec
                        [first swap execute];; drop the snapshot and run recovery
                        [evert drop] ;; use snapshot as stack
                        if]]
           [examples [[[[+]
                        [drop 1
                         [+] [drop 2 +]
                         recover]
                        recover]
                       [3]]

                      [[[1 2 "oh fudge"]
                        [[5 +]
                         [drop 5]
                         recover]
                        map]
                       [[6 7 5]]]

                      [[[swap] [drop swap] recover]
                       [swap]]]]]]

 [retry [[spec [[error] [*]]]
         [definition [[unwound] lookup
                      execute]]
         [examples [[[2 3 "four" * + handle [drop 4] dip retry] [14]]]]]]]
join

1.12. Methods

We want a way of adding methods to a word that's already set up as a simple 'decide' form. This will add the method at the beginning - adding it at the end is not good because often there's a catchall condition at the end, and adding beyond that means the new condition is unreachable. Adding at the beginning is not always what the user wants either, though. So maybe this could be improved by taking another argument: a program to combine the item and the existing list (that defaults to prepend here).

[[addmethod [[spec [[[program method] [program condition] [program definition]]
                    [[program newdefinition]]]]
             [definition [pair ;; [c b] [[[...]] decide]
                          wrap [prepend] join [[0]] dip update]]
             [examples [[[[[[[count 3 >] ["foo" put]]
                            [[not] ["bar" put]]] decide]
                          [count 1 =] [rest] addmethod]

                         [[[[[count 1 =] [rest]]
                            [[count 3 >] ["foo" put]]
                            [[not] ["bar" put]]]
                           decide]]]]]]]

 [method? [[spec [[program] [boolean]]]
           [definition [[[first [[pair?]
                                 [[list?] every?]] every?]
                         [second [decide] unwrap =]]
                        every?]]]]]
join

1.13. Pipes

[pipe? [[spec [[item] [boolean]]]
        [examples [[[timestamps pipe?] [yes]]
                   [[standard pipe?] [yes]]
                   [[[1 2 3] pipe?] [[]]]
                   [[5 pipe?] [[]]]]]]]

[animate [[spec [[environment] []]]]]

[attend [[spec [[list] [list]]]]]

[file-in [[spec [[string] [pipe]]]]]

[file-out [[spec [[string] [pipe]]]]]

[handoff [[spec [[] [pipe]]]]]

[receiver [[spec [[pipe] [pipe]]]]]

[select [[spec [[[list pipes]] [item pipe [list pipes]]]]]]

[sender [[spec [[pipe] [pipe]]]]]

[serversocket [[spec [[integer string] [pipe]]]]]

[socket [[spec [[integer string] [pipe]]]]]

[standard [[spec [[] [pipe]]]]]

[timer [[spec [[integer] [pipe]]]]]

[timestamps [[spec [[] [pipe]]]]]

[database [[spec [[[sized params] string] []]]]]

[persist [[spec [[sized] []]]]]
[[pipe-in [[spec [[item] [pipe]]]
           [definition [association
                        [[[type [file] unwrap =]
                          [value file-in]]
                         [[type [stdout] unwrap =]
                          [stdout]]]
                        decide]]]]

 [tunnel [[spec [[item] [pipe]]]
          [definition [association
                       [[[type [ip-host] unwrap =]
                         [clone
                          [port] lookup
                          [[address] lookup] dip
                          serversocket]]
                        [[type [ip-client] unwrap =]
                         [clone
                          [port] lookup
                          [[address] lookup] dip
                          socket]]]
                       decide]]]]

 [pipe-out [[spec [[item] [pipe]]]
            [definition [association
                         [[[type [file] unwrap =]
                           [value file-out]]
                          [[type [ip-host] unwrap =]
                           [clone
                            [port] lookup
                            [[address] lookup] dip
                            serversocket]]]
                         decide]]]]

 [spit [[spec [[item [item target]] []]]
        [definition [[pipe-in] dip encode put drop]]]]

 [slurp [[spec [[pipe] [item]]]
         [definition [[take] [join] fold string [drop drop] dip]]]]

 [print [[spec [[string] []]]
         [definition [[standard] dip "\n" join encode put drop]]]]

 ;;[slurp [[spec [[[item target]] [item pipe]]]]]

 [sleep [[spec [[integer] []]]
         [definition [timer take drop drop]]]]

 [future [[spec [[program] [pipe]]]
          [definition [handoff swap
                       [snapshot] join ;; return entire stack
                       wrap [dive put drop] join
                       dictionary swap spawn animate]]
          [examples [[[1 [2 +] future take dropdown] [1 [3]]]]]]]

 [generator [[spec [[[program generator-maker]] [[program wrapped-generator]]]]
             [definition [[] swap inject
                          [[generate] inject take]]]]]  ;; generate from the wrapped generator

 [siphon [[spec [[[receptacle output] [program generator]] [[receptacle output]]]]
          [description "Generates values from a wrapped generator (stacked generator inside a list), until exhausted, puts all items into the output receptacle"]
          [definition [[] ;; placeholder that gets dropped (next
                       ;; iteration it will hold a copy of the last
                       ;; element which is only needed to check if
                       ;; the loop continues and can be dropped
                       ;; after)
                       [empty?] ;; stop when generator returns
                       ;; nothing
                       [drop ;; the last value
                        [generate clone] dip
                        sink
                        [[put] bail] dip]
                       until
                       drop drop sink drop drop]] ;; the now-empty dispenser
          [examples [[[[[integers 5 taker] generator [] siphon] shield] [[0 1 2 3 4]]]]]]]

 [close [[spec [[pipe] []]]
         [definition [drop]]]]]
join

1.14. Crypto

[random [[spec [[integer] [bytes]]]]]

[key [[spec [[bytes] [bytes]]]
      [examples [[[["foo" encode key] 2 times =] [yes]]]]]]

[sign [[spec [[[bytes message] [association key]] [bytes]]]]]

[verify [[spec [[[bytes signature]
                 [bytes message]
                 [sized key]]

                [boolean]]]
         [examples [[["foo" encode key "we attack at dawn" encode [sign] shield verify] [yes]]]]]]
[[delegated [[spec [[[association pubkey]] [program]]]
             [definition [[[sink ;; css cs pk
                            [[hash] [shield dip] decorated ;; css csh cs pk
                             float ;; cs css csh pk
                             [verify] dip
                             [[]]  ;; the program to run if the child script isn't authorized
                             branch] ;; runs the child script if the sig on its hash is verified
                            [drop drop ;; the sig and (empty) child script -> pk sig msg
                             sink ;; sig msg pk
                             verify]
                            [clone] dipdown branch]
                           [[]] recover]
                          swap prepend]]]] ;; prepend the pubkey

 [hash [[spec [[item] [bytes]]]
        [definition [[[[bytes?] [hashbytes]]
                      [[true] [encode hash]]]
                     decide]]]]]
join

1.15. Time and date

[[milliseconds [[spec [[integer] [integer]]]
                [definition []]]]

 [seconds [[spec [[integer] [integer]]]
           [definition [1000 *]]]]

 [minutes [[spec [[integer] [integer]]]
           [definition [seconds 60 *]]]]

 [hours [[spec [[integer] [integer]]]
         [definition [minutes 60 *]]]]

 [days [[spec [[integer] [integer]]]
        [definition [hours 24 *]]]]]
join

1.16. Nested Environments

[environment [[spec [[sized] [environment]]]
              [examples [[[[[program [1 2 3]]] environment eval-step [stack] lookup] [[1]]]]]]]

[eval-step [[spec [[environment] [environment]]]
            [examples [[[[[program [1 inc]]] environment
                         eval-step eval-step
                         [stack] lookup]
                        [[2]]]]]]]

[evaluate [[spec [[environment] [environment]]]
           [examples [[[[[program [1 2 3 4 + *]]] environment
                        evaluate
                        [stack] lookup]
                       [[14 1]]]]]]]

[finished? [[spec [[environment] [boolean]]]
            [examples [[[[[program [1 2 3 4 + *]]] environment
                        finished?]
                       [[]]]
                      [[[[program [1 2 3 4 + *]]] environment
                        evaluate
                        finished?]
                       [yes]]]]]]

[using [[spec [[[list modules] environment] [environment]]]]]
[tos [[spec [[environment] [item]]]
      [definition [[stack] lookup first]]
      [examples [[[[[stack [1 2 3]]
                    [program [[+] step]]]
                   tos]
                  [1]]]]]]

;; TODO we don't use the term 'expression' anymore so this needs renaming
[toe [[spec [[environment] [item]]]
      [definition [[program] lookup first]]
      [examples [[[[[stack [1 2 3]]
                    [program [[+] step]]]
                   toe]
                  [[+]]]]]]]

[stage [[spec [[program] [environment]]]
        [definition [[program] label environment]]]]

[spawn [[spec [[program dictionary] [environment]]]
        [definition [[snapshot] dipdown ;; p d s
                     [program dictionary stack] label
                     environment]]
        [examples [[[1 2 3 dictionary [swap clone] spawn]
                    [1 2 3 [[program [swap clone]] [stack [3 2 1]]] environment]]]]]]

[confine [[spec [[[program module] dictionary] [*]]]
          [definition [spawn evaluate [stack] lookup restore]]]]

1.16.1. Debugging

[[break [[spec [[[program condition] environment]
                [[program condition] environment]]]
         [definition [[[[swap something?] ;; still running
                        [execute not]] ;; check condition not true yet
                       [execute]
                       every?] ;; break?
                      [[eval-step] dip]  ;; evaluate the environment one step
                      while]]]]

 [breakpoint [[spec [[] []]]
              [definition []]]]

 [sprint [[spec [[environment]
                 [environment]]]
          [definition [[[program 0] lookup wrap [breakpoint] =] break
                       drop ;; the condition
                       [] [eval-step] when]]]] ;; advance past the breakpoint word if the program isn't complete


 [advance [[spec [[environment] [environment]]]
           [definition [[[program] lookup count] shield swap ;; count up the program length, we'll run until it's smaller than this

                        [[program] lookup count  ;; only stop if expr empty or shorter than we started off
                         [[positive?] [<=]] [execute] every?]
                        [eval-step]  ;; evaluate the environment one step
                        while
                        dropdown]]]]  ;; drop the program length item

 [stepper [[spec [[] [program]]]
           [definition [[eval-step clone]]]]]

 [tracer [[spec [[program] [[program generator]]]]
          [definition [stage stepper]]]]

 [dump [[spec [[] []]]
        [definition [snapshot emit autoformat print]]]]

 [heatmap [[spec [[program] [association]]]
           [definition [[tracer
                         ;; what item is being executed
                         [[program] lookup [first]
                          ;; don't emit [] or the execution stops, use 0 instead
                          bail 0 or]
                         each 
                         [word?] keep ;; count only words, which filters out the 0's from above
                         frequencies] shielddown]]]]]


join
1.16.1.1. Examples
  1. Count the number of times each word is executed while running a program.
    [[program [10 [0 >] [clone dec] while]]]  ;; the sample program to run
    environment
    evaluate
    
    [[stack [0 1 2 3 4 5 6 7 8 9 10]] [program []]]
    
    10 [0 >] [clone dec] while
    
    
    [0 1 2 3 4 5 6 7 8 9 10]
    
    [swap] unwrap  word?
    
    
    [yes]
    

    "Increment the counter, or set to 1 if nothing"

    [] [inc] bail 1 or
    
    1
    
    [] ;; empty list to put word counts in
    [[program [3 [0 >] [clone dec] while]]]  ;; the sample program to run
    environment
    [[program] lookup something?] ;; something still in the program, keep running
    [[[program] lookup first] shield ;; get the item we're about to execute
     swap ;; put it under the environment
     [[word?] ; if it's a word
      [wrap
       [[inc] bail 1 or]
       update] ;; the results, the count for the word about to execute
      [drop] ;; if it's not a word, do nothing
      if] dip
     eval-step] ;; evaluate the environment one step
    while
    drop ;; drop the environment and just report the word counts
    
    [[wrap 1] [step 2] [first 4] [snapshot 4] [execute 1] [put 1] [inject 4] [loop 4] [dec 3] [decorate 1] [swap 5] [unwrap 14] [take 4] [join 1] [> 4] [while 1] [shield 4] [dipdown 1] [evert 16] [clone 8] [dip 9]]
    
  2. CANCELED spec checking

    clojure spec check can be replaced with predicate programs, that will be run with shield before the actual word and if it returns false, will raise an error.

  3. TODO Trace output
    [] ;; results
    [[program [1 [2 3 4 5] [*] step]]]  ;; the sample program to run
    environment
    
    [[program] lookup something?] ;; break?
    [eval-step clone [put] dip]  ;; evaluate the environment one step
    while
    
    
    [[[stack [120]] [program []]]
     [[[stack [1]] [program [[2 3 4 5] [*] step]]]
      [[stack [[2 3 4 5] 1]] [program [[*] step]]]
      [[stack [[*] [2 3 4 5] 1]] [program [step]]]
      [[stack [[*] 2 1]] [program [execute [3 4 5] [*] step]]]
      [[stack [2 1]] [program [* [3 4 5] [*] step]]]
      [[stack [2]] [program [[3 4 5] [*] step]]]
      [[stack [[3 4 5] 2]] [program [[*] step]]]
      [[stack [[*] [3 4 5] 2]] [program [step]]]
      [[stack [[*] 3 2]] [program [execute [4 5] [*] step]]]
      [[stack [3 2]] [program [* [4 5] [*] step]]]
      [[stack [6]] [program [[4 5] [*] step]]]
      [[stack [[4 5] 6]] [program [[*] step]]]
      [[stack [[*] [4 5] 6]] [program [step]]]
      [[stack [[*] 4 6]] [program [execute [5] [*] step]]]
      [[stack [4 6]] [program [* [5] [*] step]]]
      [[stack [24]] [program [[5] [*] step]]]
      [[stack [[5] 24]] [program [[*] step]]]
      [[stack [[*] [5] 24]] [program [step]]]
      [[stack [[*] 5 24]] [program [execute]]]
      [[stack [5 24]] [program [*]]]
      [[stack [120]] [program []]]]]
    
  4. DONE Step count limiting

    When testing or debugging, limit the number of steps to avoid a possible infinite loop.

    200 ;; step count remaining
    [[program [10 [0 >] [clone dec] while]]]  ;; the sample program to run
    environment
    
    [[program] lookup something? ;; something still in the program
     [positive?] dip and] ;; still step budget remaining
    [eval-step ;; evaluate the environment one step
     [dec] dip] ;; decrease the step budget
    while
    
    ;[stack] lookup ;; return the output
    
    [[program [take dip evert first [clone dec [0 >] shield] loop]] [stack [[[0 >] 4 5 6 7 8 9 10] 4 5 6 7 8 9 10]]] 0
    
  5. DONE Breakpoint
    [[[[toe [+] unwrap =]
       [tos 3 >]]
      [execute]
      every?] ;; when to stop - when we're about to add and tos already >3
     [0 [1 2 3 4 5] [+] step]  ;; the sample program to run
     environment
    
     [[[[program] lookup something?] ;; something still in the program
       [swap execute not]] ;; don't stop yet
      [execute]
      every?] ;; break?
     [eval-step]  ;; evaluate the environment one step
     while]
    
  6. TODO Step over
    [[0 [1 2 3 4 5] [+] step]  ;; the sample program to run
     environment
    
    [[program] lookup count] shield swap;; count up the program length, we'll run until it's smaller than this
    
     [[program] lookup count
      [[positive?] [<=]] [execute] every?] ;; only stop if expr empty or shorter than we started off
     [eval-step]  ;; evaluate the environment one step
     while]
    

1.17. Templating macro

[[subs-point? [[definition [[[list?]
                             [count 2 =]
                             [first [poke splice] set swap contains?]]
                            [execute] every?]]]]
 [subs [[definition [second [wrap lookup] shielddown]]]]
 [template-inner [[definition [[[[subs-point?] [[first wrap [poke] =]
                                                [subs wrap]
                                                [subs] if]]
                                [[list?] [[] swap ;;  t acc v
                                          [swap [template-inner] dive join] step wrap]]
                                [[yes] [wrap]]]
                               decide]]]]
 [template [[spec [[[list template] [sized values]] [list]]]
            [definition [template-inner unwrap dropdown]]
            [examples [[[[[a [foo]] [b bar]]
                         [[poke a] [[poke b] x [splice a]] c d 1 2 3] template]
                        [[[foo] [bar x foo] c d 1 2 3]]]]]]]]
join

1.18. Functional environment

There are use cases for kcats where you don't want a program to be able to mess with external resources like files, network sockets etc nor be able to spawn new threads, the program it's running should be a pure function and this module lets you enforce that.

[pipe-in pipe-out channel timeout
 handoff file-in file-out timestamps
 standard serversocket animate future
 spit tunnel database]
[wrap unassign] step

2. Issues

2.1. DONE Get rid of platform-specific definitions

2.2. DONE fix evaluate

[[program [1 1 +]]] environment evaluate [stack] lookup

[[2]]

2.3. TODO merkle tree functions

"foo" "bar" join hash "foobar" hash =
yes

First let's figure out how to represent a tree:

;[5 [[3 [[1c []]
;        [2c []]]]
;    [4 [[3c []]]]]]
[[hash []]
 [children [second]]
 [data [first]]
 [node [[] pair]]
 [empty-node [#b64 "" hash node]]
 [child [[children] dip get]]
 [addchild [[pop] dip put put]]
 [rawpath [1 [interpose] shield swap prepend dropdown]]
 [siblings [[] node sink [addchild] dip addchild]]
 ;[path [[] [take swap [child] dip path] [drop] if]]
 [path [dec 2 radix rawpath]]
 [parent [butlast butlast]]
 [rehash [[children [data] map] shield
          [first] shield empty swap [join] step
          hash wrap [0] swap update]]
 ;; lopsidedtree n
 [balance []]
 ;; node tree cur-ct
 [add [[clone path [pop zero?] [parent] when] dipdown  ;; node tree path ct
       swapdown ;; node path tree ct
       []]]
 [add [[odd?]
       ;; insert an unbalanced node (empty sibling)
       [empty-node siblings [path parent]]
       ;; otherwise replace the empty sibling
       []
      ]]]
; ["" drop
;  ;[0 []] 1 node addchild 2 node 3 node addchild addchild
;  ;[1 0]  1 [interpose] shield swap put dropdown lookup
;  "foo"  hash node "bar"  hash node siblings
;  ;; update the root node
;  rehash
;  ; now add a new sibling
;  "baz"  hash node siblings
;  rehash
;  3 path [pop zero?] [butlast butlast] [] if
;  ;dump
;  ["quux" hash node siblings rehash ] update
; ]
[["foo" "bar" "baz" "quux"] [node] map []
let
[["foo" []]
 ["bar" []]
 ["baz" []]
 ["quux" []]]
  • 1234

    • 12
      • 1
      • 2
    • 34
      • 3
      • 4
    • 5
    • 6
["foobarbaz" [["foobar" [["foo" []]
                         ["bar" []]]]
              ["bazquux" [["baz" []]
                          ["quux" []]]]]]
["" []]

interpose impl

[1 3 4] [foo] unwrap interpose
[1 foo 3 foo 4]
[0 [[1 []]
    [2 [[3 []]]]]]
  [1 0] 1 [interpose] shield swap prepend 0 put dropdown [inc] update
[0 [[1 []]
    [2 [[4 []]]]]]

We need a function that, given a number n, gives the path in the merkle tree. eg, 8 would be 1 1 1. Is it just n-1 in binary? 6 would be 1 0 1. Ok so just write a function to expand binary digits:

8 dec 2 radix
[1 1 1]
["foobarbaz" [["foobar" [["foo" []]
                         ["bar" []]]]
              ["baz" []]]] [1 1] [drop drop "hi" "there"] update
["foobarbaz" [["foobar" [["foo" []]
                         ["bar" []]]]
              "there"]]
[[hash []]
 [children [second]]
 [data [first]]
 [node [[] pair]]
 [child [[children] dip get]]
 [addchild [[pop] dip put put]]
 [siblings [[] node sink [addchild] dip addchild]]
 ;[path [[] [take swap [child] dip path] [drop] if]]
 [path [dec 2 radix nodepath]]
 [rehash [[children [data] map] shield [first] shield empty swap [join] step hash wrap [0] swap update]]]
[["foobarbaz" [["foobar" [["foo" []]
                          ["bar" []]]]
               ["baz" []]]]
 [1 1]

 ["bazquux" [["baz" []]
             ["quux" []]]]
 assign]
let
["foobarbaz" [["foobar" [["foo" []]
                         ["bar" []]]]
              ["bazquux" [["baz" []]
                          ["quux" []]]]]]
[["bazquux" [["baz" []]
             ["quux" []]]]
 [1 1]
 ["foobarbaz" [["foobar" [["foo" []]
                          ["bar" []]]]
               ["baz" []]]]]
reverse unwrap assign
["foobarbaz" [["foobar" [["foo" []]
                         ["bar" []]]]
              ["bazquux" [["baz" []]
                          ["quux" []]]]]]
[
 [children [second]]
 [data [first]]
 [node [[] pair]]
 [addchild [[pop] dip put put]]
 [siblings [[] node sink [addchild] dip addchild]]
 [nodepath [1 [interpose] shield swap prepend dropdown]]
 [padded [[[[count] shield] dive -] dip
          swap repeat
          swap join]]
 [path [[dec 2 radix] dip 2 log ceiling 0 padded nodepath]] ;; item-ct index
 [depth []]

 [rehash [[children [data] map] shield
          [first] shield empty swap
          [join] step
          hash
          wrap [0] swap update]]
 [joiner [[2 2 partition
           [[count 1 =] [[] put] when
            unwrap siblings] each]
          assemble [rehash] map]]
 [merkle [[hash node] map
          [count 1 >] [joiner] while]]]
[["a" "b" "c" "d" "e"]
 count
 5 ;; 2nd item
 swap path ]
let
[1 1 1 0 1 0]
[[#b64 "FO3l6Ol62TcjJ3KPUJm5VgSjlZPKw704o0OtdiBSE+c=" [[#b64 "5aAf7hTg7VxIcU8iGA8lrYNltT+XefedxKPX6Tlj+Uo="
                                                        [[#b64 "ypeBEsobvcr6wjGzmiPcTaeG7/gUfE5yuYB3ha/uSLs=" []]
                                                         [#b64 "PiPoFgA5WUoziU9lZOGxNIu9egCI1CxKy3PurtWcAJ0=" []]]]
                                                       [#b64 "v/4LNNuha8b6wXwIusVdZ2ze1aSt5B/iyZJKXd6PPls=" [[#b64 "Ln0sA6lQeuJl7PW1NWiFpTOTogKdJBOUmXJloaJa78Y="
                                                                                                              []]
                                                                                                             [#b64 "GKw+c0PwFokMUQ6T+TUmEWnZ4/VlQ2Qpgw+vCTT0+OQ=" []]]]]]]
[1 1 1] 5 0 [[[count] shield] dive -] dip
        swap repeat
        swap join
[0 0 1 1 1]

2.4. CANCELED Make taker/dropper more flexible

Goal: implement drop and drop-while with the same logic

Canceled - the commonality between drop and drop-while are too small to be worth trying to factor out.

[1 2 3 4 5] [take]
3
[[[positive?]
  [[generate drop] dip dec]
  while
  [generate swap] dip float]
 bail]
collect
[4 5]
[[[positive?] [[generate drop]
               dip dec]
  while [generate swap]
  dip float]
 bail]
0 [take] []

This is what drop-while looks like

[] [take]
[positive?]
[] ;; the state (whether threshold reached)
[[] ;; condition - whether we've finished dropping or not 
 [[generate] divedown] ;; true - pass everything else through
 [[[generate] divedown] ;; prime init
  [[[clone] divedown execute] bail] ;; bring pred up and exec it
  [drop] ;; if pred passes drop the value
  prime ;; after this should have value on top
  [drop true] dip ;; set flag
 ] ;; false - generate, check pred, repeat
 if]
collect
[] [[] [[generate] divedown]
    [[[generate] divedown]
     [[[clone] divedown execute] bail]
     [drop] prime [drop yes]
     dip]
    if]
yes [positive?] [take] []

Author: Skyrod Vactai

Created: 2024-06-26 Wed 20:00

Validate