help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Printing alist pairs to a dedicated buffur


From: Emanuel Berg
Subject: Re: Printing alist pairs to a dedicated buffur
Date: Fri, 26 Apr 2024 02:27:17 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

Heime wrote:

>> Don't use `defvar' if it can be avoided as that creates
>> global dynamic/special variables,` setq' creates global
>> static/lexical variables which isn't much better - unless
>> there is a variable by that name present, then that is used
>> instead. That kind of `setq' use is not wrong, actually it
>> is good.
>
> So it is actually good, but then still make a commotion
> about it. This way of commenting in not productive at all.

`setq' to set variables is good, to create global variables
with it is often not necessary and for the compiler not to
warn you also have to use `defvar', that is totally confusing.

(defvar global-lexical)
(setq global-lexical 10)
(special-variable-p 'global-lexical) ; nil

Also setq is error-prone as make a typo, the intended variable
with not be set but instead a global one will be created.
But the byte compiler will warn you about that if it happens.

Another solution would be one function to set available
variables, and one to create global ones. The "set available"
one would signal if such a variable isn't present, the global
one if there were already such a variable. But again, this is
what makes Lisp interesting.

> My defvar is used to store values that I need to access when
> I am working on a buffer. I can add to it as I modify the
> buffer, or delete from it. I cannot see why all this fuss
> not to use global variables.

Certainly they are there if you want to use them (pun).
Lisp is a maximalist language, anything and everything
included. Some people think global variables are okay, other
people think they should be avoided if there isn't any good
reason to have them.

Why is a static/lexical global variable better than
a dynamic/special? Good question, we must write some Elisp to
test what happens if that name collides with other source.

I wrote some Elisp that would show another option approach, so
one would always have `let' for static/lexical variables to
facilitate coding, and another construct for options to set
the behavior of whatever was enclosed. Now I don't really
understand it anymore 100%, but I yank it here [last] for your
viewing pleasure :)

But it will be the way it is now, this is just endless
theorizing because Lisp is very powerful, but also very
complicated compared to other languages.

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/vars-opts.el

(require 'cl-lib)

(defun check-binders (binds)
  (cl-loop
    for (n _) in binds
    with no-opt
    do (unless (special-variable-p n)
         (push (symbol-name n) no-opt) )
    finally (when no-opt
              (error "No option%s: %s"
                     (if (< 1 (length no-opt))
                         "s"
                       "")
                     (mapconcat #'identity (reverse no-opt) ", ") ))))

(defmacro opts (binds &rest body)
  (declare
    (indent 1)
    (debug let) )
  (check-binders binds)
  `(let ,binds ,@body) )

;; (opts ((fill-column 1)
;;        (a 0) )
;;   u) ; No option: a
;;
;; (defvar dynavar 2000)
;;
;; (opts ((dynavar 3000)
;;        (fill-column 1)
;;        (a 0)
;;        (y 2) )
;;   y) ; No options: a, y
;;
;; (opts ((dynavar 3000)
;;        (fill-column 10) )
;;   (delete-char 2)
;;   (fill-paragraph) ) ; eval me

(provide 'vars-opts)

-- 
underground experts united
https://dataswamp.org/~incal




reply via email to

[Prev in Thread] Current Thread [Next in Thread]