Skip to content

Latest commit

 

History

History
125 lines (75 loc) · 3.37 KB

File metadata and controls

125 lines (75 loc) · 3.37 KB

The STCK 2.0 Standard Library

Stck.Console handles loading of external STCK-code. You could e.g. load the standard library by using:

load Stck/stdlib.stck

Derived stack operators

rot -> [[] swap << swap << swap >> app] rot #

over -> [swap dup rot rot] over #

2dup -> [over over] 2dup #

Booleans

Booleans uses the classic lambda calculus encoding.

true = λa . λb . a / false = λa . λb . b

true -> [[.]] true #

false -> [[swap .]] false #

From there we can define boolean operators.

if = λp . λt . λe . p t e

if -> [rot app app] ? #

not -> [false true rot app] not #

and -> [dup app] and #

or -> [not swap not and not] or #

xor -> [2dup not swap not and rot rot and or not] xor #

We can compare booleans with implication and equivalence.

Left implication -> [not or] <- #

Right implication -> [swap <-] -> #

Equivalence -> [2dup -> rot rot <- and] <-> #

Math operations

Numerals is also encoded using Church encoding. We start with the successor function.

successor = (n) -> (f) -> (x) -> f(n(f)(x))

pick -> [swap dup rot swap ||] pick # succ -> [| [pick] rot || ||] succ #

Then we can define some numbers.

  1. [[[.] app]] 0 #
  2. [0 succ] 1 #
  3. [1 succ] 2 #
  4. [2 succ] 3 #
  5. [3 succ] 4 #
  6. [4 succ] 5 #
  7. [5 succ] 6 #
  8. [6 succ] 7 #
  9. [7 succ] 8 #
  10. [8 succ] 9 #
  11. [9 succ] 10 #
  12. [10 10 *] 100 #
  13. [100 10 *] 1000 #
  14. [1000 1000 *] 1M #

We can multiply and add the numbers together.

multiplication -> [[swap rot swap [app] swap << swap << swap app] swap << swap <<] * #

addition -> [[app] swap << swap [app] swap << [rot dup rot swap << rot rot << || app] swap << swap <<] + #

Then for the tricky part, defining the predecessor function. The general ide is to group together a number and boolean.

pred-first -> [0 false] pred-first #

Then you want a function that increments the number so it's one less than the number of times the function has been called. It goes something like this:

  1. pred-first -> 0 false
  2. pred-first pred-next -> 0 true
  3. pred-first pred-next pred-next -> 1 true
  4. ...

pred-next -> [[succ true] [true] ?] pred-next #

Now we can construct the predecessor function by applying the number to pred-first and pred-next, and then drop the boolean at the end.

pred -> [pred-first rot [pred-next] swap app .] pred #

With a predecessor function we can define subtraction.

subtraction -> [[pred] swap app] - #

We might also want some predicates to convert numbers to booleans.

is-zero -> [true [. false] rot app] is-zero #

less-or-equal -> [swap - is-zero] <= #

greater-or-equal -> [- is-zero] >= #

equal -> [2dup >= rot rot <= and] = #

Finally we can make a remainder/modulo operation.

remainder -> [2dup <= [dup rot swap - swap %] [.] ?] % #

Operators currently in beta

You should probably not use these operators before they're out of beta...

error -> [err app] error #

empty -> [emp app] empty #

clear -> [empty [] [. clear] ?] clear #