Function Reference¶
joy.library
¶
This module contains the Joy function infrastructure and a library of functions. Its main export is a Python function initialize() that returns a dictionary of Joy functions suitable for use with the joy() function.
-
joy.library.
BinaryBuiltinWrapper
(f)[source]¶ Wrap functions that take two arguments and return a single result.
-
class
joy.library.
DefinitionWrapper
(name, body_text, doc=None)[source]¶ Provide implementation of defined functions, and some helper methods.
-
classmethod
add_def
(definition, dictionary, fail_fails=False)[source]¶ Add the definition to the dictionary.
-
classmethod
-
joy.library.
UnaryBuiltinWrapper
(f)[source]¶ Wrap functions that take one argument and return a single result.
-
joy.library.
add_aliases
(D, A)[source]¶ Given a dict and a iterable of (name, [alias, …]) pairs, create additional entries in the dict mapping each alias to the named function if it’s in the dict. Aliases for functions not in the dict are ignored.
-
joy.library.
app1
(S, expression, dictionary)[source]¶ Given a quoted program on TOS and anything as the second stack item run the program and replace the two args with the first result of the program.
... x [Q] . app1 ----------------------------------- ... [x ...] [Q] . infra first
-
joy.library.
app2
(S, expression, dictionary)[source]¶ Like app1 with two items.
... y x [Q] . app2 ----------------------------------- ... [y ...] [Q] . infra first [x ...] [Q] infra first
-
joy.library.
app3
(S, expression, dictionary)[source]¶ Like app1 with three items.
... z y x [Q] . app3 ----------------------------------- ... [z ...] [Q] . infra first [y ...] [Q] infra first [x ...] [Q] infra first
-
joy.library.
b
(stack, expression, dictionary)[source]¶ b == [i] dip i ... [P] [Q] b == ... [P] i [Q] i ... [P] [Q] b == ... P Q
-
joy.library.
branch
(stack, expression, dictionary)[source]¶ Use a Boolean value to select one of two quoted programs to run.
branch == roll< choice i
False [F] [T] branch -------------------------- F True [F] [T] branch ------------------------- T
-
joy.library.
choice
(stack, expression, dictionary)[source]¶ Use a Boolean value to select one of two items.
A B False choice ---------------------- A A B True choice --------------------- B
Currently Python semantics are used to evaluate the “truthiness” of the Boolean value (so empty string, zero, etc. are counted as false, etc.)
-
joy.library.
clear
(stack, expression, dictionary)[source]¶ Clear everything from the stack.
clear == stack [pop stack] loop ... clear ---------------
-
joy.library.
cmp_
(stack, expression, dictionary)[source]¶ 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
-
joy.library.
concat_
(stack, expression, dictionary)[source]¶ Concatinate the two lists on the top of the stack.
[a b c] [d e f] concat ---------------------------- [a b c d e f]
-
joy.library.
cond
(stack, expression, dictionary)[source]¶ This combinator works like a case statement. It expects a single quote on the stack that must contain zero or more condition quotes and a default quote. Each condition clause should contain a quoted predicate followed by the function expression to run if that predicate returns true. If no predicates return true the default function runs.
It works by rewriting into a chain of nested ifte expressions, e.g.:
[[[B0] T0] [[B1] T1] [D]] cond ----------------------------------------- [B0] [T0] [[B1] [T1] [D] ifte] ifte
-
joy.library.
dip
(stack, expression, dictionary)[source]¶ The dip combinator expects a quoted program on the stack and below it some item, it hoists the item into the expression and runs the program on the rest of the stack.
... x [Q] dip ------------------- ... Q x
-
joy.library.
dipd
(S, expression, dictionary)[source]¶ Like dip but expects two items.
... y x [Q] dip --------------------- ... Q y x
-
joy.library.
dipdd
(S, expression, dictionary)[source]¶ Like dip but expects three items.
... z y x [Q] dip ----------------------- ... Q z y x
-
joy.library.
disenstacken
(stack, expression, dictionary)[source]¶ The disenstacken operator expects a list on top of the stack and makes that the stack discarding the rest of the stack.
-
joy.library.
divmod_
(stack, expression, dictionary)[source]¶ divmod(x, y) -> (quotient, remainder)
Return the tuple (x//y, x%y). Invariant: div*y + mod == x.
-
joy.library.
drop
(stack, expression, dictionary)[source]¶ drop == [rest] times
Expects an integer and a quote on the stack and returns the quote with n items removed off the top.
[a b c d] 2 drop ---------------------- [c d]
Stack effect:
([...0] i1 -- [...1])
-
joy.library.
dupdip
(stack, expression, dictionary)[source]¶ [F] dupdip == dup [F] dip ... a [F] dupdip ... a dup [F] dip ... a a [F] dip ... a F a
-
joy.library.
floor
(x)[source]¶ Return the floor of x as a float. This is the largest integral value <= x.
-
joy.library.
genrec
(stack, expression, dictionary)[source]¶ General Recursion Combinator.
[if] [then] [rec1] [rec2] genrec --------------------------------------------------------------------- [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun: “The genrec combinator takes four program parameters in addition to whatever data parameters it needs. Fourth from the top is an if-part, followed by a then-part. If the if-part yields true, then the then-part is executed and the combinator terminates. The other two parameters are the rec1-part and the rec2-part. If the if-part yields false, the rec1-part is executed. Following that the four program parameters and the combinator are again pushed onto the stack bundled up in a quoted form. Then the rec2-part is executed, where it will find the bundled form. Typically it will then execute the bundled form, either with i or with app2, or some other combinator.”
The way to design one of these is to fix your base case [then] and the test [if], and then treat rec1 and rec2 as an else-part “sandwiching” a quotation of the whole function.
For example, given a (general recursive) function ‘F’:
F == [I] [T] [R1] [R2] genrec
If the [I] if-part fails you must derive R1 and R2 from:
... R1 [F] R2
Just set the stack arguments in front, and figure out what R1 and R2 have to do to apply the quoted [F] in the proper way. In effect, the genrec combinator turns into an ifte combinator with a quoted copy of the original definition in the else-part:
F == [I] [T] [R1] [R2] genrec == [I] [T] [R1 [F] R2] ifte
Primitive recursive functions are those where R2 == i.
P == [I] [T] [R] tailrec == [I] [T] [R [P] i] ifte == [I] [T] [R P] ifte
-
joy.library.
getitem
(stack, expression, dictionary)[source]¶ getitem == drop first
Expects an integer and a quote on the stack and returns the item at the nth position in the quote counting from 0.
[a b c d] 0 getitem ------------------------- a
Stack effect:
([...0] i1 -- a1)
-
joy.library.
help_
(S, expression, dictionary)[source]¶ Accepts a quoted symbol on the top of the stack and prints its docs.
-
joy.library.
i
(stack, expression, dictionary)[source]¶ The i combinator expects a quoted program on the stack and unpacks it onto the pending expression for evaluation.
[Q] i ----------- Q
-
joy.library.
infer_
(stack, expression, dictionary)[source]¶ Attempt to infer the stack effect of a Joy expression.
-
joy.library.
infra
(stack, expression, dictionary)[source]¶ Accept a quoted program and a list on the stack and run the program with the list as its stack. Does not affect the rest of the stack.
... [a b c] [Q] . infra ----------------------------- c b a . Q [...] swaack
-
joy.library.
inscribe
(function)[source]¶ A decorator to inscribe functions into the default dictionary.
-
joy.library.
inscribe_
(stack, expression, dictionary)[source]¶ Create a new Joy function definition in the Joy dictionary. A definition is given as a string with a name followed by a double equal sign then one or more Joy functions, the body. for example:
sqr == dup mulIf you want the definition to persist over restarts, enter it into the definitions.txt resource.
Stack effect:
(t1 --)
-
joy.library.
loop
(stack, expression, dictionary)[source]¶ Basic loop combinator.
... True [Q] loop ----------------------- ... Q [Q] loop ... False [Q] loop ------------------------ ...
-
joy.library.
map_
(S, expression, dictionary)[source]¶ Run the quoted program on TOS on the items in the list under it, push a new list with the results in place of the program and original list.
-
joy.library.
max_
(stack, expression, dictionary)[source]¶ Given a list find the maximum. Stack effect:
([n2* ...1] -- n0)
-
joy.library.
min_
(stack, expression, dictionary)[source]¶ Given a list find the minimum. Stack effect:
([n2* ...1] -- n0)
-
joy.library.
parse
(stack, expression, dictionary)[source]¶ Parse the string on the stack to a Joy expression.
-
joy.library.
primrec
(stack, expression, dictionary)[source]¶ From the “Overview of the language JOY”:
> The primrec combinator expects two quoted programs in addition to a data parameter. For an integer data parameter it works like this: If the data parameter is zero, then the first quotation has to produce the value to be returned. If the data parameter is positive then the second has to combine the data parameter with the result of applying the function to its predecessor.
5 [1] [*] primrec
> Then primrec tests whether the top element on the stack (initially the 5) is equal to zero. If it is, it pops it off and executes one of the quotations, the [1] which leaves 1 on the stack as the result. Otherwise it pushes a decremented copy of the top element and recurses. On the way back from the recursion it uses the other quotation, [*], to multiply what is now a factorial on top of the stack by the second element on the stack.
n [Base] [Recur] primrec0 [Base] [Recur] primrec
Basen [Base] [Recur] primrec
- —————————————— n > 0
- n (n-1) [Base] [Recur] primrec Recur
-
joy.library.
remove
(stack, expression, dictionary)[source]¶ Expects an item on the stack and a quote under it and removes that item from the the quote. The item is only removed once.
[1 2 3 1] 1 remove ------------------------ [2 3 1]
-
joy.library.
reverse
(stack, expression, dictionary)[source]¶ Reverse the list on the top of the stack.
reverse == [] swap shunt
-
joy.library.
select
(stack, expression, dictionary)[source]¶ Use a Boolean value to select one of two items from a sequence.
[A B] False select ------------------------ A [A B] True select ----------------------- B
The sequence can contain more than two items but not fewer. Currently Python semantics are used to evaluate the “truthiness” of the Boolean value (so empty string, zero, etc. are counted as false, etc.)
-
joy.library.
shunt
(stack, expression, dictionary)[source]¶ Like concat but reverses the top list into the second.
shunt == [swons] step == reverse swap concat [a b c] [d e f] shunt --------------------------- [f e d a b c]
-
joy.library.
sqrt
(a)[source]¶ Return the square root of the number a. Negative numbers return complex roots.
-
joy.library.
step
(S, expression, dictionary)[source]¶ Run a quoted program on each item in a sequence.
... [] [Q] . step ----------------------- ... . ... [a] [Q] . step ------------------------ ... a . Q ... [a b c] [Q] . step ---------------------------------------- ... a . Q [b c] [Q] step
The step combinator executes the quotation on each member of the list on top of the stack.
-
joy.library.
sum_
(stack, expression, dictionary)[source]¶ Given a quoted sequence of numbers return the sum.
sum == 0 swap [+] stepStack effect:
([n2* ...1] -- n0)
-
joy.library.
take
(stack, expression, dictionary)[source]¶ Expects an integer and a quote on the stack and returns the quote with just the top n items in reverse order (because that’s easier and you can use reverse if needed.)
[a b c d] 2 take ---------------------- [b a]
Stack effect:
([...0] i1 -- [...1])
-
joy.library.
times
(stack, expression, dictionary)[source]¶ times == [– dip] cons [swap] infra [0 >] swap while pop
... n [Q] . times --------------------- w/ n <= 0 ... . ... 1 [Q] . times --------------------------------- ... . Q ... n [Q] . times --------------------------------- w/ n > 1 ... . Q (n - 1) [Q] times
-
joy.library.
void
(stack, expression, dictionary)[source]¶ True if the form on TOS is void otherwise False.
-
joy.library.
words
(stack, expression, dictionary)[source]¶ Print all the words in alphabetical order.
-
joy.library.
x
(stack, expression, dictionary)[source]¶ x == dup i ... [Q] x = ... [Q] dup i ... [Q] x = ... [Q] [Q] i ... [Q] x = ... [Q] Q