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

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

Re: Understanding the "let" construct and the setting of variables


From: Emanuel Berg
Subject: Re: Understanding the "let" construct and the setting of variables
Date: Fri, 18 Dec 2020 16:33:19 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

steve-humphreys wrote:

> This message is for showing some examples, of how to set and
> use variables in a "let", because people criticise using
> "setq". But discussion needs simple examples that would not
> overwhelm a relative beginner.

On the contrary, it is very simple!

0. you are writing a `defun'...

1. start with `let'

2. if isn't enough because computation builds upon
   computation, which is very common, use `let*'.

And don't be afraid to use `let's simply for code clarity.
Break up computation into small steps. But also steps that
makes sense (for the human brain). Such steps, small that
makes sense, are the best.

3. if that isn't enough to use let/let* because several
   functions need to access a variable, use `setq' at the base
   level (i.e., first char of the line, or column 0) - not
   that Elisp has only one level, really, which is why you
   should use `setq' there to avoid confusion and errors.
   Because everyone can see what is created by `setq', this
   should be visible in the code style as well.

   Note that just because it would seem that two functions
   need access to the same variable, this actually doesn't
   have to be the case at all! Think it thru one extra time
   before you do it.

4. If a function uses a variable that has the character of an
   option, i.e. you are likely to fiddle with it back and
   forth, it can make sense to break it out and use a setq.
   Then you can provide it will be available to the on-line
   help and, if you like, you can provide it with a docstring.
   When you later fiddle with it to get it just right this
   will be less error prone than if it is embedded in the
   function, because then to make it come to effect, you have
   to re-eval the whole function.

5. If you write single function, only this function need
   a state (a memory) you can use setq for that outside the
   function. But you can also do that with properties, here
   [last] is an example. Bind that to, say, `C-c j'. Now,
   invoke with just C-c j. But with `C-u C-c j', you set the
   state, or in this case the pad-col property, to a new value
   (yeah, one would guess new, otherwise why do it?) So the
   next time you invoke it with just C-c j what will happen
   will act upon that new state. (TBH I don't know how well it
   works - I just wrote it :) - but it seems to work, I just
   tried it with this [1])

So use let, then let*, then setq outside of the functions and
when you do think twice what the reason is you have to do it,
and if there really inset some other way?

Note that it isn't wrong to use setq even inside of functions
when you know what you are doing and that's what you really
intend to do and there isn't any other way to do it. It is
just that 9/10 times, there is.

[1] https://dataswamp.org/~incal/conf/mpv/input.conf

(defun pad-to-col (&optional set-new-col)
  (interactive "p")
  (let*((plist   (symbol-plist #'pad-to-col))
        (prop    'pad-col)
        (pad-col (or (plist-get plist prop) 0))
        (beg-col (or (current-column) 4)) )
    (if (and set-new-col (= 4 set-new-col))
        (progn
          (plist-put plist prop beg-col)
          (message "pad col set: %s" beg-col) )
      (let ((step (- pad-col beg-col)))
        (when (> step 0)
          (insert (make-string step ?\s))
          (forward-line 1)
          (forward-char beg-col) )))))

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




reply via email to

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