Thun/docs/2._Library_Examples.md

11 KiB

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

from notebook_preamble import J, V

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

J('1 2 3 clear')

dup dupd

J('1 2 3 dup')
1 2 3 3
J('1 2 3 dupd')
1 2 2 3

enstacken disenstacken stack unstack

(I may have these paired up wrong. I.e. disenstacken should be unstack and vice versa.)

J('1 2 3 enstacken') # Replace the stack with a quote of itself.
[3 2 1]
J('4 5 6 [3 2 1] disenstacken')  # Unpack a list onto the stack.
4 5 6 3 2 1
J('1 2 3 stack')  # Get the stack on the stack.
1 2 3 [3 2 1]
J('1 2 3 [4 5 6] unstack')  # Replace the stack with the list on top.
                            # The items appear reversed but they are not,
                            # 4 is on the top of both the list and the stack.
6 5 4

pop popd popop

J('1 2 3 pop')
1 2
J('1 2 3 popd')
1 3
J('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.)

J('1 2 3 roll<')
2 3 1
J('1 2 3 roll>')
3 1 2

swap

J('1 2 3 swap')
1 3 2

tuck over

J('1 2 3 tuck')
1 3 2 3
J('1 2 3 over')
1 2 3 2

unit quoted unquoted

J('1 2 3 unit')
1 2 [3]
J('1 2 3 quoted')
1 [2] 3
J('1 [2] 3 unquoted')
1 2 3
V('1 [dup] 3 unquoted')  # Unquoting evaluates.  Be aware.
              . 1 [dup] 3 unquoted
            1 . [dup] 3 unquoted
      1 [dup] . 3 unquoted
    1 [dup] 3 . unquoted
    1 [dup] 3 . [i] dip
1 [dup] 3 [i] . dip
      1 [dup] . i 3
            1 . dup 3
          1 1 . 3
        1 1 3 . 

List words

concat swoncat shunt

J('[1 2 3] [4 5 6] concat')
[1 2 3 4 5 6]
J('[1 2 3] [4 5 6] swoncat')
---------------------------------------------------------------------------

KeyError                                  Traceback (most recent call last)

<ipython-input-22-15579491b615> in <module>()
----> 1 J('[1 2 3] [4 5 6] swoncat')


/home/sforman/Desktop/ArchLayer/System/source/Thun/docs/notebook_preamble.py in J(text, stack, dictionary)
     30 
     31 def J(text, stack=S, dictionary=D):
---> 32     print stack_to_string(run(text, stack, dictionary)[0])
     33 
     34 


/home/sforman/Desktop/ArchLayer/System/source/Thun/venv/local/lib/python2.7/site-packages/joy/joy.pyc in run(text, stack, dictionary, viewer)
     77 	'''
     78         expression = text_to_expression(text)
---> 79         return joy(stack, expression, dictionary, viewer)
     80 
     81 


/home/sforman/Desktop/ArchLayer/System/source/Thun/venv/local/lib/python2.7/site-packages/joy/joy.pyc in joy(stack, expression, dictionary, viewer)
     56                 term, expression = expression
     57                 if isinstance(term, Symbol):
---> 58                         term = dictionary[term]
     59                         stack, expression, dictionary = term(stack, expression, dictionary)
     60                 else:


KeyError: swoncat
J('[1 2 3] [4 5 6] shunt')

cons swons uncons

J('1 [2 3] cons')
J('[2 3] 1 swons')
J('[1 2 3] uncons')

first second third rest

J('[1 2 3 4] first')
J('[1 2 3 4] second')
J('[1 2 3 4] third')
J('[1 2 3 4] rest')

flatten

J('[[1] [2 [3] 4] [5 6]] flatten')

getitem at of drop take

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

J('[10 11 12 13 14] 2 getitem')
J('[1 2 3 4] 0 at')
J('2 [1 2 3 4] of')
J('[1 2 3 4] 2 drop')
J('[1 2 3 4] 2 take')  # reverses the order

reverse could be defines as reverse == dup size take

remove

J('[1 2 3 1 4] 1 remove')

reverse

J('[1 2 3 4] reverse')

size

J('[1 1 1 1] size')

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.

J('1 2 3 [4 5 6] swaack')

choice select

J('23 9 1 choice')
J('23 9 0 choice')
J('[23 9 7] 1 select')  # select is basically getitem, should retire it?
J('[23 9 7] 0 select')

zip

J('[1 2 3] [6 5 4] zip')
J('[1 2 3] [6 5 4] zip [sum] map')

Math words

+ add

J('23 9 +')

- sub

J('23 9 -')

* mul

J('23 9 *')

/ div floordiv truediv

J('23 9 /')
J('23 -9 truediv')
J('23 9 div')
J('23 9 floordiv')
J('23 -9 div')
J('23 -9 floordiv')

% mod modulus rem remainder

J('23 9 %')

neg

J('23 neg -5 neg')

pow

J('2 10 pow')

sqr sqrt

J('23 sqr')
J('23 sqrt')

++ succ -- pred

J('1 ++')
J('1 --')

<< lshift >> rshift

J('8 1 <<')
J('8 1 >>')

average

J('[1 2 3 5] average')

range range_to_zero down_to_zero

J('5 range')
J('5 range_to_zero')
J('5 down_to_zero')

product

J('[1 2 3 5] product')

sum

J('[1 2 3 5] sum')

min

J('[1 2 3 5] min')

gcd

J('45 30 gcd')

least_fraction

If we represent fractions as a quoted pair of integers [q d] this word reduces them to their ... least common factors or whatever.

J('[45 30] least_fraction')
J('[23 12] least_fraction')

Logic and Comparison

? truthy

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

J('23 truthy')
J('[] truthy')  # Python semantics.
J('0 truthy')
? == dup truthy
V('23 ?')
J('[] ?')
J('0 ?')

& and

J('23 9 &')

!= <> ne

J('23 9 !=')

The usual suspects:

  • < lt
  • <= le
  • = eq
  • > gt
  • >= ge
  • not
  • or

^ xor

J('1 1 ^')
J('1 0 ^')

Miscellaneous

help

J('[help] help')

parse

J('[parse] help')
J('1 "2 [3] dup" parse')

run

Evaluate a quoted Joy sequence.

J('[1 2 dup + +] run')

Combinators

app1 app2 app3

J('[app1] help')
J('10 4 [sqr *] app1')
J('10 3 4 [sqr *] app2')
J('[app2] help')
J('10 2 3 4 [sqr *] app3')

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
J('3 [0 <=] [1 - dup] anamorphism')

branch

J('3 4 1 [+] [*] branch')
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
J('10 2 [+] [-] cleave')

dip dipd dipdd

J('1 2 3 4 5 [+] dip')
J('1 2 3 4 5 [+] dipd')
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
V('23 [++] dupdip *')  # N(N + 1)

genrec primrec

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

i

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

ifte

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

infra

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

loop

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

map pam

J('10 [1 2 3] [*] map')
J('10 5 [[*][/][+][-]] pam')

nullary unary binary ternary

Run a quoted program enforcing arity.

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

step

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

times

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

b

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

while

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

x

J('[x] help')
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.)

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