78 KiB
78 KiB
In [6]:
from notebook_preamble import D, J, V, define, DefinitionWrapperIn [2]:
define('BTree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec')In [3]:
J('[] [23] BTree-iter') # It doesn't matter what F is as it won't be used.In [4]:
J('["tommy" 23 [] []] [first] BTree-iter')'tommy'
In [5]:
J('["tommy" 23 ["richard" 48 [] []] ["jenny" 18 [] []]] [first] BTree-iter')'tommy' 'richard' 'jenny'
In [6]:
J('["tommy" 23 ["richard" 48 [] []] ["jenny" 18 [] []]] [second] BTree-iter')23 48 18
In [7]:
define('BTree-new == swap [[] []] cons cons')In [8]:
V('"v" "k" BTree-new') . 'v' 'k' BTree-new
'v' . 'k' BTree-new
'v' 'k' . BTree-new
'v' 'k' . swap [[] []] cons cons
'k' 'v' . [[] []] cons cons
'k' 'v' [[] []] . cons cons
'k' ['v' [] []] . cons
['k' 'v' [] []] .
In [9]:
define('P == pop roll> pop first')In [10]:
V('["k" "v" [] []] "vv" "kk" [0] P >') . ['k' 'v' [] []] 'vv' 'kk' [0] P >
['k' 'v' [] []] . 'vv' 'kk' [0] P >
['k' 'v' [] []] 'vv' . 'kk' [0] P >
['k' 'v' [] []] 'vv' 'kk' . [0] P >
['k' 'v' [] []] 'vv' 'kk' [0] . P >
['k' 'v' [] []] 'vv' 'kk' [0] . pop roll> pop first >
['k' 'v' [] []] 'vv' 'kk' . roll> pop first >
'kk' ['k' 'v' [] []] 'vv' . pop first >
'kk' ['k' 'v' [] []] . first >
'kk' 'k' . >
True .
In [11]:
define('K == cons cons dipdd')
define('T == [K] cons cons cons infra')In [12]:
V('"r" "l" "v" "k" "vv" "kk" [0] K') . 'r' 'l' 'v' 'k' 'vv' 'kk' [0] K
'r' . 'l' 'v' 'k' 'vv' 'kk' [0] K
'r' 'l' . 'v' 'k' 'vv' 'kk' [0] K
'r' 'l' 'v' . 'k' 'vv' 'kk' [0] K
'r' 'l' 'v' 'k' . 'vv' 'kk' [0] K
'r' 'l' 'v' 'k' 'vv' . 'kk' [0] K
'r' 'l' 'v' 'k' 'vv' 'kk' . [0] K
'r' 'l' 'v' 'k' 'vv' 'kk' [0] . K
'r' 'l' 'v' 'k' 'vv' 'kk' [0] . cons cons dipdd
'r' 'l' 'v' 'k' 'vv' ['kk' 0] . cons dipdd
'r' 'l' 'v' 'k' ['vv' 'kk' 0] . dipdd
'r' . 'vv' 'kk' 0 'l' 'v' 'k'
'r' 'vv' . 'kk' 0 'l' 'v' 'k'
'r' 'vv' 'kk' . 0 'l' 'v' 'k'
'r' 'vv' 'kk' 0 . 'l' 'v' 'k'
'r' 'vv' 'kk' 0 'l' . 'v' 'k'
'r' 'vv' 'kk' 0 'l' 'v' . 'k'
'r' 'vv' 'kk' 0 'l' 'v' 'k' .
In [13]:
V('["k" "v" "l" "r"] "vv" "kk" [0] T') . ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] T
['k' 'v' 'l' 'r'] . 'vv' 'kk' [0] T
['k' 'v' 'l' 'r'] 'vv' . 'kk' [0] T
['k' 'v' 'l' 'r'] 'vv' 'kk' . [0] T
['k' 'v' 'l' 'r'] 'vv' 'kk' [0] . T
['k' 'v' 'l' 'r'] 'vv' 'kk' [0] . [K] cons cons cons infra
['k' 'v' 'l' 'r'] 'vv' 'kk' [0] [K] . cons cons cons infra
['k' 'v' 'l' 'r'] 'vv' 'kk' [[0] K] . cons cons infra
['k' 'v' 'l' 'r'] 'vv' ['kk' [0] K] . cons infra
['k' 'v' 'l' 'r'] ['vv' 'kk' [0] K] . infra
'r' 'l' 'v' 'k' . 'vv' 'kk' [0] K [] swaack
'r' 'l' 'v' 'k' 'vv' . 'kk' [0] K [] swaack
'r' 'l' 'v' 'k' 'vv' 'kk' . [0] K [] swaack
'r' 'l' 'v' 'k' 'vv' 'kk' [0] . K [] swaack
'r' 'l' 'v' 'k' 'vv' 'kk' [0] . cons cons dipdd [] swaack
'r' 'l' 'v' 'k' 'vv' ['kk' 0] . cons dipdd [] swaack
'r' 'l' 'v' 'k' ['vv' 'kk' 0] . dipdd [] swaack
'r' . 'vv' 'kk' 0 'l' 'v' 'k' [] swaack
'r' 'vv' . 'kk' 0 'l' 'v' 'k' [] swaack
'r' 'vv' 'kk' . 0 'l' 'v' 'k' [] swaack
'r' 'vv' 'kk' 0 . 'l' 'v' 'k' [] swaack
'r' 'vv' 'kk' 0 'l' . 'v' 'k' [] swaack
'r' 'vv' 'kk' 0 'l' 'v' . 'k' [] swaack
'r' 'vv' 'kk' 0 'l' 'v' 'k' . [] swaack
'r' 'vv' 'kk' 0 'l' 'v' 'k' [] . swaack
['k' 'v' 'l' 0 'kk' 'vv' 'r'] .
In [14]:
define('Te == [cons cons dipd] cons cons cons infra')In [15]:
V('["k" "v" "l" "r"] "vv" "kk" [0] Te') . ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] Te
['k' 'v' 'l' 'r'] . 'vv' 'kk' [0] Te
['k' 'v' 'l' 'r'] 'vv' . 'kk' [0] Te
['k' 'v' 'l' 'r'] 'vv' 'kk' . [0] Te
['k' 'v' 'l' 'r'] 'vv' 'kk' [0] . Te
['k' 'v' 'l' 'r'] 'vv' 'kk' [0] . [cons cons dipd] cons cons cons infra
['k' 'v' 'l' 'r'] 'vv' 'kk' [0] [cons cons dipd] . cons cons cons infra
['k' 'v' 'l' 'r'] 'vv' 'kk' [[0] cons cons dipd] . cons cons infra
['k' 'v' 'l' 'r'] 'vv' ['kk' [0] cons cons dipd] . cons infra
['k' 'v' 'l' 'r'] ['vv' 'kk' [0] cons cons dipd] . infra
'r' 'l' 'v' 'k' . 'vv' 'kk' [0] cons cons dipd [] swaack
'r' 'l' 'v' 'k' 'vv' . 'kk' [0] cons cons dipd [] swaack
'r' 'l' 'v' 'k' 'vv' 'kk' . [0] cons cons dipd [] swaack
'r' 'l' 'v' 'k' 'vv' 'kk' [0] . cons cons dipd [] swaack
'r' 'l' 'v' 'k' 'vv' ['kk' 0] . cons dipd [] swaack
'r' 'l' 'v' 'k' ['vv' 'kk' 0] . dipd [] swaack
'r' 'l' . 'vv' 'kk' 0 'v' 'k' [] swaack
'r' 'l' 'vv' . 'kk' 0 'v' 'k' [] swaack
'r' 'l' 'vv' 'kk' . 0 'v' 'k' [] swaack
'r' 'l' 'vv' 'kk' 0 . 'v' 'k' [] swaack
'r' 'l' 'vv' 'kk' 0 'v' . 'k' [] swaack
'r' 'l' 'vv' 'kk' 0 'v' 'k' . [] swaack
'r' 'l' 'vv' 'kk' 0 'v' 'k' [] . swaack
['k' 'v' 0 'kk' 'vv' 'l' 'r'] .
In [16]:
define('Ee == pop swap roll< rest rest cons cons')In [17]:
V('["k" "v" "l" "r"] "vv" "k" [0] Ee') . ['k' 'v' 'l' 'r'] 'vv' 'k' [0] Ee
['k' 'v' 'l' 'r'] . 'vv' 'k' [0] Ee
['k' 'v' 'l' 'r'] 'vv' . 'k' [0] Ee
['k' 'v' 'l' 'r'] 'vv' 'k' . [0] Ee
['k' 'v' 'l' 'r'] 'vv' 'k' [0] . Ee
['k' 'v' 'l' 'r'] 'vv' 'k' [0] . pop swap roll< rest rest cons cons
['k' 'v' 'l' 'r'] 'vv' 'k' . swap roll< rest rest cons cons
['k' 'v' 'l' 'r'] 'k' 'vv' . roll< rest rest cons cons
'k' 'vv' ['k' 'v' 'l' 'r'] . rest rest cons cons
'k' 'vv' ['v' 'l' 'r'] . rest cons cons
'k' 'vv' ['l' 'r'] . cons cons
'k' ['vv' 'l' 'r'] . cons
['k' 'vv' 'l' 'r'] .
In [18]:
define('E == [P <] [Te] [Ee] ifte')In [19]:
define('BTree-add == [popop not] [[pop] dipd BTree-new] [] [[P >] [T] [E] ifte] genrec')In [20]:
J('[] 23 "b" BTree-add') # Initial['b' 23 [] []]
In [21]:
J('["b" 23 [] []] 88 "c" BTree-add') # Less than['b' 23 [] ['c' 88 [] []]]
In [22]:
J('["b" 23 [] []] 88 "a" BTree-add') # Greater than['b' 23 ['a' 88 [] []] []]
In [23]:
J('["b" 23 [] []] 88 "b" BTree-add') # Equal to['b' 88 [] []]
In [24]:
J('[] 23 "a" BTree-add 88 "b" BTree-add 44 "c" BTree-add') # Series.['a' 23 [] ['b' 88 [] ['c' 44 [] []]]]
In [25]:
J('[] [3 9 5 2 8 6 7 8 4] [0 swap BTree-add] step')[3 0 [2 0 [] []] [9 0 [5 0 [4 0 [] []] [8 0 [6 0 [] [7 0 [] []]] []]] []]]
In [26]:
define('to_set == [] swap [0 swap BTree-add] step')In [27]:
J('[3 9 5 2 8 6 7 8 4] to_set')[3 0 [2 0 [] []] [9 0 [5 0 [4 0 [] []] [8 0 [6 0 [] [7 0 [] []]] []]] []]]
In [28]:
define('unique == [to_set [first] BTree-iter] cons run')In [29]:
J('[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique') # Filter duplicate items.[7 6 8 4 5 9 2 3]
In [11]:
from joy.library import FunctionWrapper
from joy.utils.stack import pushback
from notebook_preamble import D
@FunctionWrapper
def cmp_(stack, expression, dictionary):
'''
cmp takes two values and three quoted programs on the stack and runs
one of the three depending on the results of comparing the two values:
a b [G] [E] [L] cmp
------------------------- a > b
G
a b [G] [E] [L] cmp
------------------------- a = b
E
a b [G] [E] [L] cmp
------------------------- a < b
L
'''
L, (E, (G, (b, (a, stack)))) = stack
expression = pushback(G if a > b else L if a < b else E, expression)
return stack, expression, dictionary
D['cmp'] = cmp_In [14]:
from joy.library import FunctionWrapper, S_ifte
@FunctionWrapper
def cond(stack, expression, dictionary):
'''
like a case statement; works by rewriting into a chain of ifte.
[..[[Bi] Ti]..[D]] -> ...
[[[B0] T0] [[B1] T1] [D]] cond
-----------------------------------------
[B0] [T0] [[B1] [T1] [D] ifte] ifte
'''
conditions, stack = stack
if conditions:
expression = _cond(conditions, expression)
try:
# Attempt to preload the args to first ifte.
(P, (T, (E, expression))) = expression
except ValueError:
# If, for any reason, the argument to cond should happen to contain
# only the default clause then this optimization will fail.
pass
else:
stack = (E, (T, (P, stack)))
return stack, expression, dictionary
def _cond(conditions, expression):
(clause, rest) = conditions
if not rest: # clause is [D]
return clause
P, T = clause
return (P, (T, (_cond(rest, ()), (S_ifte, expression))))
D['cond'] = condIn [31]:
J("1 0 ['G'] ['E'] ['L'] cmp")'G'
In [32]:
J("1 1 ['G'] ['E'] ['L'] cmp")'E'
In [33]:
J("0 1 ['G'] ['E'] ['L'] cmp")'L'
In [34]:
from joy.library import DefinitionWrapper
DefinitionWrapper.add_definitions('''
P == over [popop popop first] nullary
T> == [cons cons dipdd] cons cons cons infra
T< == [cons cons dipd] cons cons cons infra
E == pop swap roll< rest rest cons cons
BTree-add == [popop not] [[pop] dipd BTree-new] [] [P [T>] [E] [T<] cmp] genrec
''', D)In [35]:
J('[] 23 "b" BTree-add') # Initial['b' 23 [] []]
In [36]:
J('["b" 23 [] []] 88 "c" BTree-add') # Less than['b' 23 [] ['c' 88 [] []]]
In [37]:
J('["b" 23 [] []] 88 "a" BTree-add') # Greater than['b' 23 ['a' 88 [] []] []]
In [38]:
J('["b" 23 [] []] 88 "b" BTree-add') # Equal to['b' 88 [] []]
In [39]:
J('[] 23 "a" BTree-add 88 "b" BTree-add 44 "c" BTree-add') # Series.['a' 23 [] ['b' 88 [] ['c' 44 [] []]]]
In [40]:
define('BTree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')In [41]:
J('[3 9 5 2 8 6 7 8 4] to_set BTree-iter-order')2 3 4 5 6 7 8 9
In [42]:
# I don't want to deal with name conflicts with the above so I'm inlining everything here.
# The original Joy system has "hide" which is a meta-command which allows you to use named
# definitions that are only in scope for a given definition. I don't want to implement
# that (yet) so...
define('''
BTree-get == [pop not] swap [] [
over [pop popop first] nullary
[[rest rest rest first] dipd i]
[popop second]
[[third] dipd i]
cmp
] genrec
''')In [43]:
J('[] "gary" [popop "err"] BTree-get')'err'
In [44]:
J('["gary" 23 [] []] "gary" [popop "err"] BTree-get')23
In [45]:
J('''
[] [[0 'a'] [1 'b'] [2 'c']] [i BTree-add] step
'c' [popop 'not found'] BTree-get
''')2
Warning:
Output truncated. This notebook contains too many cells to display efficiently.