Picture from instagram via midjourney.
If you find Scheme boring, without creativity, and dare challenge without fear the gentle, hot and firm burn of minimalism^W barely understood devices such as procedural pattern matching,
vau, and statistics gathered on-the-fly to configure lowering at runtime that may be wholly, and fully localized, user defined, packaged, and re-used1.
Even if those are readily source available by your favorite brute force army. There is a parenthetical take: Kernel, and Futamura. Read on.
Kernel is the other programming interface that I can not take my mind away from. I tried. I failed. I failed many times. I failed Babelia because Kernel. I worked hard. I failed. I still dare recalling my failure. And nowadays, I do not shy away anymore. I dare claim it is not only elegant, it is beautiful. It takes more head space than any other language, standard, or (parenthetical leaning) implementation. It seems to me there is enough material for one to beam gamma rays to alphas for inspiration for decades, maybe centuries!
The primo, and ultimo goal: control a little more than Sun core.
Previously I called the following John Shutt’s equation of software. To keep any error my own, and because it goes against the grain, I intend to not mention him outside reference, and thanks. May his arguments always be properly evaluated.
The purpose of that equation is to describe enough of a system, and deliver enough material to support engineered discourse. Here are the three branches of seed’s
define (eval xp env ctx) (cond (;; If the expression `XP` is a symbol, return the object that is ;; associated with it in the environement `ENV`... symbol? xp) (environment-ref env xp)) ((;; If `XP` is a construction, try to apply it pair? xp) ((define combiner (let ((prefix (car xp))) (if (combiner? prefix) ( prefix (environment-ref env prefix))))cond ;; Most likely combiner class, what is returned by lambda ( ((applicative? combiner);; Evaluate arguments `(cdr XP)`, hopfully mere environement-ref. let ((xp+ (map (lambda (x) (eval x env ctx)) (cdr xp)))) ( (apply combiner env ctx xp+))) ((operative? combiner);; The arguments `(cdr XP)` are passed as is, most likely, but ;; not only: symbols, numbers, booleans, and constructions... cdr xp)))) (apply combiner env ctx (;; ... not only self-evaluating! else xp))) (
ctx hold the current flow of execution, to make it possible to migrate across hardware frontiers.
Download the small demo at hyper.dev.
Combiners returned by
vau make it possible, and easy to hook into compilation machinery, that is without more time spent on a wood bank.
Here is the
define when ( (vau (object . xps) envif (eval object env) (eval (list* sequence xps) env) ( (void))))
Mind the fact that it works better if you do not know what a macro is, what compilation hooks are, and when you are not parenthetical phobic. Some familiarity with Scheme standard, R4RS, or R5RS helps.
It can be used like:
(when signal2006)) (reply
At somepoint, the previous procedure definition of
when will be called. Using beta-reduction, and the fact that only
replay are lexically scoped:
if (eval 'signal env) (eval (list* sequence (list 'reply 2006)) env) ( (void)
xps were copy-pasted as a construction, and self-evaluating objects like symbols. In
env, the symbols
'reply are bound. When
(eval 'signal env) is processed, it returns for instance 101. That yields the following sequence:
if 101 ;; that is not flasy (eval (list* sequence (list 'reply 2006)) env) ( (void)
eval (list* sequence (list 'reply 2006)) env)(
That is evaluated at call-site to the same object as the following expression:
when will bind the condition, called
object in the above definition, to a variable inside the body. That is similar to walrus operator. An anaphoric
when can be implemented with:
define anaphoric-when ( (vau (variable object . xps) envdefine tmp (eval object env)) (if tmp (eval (list* sequence xps) (list (cons variable tmp)))) (environment-cons env ( (void))))
It is supposed to be used in cases where the test condition is cpu heavy:
+ 2006 (- 1337 42)) (anaphoric-when signal ( (reply signal))
when, the use of anaphoric when is mostly lexically scoped. The applicative
eval takes an environment as argument. The definition of
anaphoric-when needs the object associated with the symbol
anaphoric-when is used, hence the first line
(define tmp (eval object env)) where
ENV is the environment where
anaphoric-when is used.
The main difference between
anaphoric-when is that anaphoric adds the condition object inside the environment where the body of
anaphoric-when is evaluated.
Again, describing a beta-reduction sequence:
define tmp (eval (list '+ 2006 (list '- 1337 42)) env)) (if tmp (eval (list* sequence (list 'reply 'signal)) (list (cons 'signal tmp)))) (environment-cons env ( (void))
define tmp 3301) (if tmp (eval (list* sequence (list 'reply 'signal)) (list (cons 'signal tmp)))) (environment-cons env ( (void))
if 3301 ;; not falsy (eval (list* sequence (list 'reply 'signal)) (list (cons 'signal 3301)))) (environment-cons env ( (void))
eval (list* sequence (list 'reply 'signal)) (list (cons 'signal 3301)))) (environment-cons env (
That is echo.
define-macro, and even more so hygienic syntax transformers, the approach of f-expr using
vau makes it possible to re-use existing knowledge of how to program. It may be possible to re-implement the industrial macro machinery of modern implementations, but do we really want that?
I will write a procedural match ie. a pattern matcher, then see where to go from there. I think publicly distributed, and localized code are more helpful, than any other projections.
By the way, while I am at looking forward, take a look at GRASP, The GRAphical Scheme Programming Environment, look at the videos. I also recommend the answers by the same author on quora.
Regarding Futamura projection, it appears it is still interesting, and good material to build a new implementation of Scheme. After reading pebook, it is certain that it is a lot of work.
may be known as up-coming long awaited next AAA release.↩︎