Clue (oklopol)


 * You may be looking for the other language named Clue (by Keymaker).

Clue is a programming language created by User:oklopol based on the example-driven programming paradigm. In Clue, ":" and ".." actually mean the same thing, and similarly, in all the dot commands, only the number of dots altogether in a string of '.' 's and ':' 's matters!

Syntax
A Clue program is a set of function clues. Each clue is compiled to a function based on the examples and the usable function given. There are bag commands and example commands, and each function can have any amount of each type. If "clue function" is the clue function being clued, a bag command is of the form

clue function ~ helper 1; helper 2; ...; helper n

where helpers can be either names of helper functions or clue objects (defined later).

Example functions come in two forms, base examples and recursion examples. The general form of a base example is

clue function ~ {. inputs 1 -> output 1 . inputs 2 -> output 2 ...                . inputs n -> output n }

The general form of a recursion example is

clue function ~ {:. inputs 1 -> output 1 : subinputs 1.1 -> suboutput 1.1 ...                 : subinputs 1.k -> suboutput 1.k                 ... :. inputs n -> output n                 : subinputs n.1 -> suboutput n.1 ...                 : subinputs n.k -> suboutput n.k }

All inputs in example commands are a whitespace separated list of clue objects. Within one example, all these lists should be of the same length (the length being the arity of the function being defined).

There are two types of objects in clue, lists and integers. List elements are written betweem []-brackets, whitespace separated, numbers are given in the obvious way.

The precise details of the syntax are not known.

starts a comment, the rest of the line is simply ignored.

Semantics
Each function clue is compiled into a function. The function will use only the helper functions and helper objects listed in the bag of that function clue. All clue functions have a single branching function (made out of the contents of the bag) whose return value, when given the input, determines what function of its input the clue function computes.

Branching
Each example command is a separate logical branch of the function, that is, when a function is executed, a branching function is applied to the inputs, and the result determines the branch taken. Each example command corresponds to a single branch of the function.

Each example command associated with the function has its own code for computing the output from the inputs, and one value of the branching function is associated with each such branch. There can be one default branch without such a value, and this branch is taken by default, if the branching function gives a value not associated with anybranch. The branching function is composed of the functions of the function bag, and it must 1) return the same value for all the example inputs within each example command, except for at most one branch. 2) return different values for inputs of different example branches. It is not specified which such function the compiler infers.

Base example branches
Base examples are compiled into base functions composed of the contents of the bag such that for all inputs given in the example command, the corresponding outputs are returned. Recursion of any kind is not allowed, the dependencies of functions on each other must form a tree (Recursive examples add self-loops in this tree, but mutual recursion is not possible at all). Which such function the example is compiled into is again not specified.

If the function the base branch is associated with is called, and this branch is taken, the base function the example was compiled into is called with the arguments of the original function call as the arguments, and the result of the function call is the result of the base function associated with this branch.

If multiple examples are given in a single example command, the same code should work for all examples.

Recursive example branches
A recursive example
 * . inputs -> output

... : subinputs k -> suboutput k is, similarly to the base example case, compiled into a function that is called if this branch is taken, with the arguments of the original function call. Now, code for turning inputs into outputs is not inferred. Instead, code is inferred for turning inputs into subinputs 1, then inputs and suboutput 1 into subinputs 2, then inputs, suboutput 1 and suboutput 2 into subinputs 3, and so on. Finally, from all the outputs and inputs, output is constructed.

When called, the function the command is compiled to will compute the subinputs as explained before, call itself recursively on the subinputs, and then use inputs and suboutputs to construct the final output. The resulting function might not actually turn "inputs" into "outputs", although it's good programming practise to only write functions with this property (and quite a challenge to write meaningful ones without it).

Again, multiple examples can be given in the same command, and the same code should work for the exact same computations. Once again, as long as the compiled code has the properties explained, and is built from the contents of the bag, it isn't specified what it is.

Running the program
A Clue program cannot actually be executed from within source code, but most Clue compilers allow testing of the compiled functions with user given input.

Examples

 * Quicksort
 * SKI calculus

External resources
A reference implementation for Clue 1.0 is available at vjn.fi, but that language is considered highly obsolete, and nobody should use it. As for a Clue 1.25 implementation, perhaps the kind folk in #esoteric might know.