Basic evaluation
Let us see how MeTTa turns one expression into another. The whole language is built on a single idea: an expression is reduced by applying equality rules until none apply.
Programs are atoms
A script is parsed atom by atom into the space. An atom on its own is stored; an atom with ! is evaluated and its result printed. Here both happen:
(+ 1 2) reduces to 3 because + is a grounded operation that runs on its arguments. But (Hi there) reduces to itself: Hi is just a symbol, not an operation, so there is nothing to run. A bare symbol heading an expression behaves like a data constructor, the way Cons does in a functional language. This is why facts like (Likes Alice Pizza) are values, not computations.
Equalities are your functions
To make an expression reduce to something other than itself, define an equality with =:
(= (greet) (Hello World)) says "(greet) can be reduced to (Hello World)". Equalities look like function definitions, but they differ in important ways.
They need not be total. A rule can match only some inputs, and an unmatched call is simply left alone:
There is no error for (only-a B); it is just a value the interpreter could not reduce. In MeTTa there is no hard line between a function and a data constructor.
Order matters relative to definition. A call is reduced using the rules that exist at that point in the program:
Parameters and patterns
Rules take variables, and the bound values are substituted into the right-hand side:
The left-hand side can have structure, so you get pattern matching for free:
It is more general than functional-language matching, because the pattern can be any shape, and a variable may even repeat. A repeated variable only matches when both positions are equal:
Several results
A head can have more than one rule, and they are not mutually exclusive. Evaluation is nondeterministic: every applicable rule contributes a result.
This even applies when a specific rule and a general rule both match:
Evaluation keeps going
A result is reduced further, for both symbolic and grounded steps:
Arguments are normally evaluated before the call, just like in most languages:
That is the whole evaluation model: match a rule, substitute, reduce the result, repeat. Next we use it for repetition and choices: Recursion and control.