name? - global vars via symbol macros

19 views
Skip to first unread message

Madhu

unread,
Nov 27, 2021, 7:44:16 AM11/27/21
to
For experimental programming I find it easiest to manipulate state in
global variables and refer to them with a $ prefix - as $line.
Typically this state the state would be put into a struct "context"
object to avoid the global environment. Here is a defmacro helper to do
just that

(defun make-def-forms (name vars)
"Return forms that: define a struct named NAME with slots VARS. Define
a global variable of the form *NAME* and initialize it with the
default constructor for the structure. Define symbol macros of the
form $VAR to access each slot VARS in the global variable."
(destructuring-bind (var-name constructor-name acc-names)
(read-from-string
(format nil "(*~(~A~)* make-~(~:*~A~) (~{$~(~A~)~^ ~}))"
name vars))
`(progn
(defstruct ,name ,@vars)
(defvar ,var-name (,constructor-name))
,@(loop for acc-name in acc-names for var in vars
collect `(define-symbol-macro ,acc-name
(slot-value ,var-name ',var))))))



e.g.
(eval (make-def-forms 'ctx '(buffer index)))
(setq $buffer (make-array 10) $index 0)
(setf (elt $buffer (setf $index 1)) 10)
(elt $buffer $index)
(macroexpand-1 '$index)

The question is there a better name than make-def-forms for this
particular "general" functionality, and the associated macro?

also I prefer vars to to be passed in from a list object, and a defmacro
does not help there (unless it is in a global variable).

Madhu

unread,
Nov 30, 2021, 10:16:06 PM11/30/21
to
* Madhu <m3fsrhy...@leonis4.robolove.meer.net> :
Wrote on Sat, 27 Nov 2021 18:14:11 +0530:
No takers? :( I'm going with

(defmacro define-contexted-global-lexicals (context-name &rest vars)
(make-def-forms context-name vars))

(define-contexted-global-lexicals buffer-context buffer buffer-len)

which defines $buffer and $buffer-len

not that i'm happy with it


Zyni Moë

unread,
Dec 1, 2021, 5:44:46 AM12/1/21
to
Madhu <eno...@meer.net> wrote:
> * Madhu <m3fsrhy...@leonis4.robolove.meer.net> :

>
>> For experimental programming I find it easiest to manipulate state in
>> global variables and refer to them with a $ prefix - as $line.
>>

Tim Bradshaw's global lexicals hack
(https://tfeb.github.io/tfeb-lisp-toys/#global-lexical-variables-glex) now
has reader support: you can make it be so that #$x refers to a global
lexical x:

(setf #$x 3)

means that #$x will be 3, and if you then do (defglex x), x will be 3 too,
but x is not bound in the symbol-value sense.

Suspect this is not what you are after, but perhaps worth mentioning.

Disclaimer: reader support only exists because I asked him to add it, I
only asked him to add it because of your post (hence $ is the char). So it
is nicely circular any way.

--
the small snake
Reply all
Reply to author
Forward
0 new messages