<commit_before>## Introduction

Hof is a new language based on the SKI calculus named after <NAME>.

    Syntax:   Semantics:        Meaning:
    T -> I    λx.x              I combinator from SKI calculus
    T -> K    λx.λy.x           K combinator from SKI calculus
    T -> S    λx.λy.λz.xz(yz)   S combinator from SKI calculus
    T -> V    λv.λx.x           Void combinator ignores v and returns I
    T -> P    λx.x              Print x to stdout

    T -> R    λx.λy.(x|y)       Randomly return either x or y with Bernoulli
                                probability distribution

    T -> A    (T₁T₂)            Form a new term out of the application of
                                terms T₁ and T₂

The interpreter for the language is written in C++ and features lazy evaluations
implemented with memoized thunks.<commit_msg>Update the README to include the new lambda lexer/parser.<commit_after>## Introduction

Hof is a new language based on the SKI calculus named after Douglas Hofstadter.

    Syntax:   Semantics:        Meaning:
    T -> I    λx.x              I combinator from SKI calculus
    T -> K    λx.λy.x           K combinator from SKI calculus
    T -> S    λx.λy.λz.xz(yz)   S combinator from SKI calculus
    T -> V    λv.λx.x           Void combinator ignores v and returns I
    T -> P    λx.x              Print x to stdout

    T -> R    λx.λy.(x|y)       Randomly return either x or y with Bernoulli
                                probability distribution

    T -> A    (T₁T₂)            Form a new term out of the application of
                                terms T₁ and T₂

The interpreter for the language is written in C++ and features lazy evaluations
implemented with memoized thunks.

The interpreter also contains a full Lambda Calculus lexer/parser which
transcompiles the untyped Lambda Calclulus into the SKI calculus, with η-reduction
simplification included, which is then ranscompiled into Hof in turn.

Another feature is verbose mode which shows the full evaluation cycle in
colorized terminal output.  Combined with a good debugger, verbose mode can
reveal the entire combinator application loop by stepping through with
breakpoints in the eval/apply cycle.
{'fraction_non_alphanumeric': 0.04557761732851986, 'fraction_numerical': 0.0, 'mean_word_length': 1.9798387096774193, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1707116', 'n_tokens_mistral': 642, 'n_tokens_neox': 595, 'n_words': 287}