2024-06-17 11:47:11

I'd read a little about lambda-calculus before, but never took
the plunge and actually try it out by hand until yesterday, as I
stumbled upon a recommended video by Eyesomorphism. I paused the
video after the definitions for booleans and "if" was revealed,
and decided to try it out myself, as I couldn't believe such a
simple implementation could work in some a seemingly primitive
language!

At first, I went with Python lambdas, as with what's demo'ed in
the video.

   true  = lambda: x lambda: y: x
   false = lambda: x lambda: y: y
   ift   = lambda: b lambda: x: lambda y: b(x)(y)

I couldn't really make sense of it, for some reason. I wanted to
take a look at the intermediate lambdas, particularly b(x), so I
decided to go with a Lisp. Naturally, my guilt with spending time
away from emacs got the best of me and I went with Elisp.

I eventually grasped how it worked, and I decided to write
full-blown notes on lambda-calculus as I explored it in the form
of a exploration-driven tutorial.

PS - writing the Python implementation now, after being familiar
with how multiple arguments are implemented, I immediately
recognized the b(x)(y) as passing x and y to b. And now I now,
the conditional branching actually took place in true and false!
I was oblivious to the names x and y that matched the parameters
of true and false...

As of now, I have covered boolean operators, numbers, arithmetic
operations, as well as helper functions that allowed me to define
and call functions with multiple arguments with a little less
parentheses. :P

I kept discovering parallels of it and functional programming
(particularly the ML's syntax of multiple arguments, and how
arithmetic operation functions are defined similar to how we'd
use map and reduce), as well as Lisps.

Still, as someone who started their programming journey with C
and C-like languages, I naturally find C-like syntax easier to
debug, despite Emacs's electric bracket pair highlighting. I am
still on my way of fully appreciating FP/ML and Lisps. I'll get
there, I hope so and I'm also sure of it.

The tutorial which I've saved locally as a single file named
lambda-calculus.el is fully driven by eval-region, C-x C-e, and
eval-buffer. 'emacs -nw -Q' is my only IDE. The only
customization I have is a few file-local variables that sets
lexical-bindings (apparently lambda-calculus requires closures,
which is actually non-trivial), fill-column, ruler-mode and the
Modus Vivendi theme (Tutorial prose is written in comments, a
high-contrast theme is essential).

dir-locals.el in full (together with a command that lets me
insert the date at the top of each phlog)

((nil . ((fill-column . 65)
        (eval . (ruler-mode))
        (eval . (auto-save-visited-mode))
        (eval . (auto-fill-mode))
        (eval . (defun date ()
                  (interactive)
                  (insert (shell-command-to-string
                                       "date '+%Y-%m-%d %T'"))
                  (join-line)))
        (eval . (load-theme 'modus-vivendi t)))))

(Yes, I am now sticking to dir & file-locals in place of my
emacs!)

With regards to emacs, I was surprised to find that I *never*
accidentally typed in Vim keys, *at all* (I don't have the mouse
enabled either, which, admittedly, I do use for large jumps in
navigation sometimes in vim). With emacs keys so ubiquitous in
input fields everywhere even beyond the terminal, I've gotten
quite used to it and if I were to guess, my productivity with
emacs keys as of now is as much as about 90% of that of Vim!
(Another factor, possibly is my spam-testing of my TUI input
forms which I've had to implement and re-implement in over 5
languages as part of my todomvc-tui project).

I've found C-x C-q extremely useful as someone too accustomed to
browsing things in Vim normal mode. I currently have an
uncommitted change in my dotfiles that removes evil mode
completely from my canonical emacs config. After the experience
yesterday and today, (and yes, it's annoying to 'C-u -1 C-l' or
'C-u 0 C-l' instead of just zb/zt in Vim, I am seriously
considering making the eradiaction of evil perminent -- burn it
with fire~).

Of course, I'm now phlogging with 'emacs -nw -Q' with a few
dir-locals -- fill-column, ruler-mode, auto-fill-column,
auto-save, and the Modus Vivendi theme.

Back to lambda-calculus, I found the idea of Church Numerals
ingenious and very much like the reduce function in FP. To
convert a number from LC into Elisp I simply do:

 (: n (:L (x) (1+ x)) 0)

Where `:` is a shortcut for `funcall` which allows LC's multiple
arguments, `:L` is a shortcut for `lambda`, `n` is the LC number
and the sexp's return value is an elisp number!

The beauty of doing this in elisp is that I can define new things
in the file then have it be usable *immediately*, *without
leaving/reopening the file* by simply overriding the previous
definition of it or just evaluate the new thing with C-x C-e.

I also get parameter hints that shows up in the minibuffer for
*my own* helper functions as well as LC functions for free,
without needing an LSP.