# Examples (and some documentation) for the Words in the Library¶

# Stack Chatter¶

This is what I like to call the functions that just rearrange things on the stack. (One thing I want to mention is that during a hypothetical compilation phase these "stack chatter" words effectively disappear, because we can map the logical stack locations to registers that remain static for the duration of the computation. This remains to be done but it's "off the shelf" technology.)

### `clear`¶

In [132]:

    1 2 3

    1 1 3 1 2 3

In [133]:

    clear

### `dup` `dupd`¶

In [134]:

    1 2 3 dup

    1 2 3 3

In [135]:

    clear

In [136]:

    1 2 3 dupd

    1 2 2 3

In [137]:

    clear

### `enstacken` `disenstacken` `stack` `unstack`¶

Replace the stack with a quote of itself.

In [138]:

    1 2 3 enstacken

    [3 2 1]

In [139]:

    clear

Unpack a list onto the stack.

4 5 6 [3 2 1] unstack

Get the stack on the stack.

In [140]:

    1 2 3 stack

    1 2 3 [3 2 1]

In [141]:

    clear

Replace the stack with the list on top. The items appear reversed but they are not, is on the top of both the list and the stack.

In [142]:

    1 2 3 [4 5 6] disenstacken

    6 5 4

### `pop` `popd` `popop`¶

In [143]:

    clear
    1 2 3 pop

    1 2

In [144]:

    clear
    1 2 3 popd

    1 3

In [145]:

    clear
    1 2 3 popop

    1

### `roll<` `rolldown` `roll>` `rollup`¶

The "down" and "up" refer to the movement of two of the top three items (displacing the third.)

In [146]:

    clear
    1 2 3 roll<

    2 3 1

In [147]:

    clear
    1 2 3 roll>

    3 1 2

### `swap`¶

In [148]:

    clear
    1 2 3 swap

    1 3 2

### `tuck` `over`¶

In [149]:

    clear
    1 2 3 tuck

    1 3 2 3

In [150]:

    clear
    1 2 3 over

    1 2 3 2

### `unit` `quoted` `unquoted`¶

In [151]:

    clear
    1 2 3 unit

    1 2 [3]

In [152]:

    clear
    1 2 3 quoted

    1 [2] 3

In [153]:

    clear
    1 [2] 3 unquoted

    1 2 3

Unquoting evaluates. Be aware.

In [154]:

    clear
    1 [dup] 3 unquoted

    1 1 3

# List words¶

### `concat` `swoncat` `shunt`¶

In [155]:

    clear
    [1 2 3] [4 5 6] concat

    [1 2 3 4 5 6]

In [156]:

    clear
    [1 2 3] [4 5 6] swoncat

    [4 5 6 1 2 3]

In [157]:

    clear
    [1 2 3] [4 5 6] shunt

    [6 5 4 1 2 3]

### `cons` `swons` `uncons`¶

In [158]:

    clear
    1 [2 3] cons

    [1 2 3]

In [159]:

    clear
    [2 3] 1 swons

    [1 2 3]

In [160]:

    clear
    [1 2 3] uncons

    1 [2 3]

### `first` `second` `third` `rest`¶

In [161]:

    clear
    [1 2 3 4] first

    1

In [162]:

    clear
    [1 2 3 4] second

    2

In [163]:

    clear
    [1 2 3 4] third

    3

In [166]:

    clear
    [1 2 3 4] rest

    [2 3 4]

### `flatten`¶

In [167]:

    clear
    [[1] [2 [3] 4] [5 6]] flatten

    [1 2 [3] 4 5 6]

### `getitem` `at` `of` `drop` `take`¶

`at` and `getitem` are the same function. `of == swap at`

In [168]:

    clear
    [10 11 12 13 14] 2 getitem

    12

In [169]:

    clear
    [1 2 3 4] 0 at

    1

In [170]:

    clear
    2 [1 2 3 4] of

    3

In [171]:

    clear
    [1 2 3 4] 2 drop

    [3 4]

In [172]:

    clear
    [1 2 3 4] 2 take

    [2 1]

`take` reverses the order.

`reverse` could be defines as `reverse == dup size take`

### `remove`¶

In [173]:

    clear
    [1 2 3 1 4] 1 remove

    [2 3 1 4]

### `reverse`¶

In [174]:

    clear
    [1 2 3 4] reverse

    [4 3 2 1]

### `size`¶

In [175]:

    clear
    [1 1 1 1] size

    4

### `swaack`¶

"Swap stack" swap the list on the top of the stack for the stack, and put the old stack on top of the new one. Think of it as a context switch. Niether of the lists/stacks change their order.

In [176]:

    clear
    1 2 3 [4 5 6] swaack

    6 5 4 [3 2 1]

### `choice` `select`¶

In [180]:

    clear
    23 9 true choice

    9

In [181]:

    clear
    23 9 false choice

    23

In [182]:

    clear
    [23 9 7] 1 select

    9

(`select` is basically `getitem`, should retire it?)

In [183]:

    clear
    [23 9 7] 0 select

    23

### `zip`¶

In [184]:

    clear
    [1 2 3] [6 5 4] zip

    [[6 1] [5 2] [4 3]]

In [185]:

    clear
    [1 2 3] [6 5 4] zip [sum] map

    [7 7 7]

# Math words¶

### `+` `add`¶

In [186]:

    clear
    23 9 +

    32

### `-` `sub`¶

In [187]:

    clear
    23 9 -

    14

### `*` `mul`¶

In [188]:

    clear
    23 9 *

    207

### `/` `div`¶

In [189]:

    clear
    23 9 /

    2

In [191]:

    clear
    23 9 div

    2

In [193]:

    clear
    23 -9 div

    -3

### `%` `mod` `modulus` `rem` `remainder`¶

In [195]:

    clear
    23 9 %

    5

### `neg`¶

In [196]:

    clear
    23 neg -5 neg

    -23 5

### pow¶

In [197]:

    clear
    2 10 pow

    1024

### `sqr`¶

In [198]:

    clear
    23 sqr

    529

### `++` `succ` `--` `pred`¶

In [199]:

    clear
    1 ++

    2

In [200]:

    clear
    1 --

    0

### `<<` `lshift` `>>` `rshift`¶

In [201]:

    clear
    8 1 <<

    16

In [202]:

    clear
    8 1 >>

    4

### `range` `range_to_zero` `down_to_zero`¶

In [204]:

    clear
    5 range

    [4 3 2 1 0]

In [205]:

    clear
    5 range_to_zero

    [0 1 2 3 4 5]

In [206]:

    clear
    5 down_to_zero

    5 4 3 2 1 0

In [207]:

    clear
    [5 down_to_zero] run

    [0 1 2 3 4 5]

### `product`¶

In [208]:

    clear
    [1 2 3 5] product

    30

### `sum`¶

In [209]:

    clear
    [1 2 3 5] sum

    11

### `min`¶

In [210]:

    clear
    [1 2 3 5] min

    1

### `gcd`¶

In [211]:

    clear
    45 30 gcd

    15

# Logic and Comparison¶

### `?` `truthy`¶

Get the Boolean value of the item on the top of the stack.

In [216]:

    clear
    23 bool

    true

In [217]:

    clear
    [] bool

    false

In [218]:

    clear
    0 bool

    false

    ? == dup truthy

In [219]:

    clear
    23 ?

    23 true

In [220]:

    clear
    [] ?

    [] false

In [221]:

    clear
    0 ?

    0 false

### `&` `and`¶

In [223]:

    clear
    true false &

    false

### `!=` `<>` `ne`¶

In [224]:

    clear
    23 9 !=

    true

The usual suspects:

- `<` `lt`
- `<=` `le`
- `=` `eq`
- `>` `gt`
- `>=` `ge`
- `not`
- `or`

# Miscellaneous¶

### `help`¶

In [228]:

    clear
    [help] help

    ==== Help on help ====

    Accepts a quoted symbol on the top of the stack and prints its docs.

    ---- end ( help )

### `run`¶

Evaluate a quoted Joy sequence.

In [229]:

    clear
    [1 2 dup + +] run

    [5]

# Combinators¶

### `app1` `app2` `app3`¶

In [230]:

    clear
    [app1] help

    ==== Help on app1 ====

    app1 ≡ grba infrst

    ---- end ( app1 )

In [231]:

    clear
    10 4 [sqr *] app1

    10 160

In [232]:

    clear
    10 3 4 [sqr *] app2

    10 90 160

In [233]:

    clear
    [app2] help

    ==== Help on app2 ====

    app2 ≡ [grba swap grba swap] dip [infrst] cons ii

    ---- end ( app2 )

In [234]:

    clear
    10 2 3 4 [sqr *] app3

    160 90 40

(Wait... is that... backwards?)

It should be `40 90 160` shouldn't it?

In [235]:

    clear
    10 2 3 4 [sqr *] 3 [grabN] codi map reverse disenstacken

    40 90 160

Ah! See? It needs `reverse` in there!

In [236]:

    clear
    10 2 3 4 5 [sqr *] 4 [grabN] codi map reverse disenstacken

    40 90 160 250

### `anamorphism`¶

Given an initial value, a predicate function `[P]`, and a generator function `[G]`, the `anamorphism` combinator creates a sequence.

       n [P] [G] anamorphism
    ---------------------------
              [...]

Example, `range`:

    range == [0 <=] [1 - dup] anamorphism

In [ ]:

    J('3 [0 <=] [1 - dup] anamorphism')

### `branch`¶

In [ ]:

    J('3 4 1 [+] [*] branch')

In [ ]:

    J('3 4 0 [+] [*] branch')

### `cleave`¶

    ... x [P] [Q] cleave

From the original Joy docs: "The cleave combinator expects two quotations, and below that an item `x` It first executes `[P]`, with `x` on top, and saves the top result element. Then it executes `[Q]`, again with `x`, and saves the top result. Finally it restores the stack to what it was below `x` and pushes the two results P(X) and Q(X)."

Note that `P` and `Q` can use items from the stack freely, since the stack (below `x`) is restored. `cleave` is a kind of parallel primitive, and it would make sense to create a version that uses, e.g. Python threads or something, to actually run `P` and `Q` concurrently. The current implementation of `cleave` is a definition in terms of `app2`:

    cleave == [i] app2 [popd] dip

In [ ]:

    J('10 2 [+] [-] cleave')

### `dip` `dipd` `dipdd`¶

In [ ]:

    J('1 2 3 4 5 [+] dip')

In [ ]:

    J('1 2 3 4 5 [+] dipd')

In [ ]:

    J('1 2 3 4 5 [+] dipdd')

### `dupdip`¶

Expects a quoted program `[Q]` on the stack and some item under it, `dup` the item and `dip` the quoted program under it.

    n [Q] dupdip == n Q n

In [ ]:

    V('23 [++] dupdip *')  # N(N + 1)

### `genrec` `primrec`¶

In [ ]:

    J('[genrec] help')

In [ ]:

    J('3 [1 <=] [] [dup --] [i *] genrec')

### `i`¶

In [ ]:

    V('1 2 3 [+ +] i')

### `ifte`¶

    [predicate] [then] [else] ifte

In [ ]:

    J('1 2 [1] [+] [*] ifte')

In [ ]:

    J('1 2 [0] [+] [*] ifte')

### `infra`¶

In [ ]:

    V('1 2 3 [4 5 6] [* +] infra')

### `loop`¶

In [ ]:

    J('[loop] help')

In [ ]:

    V('3 dup [1 - dup] loop')

### `map` `pam`¶

In [ ]:

    J('10 [1 2 3] [*] map')

In [ ]:

    J('10 5 [[*][/][+][-]] pam')

### `nullary` `unary` `binary` `ternary`¶

Run a quoted program enforcing arity.

In [ ]:

    J('1 2 3 4 5 [+] nullary')

In [ ]:

    J('1 2 3 4 5 [+] unary')

In [ ]:

    J('1 2 3 4 5 [+] binary')  # + has arity 2 so this is technically pointless...

In [ ]:

    J('1 2 3 4 5 [+] ternary')

### `step`¶

In [ ]:

    J('[step] help')

In [ ]:

    V('0 [1 2 3] [+] step')

### `times`¶

In [ ]:

    V('3 2 1 2 [+] times')

### `b`¶

In [ ]:

    J('[b] help')

In [ ]:

    V('1 2 [3] [4] b')

### `while`¶

    [predicate] [body] while

In [ ]:

    J('3 [0 >] [dup --] while')

### `x`¶

In [ ]:

    J('[x] help')

In [ ]:

    V('1 [2] [i 3] x')  # Kind of a pointless example.

# `void`¶

Implements Laws of Form arithmetic over quote-only datastructures (that is, datastructures that consist soley of containers, without strings or numbers or anything else.)

In [ ]:

    J('[] void')

In [ ]:

    J('[[]] void')

In [ ]:

    J('[[][[]]] void')

In [ ]:

    J('[[[]][[][]]] void')