# Tock

**Tock** is an esolang/model of computation created by User:Silver. The name is because it puts a lot of focus on working in discrete steps, and Tick was taken.

## Overview

There is a collection of functions taking an integer `t`

to a real. These functions can depend on the values that the other functions take for `t-1`

, but not for any other input, so `f(t)`

can be defined in terms of `g(t-1)`

but not `g(t)`

, `g(t-2)`

, `g(t+1)`

or `g(3)`

. Two functions, called `halt`

and `out`

, are special: the output of the program is the value of `out(t)`

for the smallest `t`

such that `halt(t)`

is zero.

## Language

A program is a collection of functions, which must include functions called `halt`

and `out`

. Each function is defined as follows:

[function name] [initial value] { [expression] }

or:

[function name] [initial value] { [condition] : [expression]; [condition] : [expression]; otherwise : [expression] }

A function name can consist of alphabetical characters and underscores only. The initial value is a number.

A condition consists of two expressions related by one of `=`

, `!=`

, `>`

, `<`

, `>=`

or `<=`

. Clauses of a piecewise definition are checked sequentially, the otherwise clause is optional (but the program will throw an error if no clause matches).

An expression is an arithmetical expression using `+`

, `-`

, `*`

, `/`

, `^`

, `%`

and `()`

. It can contain both numbers and the names of other functions. Those names are interpreted as the values of those functions at `t-1`

.

Line comments are permitted using double slashes.

## Examples

The following is a simple program that outputs 10:

halt 10 { halt - 1 } out 0 { out + 1 }

While the following outputs 20:

halt 1 { counter = 10: 0; otherwise: 1 } out 0 { counter * 2 } counter 0 { counter + 1 }

See fractran.tock in the implementation repository linked below for a more involved example.

## Computational Class

**Tock** is Turing Complete, as shown by the existence of the following translation of Fractran:

halt 1 { pointer > [number of fractions]: 0; otherwise: 1; } out 0 { n } mode 0 { (mode + 1) % 4; // modes are: // 0 - load pointed at fraction // 1 - compare fraction to current n // 2 - update n and pointer accordingly // 3 - check if finished } pointer 0 { mode + (10 * current_match) = 12: 0; // return to start mode + (10 * current_match) = 2: pointer + 1; // next fraction otherwise: pointer; } current_fract_numerator 1 { pointer + ([number larger than number of fractions] * mode) = 0: [numerator of first fraction]; pointer + ([number larger than number of fractions] * mode) = 1: [numerator of second fraction]; ... otherwise: current_fract_numerator; } current_fract_denominator 1 { pointer + ([number larger than number of fractions] * mode) = 0: [denominator of first fraction]; pointer + ([number larger than number of fractions] * mode) = 1: [denominator of second fraction]; ... otherwise: current_fract_denominator; } current_match 0 { (n * current_fract_numerator) % current_fract_denominator = 0: 1; otherwise: 0; } n [input to the fractran program] { current_match + ([number larger than the number of fractions] * mode) = ([same large number] * 2) + 1: n * (current_fract_numerator / current_fract_denominator); otherwise: n; }

See fractran.tock in the implementation repository linked below for an example of using this to translate a fractran program.

## Implementation

An implementation exists at [1]