all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Drew Adams <drew.adams@oracle.com>
To: Jean Louis <bugs@gnu.support>,
	Michael Heerdegen <michael_heerdegen@web.de>
Cc: help-gnu-emacs@gnu.org
Subject: RE: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
Date: Fri, 18 Dec 2020 09:14:10 -0800 (PST)	[thread overview]
Message-ID: <5f8911eb-b20c-400e-86c6-a6ea6ca3d437@default> (raw)
In-Reply-To: <X9yQTIpbqBxhK6Mf@protected.rcdrun.com>

> First step:
> 
> (let* ((mailing-hash (rcd-db-table-id-hash "mailinglistoptions" option *cf*))
>        (mid (gethash 'mailinglistoptions_accounts mailing-hash))
>        (mid-hash (rcd-db-table-id-hash "accounts" mid *cf*))
>        (accounts-hash (rcd-db-table-id-hash "accounts" mid *cf*))
>        (email-list (rcd-email-list mid))))
> 
> Second step:
> 
> (let* ((setq mailing-hash (rcd-db-table-id-hash "mailinglistoptions" option *cf*))
>        (mid (gethash 'mailinglistoptions_accounts mailing-hash))
>        (mid-hash (rcd-db-table-id-hash "accounts" mid *cf*))
>        (accounts-hash (rcd-db-table-id-hash "accounts" mid *cf*))
>        (email-list (rcd-email-list mid))))

Nope.  That raises an error telling you
 "`let' bindings can have only one value-form".

FYI, that `let' has an empty body - it has only bindings.
That's not an error, but it might let you know that
something might not be as you hope.

More importantly, this "binding" is erroneous:

(setq mailing-hash (rcd-db-table-id-hash ...))

A `let' binding is either just a symbol (implicit binding
to `nil') or a two-element list of a symbol and a sexp.

That "binding" looks at first like it's binding symbol
`setq' to the value of variable `mailing-hash'.  But
the list doesn't end there - it's not a 2-element list
(which is what the error message tells you).

If you intend to use `setq' to assign a value to a
variable, instead of let-binding it, then move the
`setq' to the body of the `let'.

CAN you use a `setq' or other procedural code inside
a let-binding?  Sure, if you want to.  Just provide a
variable to bind to it.

(let* ((fred      42)
       (_IGNORED  (setq fred  'nope-24))
       (_NADA     (message "FRED: %S" fred)))
  ;; Empty body, if you like
  )

(Nothing special about the variable names.  But an
underscore prefix is sometimes used conventionally
to tell human readers that the thingy isn't really
used or isn't used in some particular way.  Here,
I use it to tell myself that the variable is used
only to be able to evaluate some sexp for its side
effect.  And I use uppercase just to make this
weirdness more obvious to myself.)

You can also bind the same variable multiple times,
if you like:

(let* ((fred   42)
       (alice  (foo fred))
       (fred   (if (> fred 0) 24 'derf))
       (fred   '(nah dont-do-that at-all)))
 (message "FRED: %S" fred))

IOW:

You can put any kind of procedural code in a `let' body
or a `let' binding.  If in a binding, it needs to be as
a sexp to evaluate and bind to some variable.

You can use multiple, sequential bindings for the same
variable, if you use `let*'.

You can also use the same variable name multiple times
with plain `let', but that's typically useless and not
what you intend.

(let ((fred  42) ; Not used anywhere
      (fred  '(nah dont-do-that at-all)))
 (message "FRED: %S" fred))

> Third step:
> 
> (let* ((mailing-hash (rcd-db-table-id-hash "mailinglistoptions" option *cf*))
>        (setq mid (gethash 'mailinglistoptions_accounts mailing-hash))
         ^^^^^^^^^^^^^^^^^^^...
Same problem as above.

> How would you do message calls there?

See above.  Put any procedural code you want to use
in the bindings part into a binding: provide a var
that you use or don't use, binding it to the code
you want to evaluate for its side effects.

Is this kind of thing great style?  Maybe not.  But
you can do it.

Being able to add `message' calls wherever you want
can be helpful.

Whether to use multiple `let*' bindings for the same
variable, versus the alternative of using multiple
`let(*)' forms, is a question of style and how you
want to work.  Coding is not only about the final
result; it can also be about intermediate forms that
are easy to work with, that talk to you, or are
otherwise convenient (for you) in some way.

Another thing you can add, as an alternative to
`message' calls, are calls to `debug'.  Those are
essentially breakpoints.  They let you know which
branch of code gets executed, opening the debugger
when encountered.

(let* ((fred   42)
       (_ZIP   (setq fred  'nope-24))
       (_NADA  (when (toto) (debug nil fred))))
  (unless (titi) (debug))
  ;;...
  )

`C-h f debug'...



  reply	other threads:[~2020-12-18 17:14 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-17  3:02 Making ielm behave like a shell (getting to previous commands using the up-arrow key) steve-humphreys
2020-12-17  3:34 ` Okam
2020-12-17  4:27 ` Michael Heerdegen
2020-12-17  4:44   ` steve-humphreys
2020-12-17  5:02     ` Michael Heerdegen
2020-12-17  5:17       ` steve-humphreys
2020-12-17  9:06         ` Jean Louis
2020-12-17  9:13           ` Jean Louis
2020-12-17 22:29           ` Michael Heerdegen
2020-12-18  5:05             ` Jean Louis
2020-12-18  9:01               ` Michael Heerdegen
2020-12-18 11:19                 ` Jean Louis
2020-12-18 17:14                   ` Drew Adams [this message]
2020-12-18 18:36                     ` Jean Louis
2020-12-18 19:11                       ` Drew Adams
2020-12-18 19:53                         ` Jean Louis
2020-12-18 21:15                           ` Drew Adams
2020-12-19  2:07                   ` Michael Heerdegen
2020-12-19  2:51                     ` Drew Adams
2020-12-18 11:28                 ` Jean Louis
2020-12-19  1:55                   ` Michael Heerdegen
2020-12-19  2:45                     ` Drew Adams
2020-12-19  1:57               ` Michael Heerdegen
2020-12-17  8:22   ` Joost Kremers
2020-12-18 10:20     ` Philip K.

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5f8911eb-b20c-400e-86c6-a6ea6ca3d437@default \
    --to=drew.adams@oracle.com \
    --cc=bugs@gnu.support \
    --cc=help-gnu-emacs@gnu.org \
    --cc=michael_heerdegen@web.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.