• name? - global vars via symbol macros

    From Madhu@21:1/5 to All on Sat Nov 27 18:14:11 2021
    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).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Wed Dec 1 08:46:00 2021
    * Madhu <m3fsrhydic.fsf@leonis4.robolove.meer.net> :
    Wrote on Sat, 27 Nov 2021 18:14:11 +0530:

    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).

    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Zyni=20Mo=C3=AB?=@21:1/5 to Madhu on Wed Dec 1 10:44:41 2021
    Madhu <enometh@meer.net> wrote:
    * Madhu <m3fsrhydic.fsf@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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)