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 
Category:Languages
Category:2021
Category:Turing complete
Category:Output only
Category:Implemented