In part I, we made a hextille grid (file), filled it with symbols, added some more symbols, and made some symbols stand for bitmaps. Finally, we caught a glimpse of a lambda form being added.
From what I can tell so far, lambdas play really well in NicCLIM. Basically for writing computer programs, we would prefer to use the host lisp directly. I am not proposing to have come up with a different good-old-fashioned-ai programming language.
However, lisp lacks something like physical intuition itself (but it is an extremely high level implementation language for authoring different systems which do provoke physical intuition, and I equate physical intuition and game maps). This is like how lambdaMOO (not a lisp program as such) has a certain social magic that lisp does not quite provide but lisp programs can provide.
So this Part II article is about writing lisp as such and yanking (pasting) the lisp into the game map, and then part III later will be physically using the lisp code as an object in the map.
lambda
!I guess you read part I and can recover the position there. As a fun aside, I made a special LAMBDA.PNG
so instead of lambda showing up in the cell, we will have a fetching unix_surrealism graphic.
(setf (get 'life :bitmap) 'imgs/life.png
(get 'empty :bitmap) 'imgs/empty.png
(get 'lambda :bitmap) 'imgs/lambda.png)
(enclose-map 'gol)
In hindsight, let us use smaller and neater lambdas than that one instead, and then in part iii we will macro moving around using them.
Well, we are just writing this off the cuff. Since I can just yank (“paste”) into McCLIM’s interactor, it’s fine that I am just writing the lambda here. Hopefully I can integrate JackDaniel’s new McCLIM accepting-values
editor in the future.
(lambda (f1 f2)
(lambda (x)
(funcall f1 (funcall f2 x))))
I guess this obviously works. Remember that *
(and **
and ***
and +
, ++
, +++
, /
, //
, ///
, and -
have special meanings in interactive lisp useage).
(apply * (list #'1+ #'1+))
(funcall * 0)
⮕
CL-USER> (apply * (list #'1+ #'1+))
#<bytecompiled-closure #<bytecompiled-function 0x7f88d7e2e910>>
CL-USER> (funcall * 0)
2
I actually added the former lambda and the next one.
I did not plan this, but because I allow right-jagged maps, and because lambdas will in general be wider and taller than other cells and the rows and columns dynamically resize, it makes sense to keep the lambdas together sticking out the right-hand-side of the last row, where they can hang out with other lambda-sized-columns and lambda-sized-rows without affecting the rows and cols of the “data” part of the map. This convention makes them somewhat easy to find (try jumping to the expected bottom right of the map).
(lambda (x) (cond ((member 'life x) 1)
(t 0)))
LIFE
(lambda (x)
(with-slots
(cursor-locn table-list)
*application-frame*
(let ((current (nth (cadr cursor-locn)
(nth (car cursor-locn)
table-list))))
(case x
(2 '(empty life))
(3 current)
(4 current)
(t '(empty))))))
(lambda (n &aux (sum 0) (count 0))
(lambda (x)
(prog2
(incf count)
(incf sum x)
(when (= n count)
(setf count 0
sum 0)))))
Okay, slightly forced prog2 useage.
(lambda (fun)
(lambda (&optional (x nil))
(declare (ignore x))
(loop :with dirs := '(e ne n nw w sw s se)
:for dir :in dirs
:for neighbor := (adjacent-peek dir)
:for result := (funcall fun neighbor)
:finally (return result))))
I did not investigate them deeply since we are concentrating on pasting lambdas into NicCLIM maps as an extension to the bottom right corner.
When I make the cell contain the lambda, I get normal looking pretty printed text, but when I make the cell be the lambda, top level symbols of the cell with a :bitmap
property render as the bitmap behind the other symbols instead.
For the context of what buttons I was pressing to do this, inserting a new cell before-here in the row is C-M-n
, rotatef
-the-current-cursor-and-this-cell is M-S-f
, and yank (paste) in the interactor is C-y
, so I was not doing much to get here and the aesthetic should be understood as extremin of effort.
In my opinion, being able to stow lambdas jaggedly off the edge of the bottom-right corner of the physical game map worked out quite serendipitously.
Definitely, some more fine grained control of the current common lisp pretty printing options is probably in order.
It was kind of fun introducing a background image connoting that a lambda is being defined in this cell instead of printing the leading symbol lambda, but basically black text contrast (or control of text properties generally) needs to be available.
Part iii will focus on the map editor macro control of the map, which will involve picking up and using these lambdas while moving around the map.
What do you think? Things got pretty crazy.