Kiosk

From Esolang
Jump to navigation Jump to search

Kiosk (/kʰio̯sk/) is an esolang created by User:Yayimhere, after wondering if both having (x), be pushing, while also having xyz...(F) be application, was possible in a single language. It works on a lambda calculus "framework", but uses instructions that are more usual for stacks. This mix of imperative and functional programming, combined with the concept itself, leads to a, though elegant, confusing language.

Memory

Kiosk uses a queue(originally called the environment), and a stack. Every time something is pushed to the stack, and item is popped from the front of the queue, and is then fed to the function on the top of the stack. Then, the next item is popped, until the queue is empty. Some items may be marked as "keep" on the queue. When they've been popped, they are moved to the back of the queue, and are counted as popped when doing the iterating process(note that all elements start as "unkept").

Execution

When a program has reached its end, the whole stack is executed by appending each element of it to a new empty program(placing the top of the stack at the end of that chain). This continues until the stack is empty, in which the queue is printed, with the front being printed as the first character. Note that kept characters are ignored when printing

Commands

Kiosk has four commands, aswell as 5 combinators(which will be explained in a bit). These commands are:

  • (x): push x to the top of the stack. must be a list of combinators(this condition is only required when the queue is being used on the pushed element).
  • *: wraps the top of the stack with brackets(the pushing kind). Does not apply to programs.
  • .: toggles the front element of the queue between keep, and unkept.
  • [x]: pushes a program string x onto the stack. The queue is not emptied when this is done.
  • -: pop the front of the queue
  • x: pop the front of the queue and move it to the back

now, we move onto the combinators. These combinators are lambda expressions, and can be passed freely to each other. They are as follows:

  • ": \x. x x
  • ~: \x.\y. y x
  • k: \x.\y. x
  • i: \x.x
  • &: \x.\y.y
  • $: \x.\y.\z.(x z) (y y)

when a combinator appears in the program, it is pushed to the end of the queue. A * is always implied at the end of the program, however not when doing the execution cycling afterwards.

Functions application

As you can see, (x) already pushes to the stack. But how does the xyz...(F) part work? Lets take an example, simply applying i to itself using ":

i(")

after i is ran, the queue has i on it. Then " is pushed to the stack, in which i is passed to it via the cycling rules of the queue. Then, the implied * is ran, pushing the result to the stack again in the second cycle of execution, before finally running it without the surrounding (...), of which it its added to the queue, and printed to the screen.