unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Making ielm behave like a shell (getting to previous commands using the up-arrow key)
@ 2020-12-17  3:02 steve-humphreys
  2020-12-17  3:34 ` Okam
  2020-12-17  4:27 ` Michael Heerdegen
  0 siblings, 2 replies; 25+ messages in thread
From: steve-humphreys @ 2020-12-17  3:02 UTC (permalink / raw)
  To: Help Gnu Emacs


I have started using ielm and would be useful for it to behave like a terminal
That is enabling history on ielm to view all the previous executed commands
using the Up Arrow Key.

Regards
Steve



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  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
  1 sibling, 0 replies; 25+ messages in thread
From: Okam @ 2020-12-17  3:34 UTC (permalink / raw)
  To: help-gnu-emacs

On 12/16/20 10:02 PM, steve-humphreys@gmx.com wrote:
> 
> 
> I have started using ielm and would be useful for it to behave like a terminal
> That is enabling history on ielm to view all the previous executed commands
> using the Up Arrow Key.
> 
> Regards
> Steve
> 

If you're not already aware, many places in Emacs allow you to access 
your input history using "M-n" and "M-p". This works in IELM and Term, 
for example.

You can check what commands these keys run using the command 
`describe-key', which is bound to [F1 k] and "C-h k". You'll see that 
"M-n" and "M-p" run the commands `comint-next-input' and 
`comint-previous-input', respectively.

If you want to rebind [up] and [down] to cycle history instead of moving 
the cursor, you can do

   (define-key ielm-map (kbd "<up>") #'comint-previous-input)
   (define-key ielm-map (kbd "<down>") #'comint-next-input)

which applies only to IELM.  If you would like to have that behavior in 
every mode that uses Comint (such as Term, the inferior Python shell, 
etc.), then you can define the key in `comint-mode-map' instead.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  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  8:22   ` Joost Kremers
  1 sibling, 2 replies; 25+ messages in thread
From: Michael Heerdegen @ 2020-12-17  4:27 UTC (permalink / raw)
  To: help-gnu-emacs

steve-humphreys@gmx.com writes:

> I have started using ielm and would be useful for it to behave like a
> terminal That is enabling history on ielm to view all the previous
> executed commands using the Up Arrow Key.

You know that M-p does that?

FWIW, personally I'm quite happy that I can "walk around" with the arrow
keys in ielm buffers.


Regards,

Michael.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-17  4:27 ` Michael Heerdegen
@ 2020-12-17  4:44   ` steve-humphreys
  2020-12-17  5:02     ` Michael Heerdegen
  2020-12-17  8:22   ` Joost Kremers
  1 sibling, 1 reply; 25+ messages in thread
From: steve-humphreys @ 2020-12-17  4:44 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: help-gnu-emacs


> Sent: Thursday, December 17, 2020 at 5:27 AM
> From: "Michael Heerdegen" <michael_heerdegen@web.de>
> To: help-gnu-emacs@gnu.org
> Subject: Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
>
> steve-humphreys@gmx.com writes:
>
> > I have started using ielm and would be useful for it to behave like a
> > terminal That is enabling history on ielm to view all the previous
> > executed commands using the Up Arrow Key.
>
> You know that M-p does that?

Forgot about it!!

> FWIW, personally I'm quite happy that I can "walk around" with the arrow
> keys in ielm buffers.

You walk to do what?

> Regards,
>
> Michael.
>
>
>



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-17  4:44   ` steve-humphreys
@ 2020-12-17  5:02     ` Michael Heerdegen
  2020-12-17  5:17       ` steve-humphreys
  0 siblings, 1 reply; 25+ messages in thread
From: Michael Heerdegen @ 2020-12-17  5:02 UTC (permalink / raw)
  To: help-gnu-emacs

steve-humphreys@gmx.com writes:

> > FWIW, personally I'm quite happy that I can "walk around" with the arrow
> > keys in ielm buffers.
>
> You walk to do what?

To copy parts of an old input, most of the time.  Also C-x C-e
sometimes.

Michael.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-17  5:02     ` Michael Heerdegen
@ 2020-12-17  5:17       ` steve-humphreys
  2020-12-17  9:06         ` Jean Louis
  0 siblings, 1 reply; 25+ messages in thread
From: steve-humphreys @ 2020-12-17  5:17 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: help-gnu-emacs

ielm should be  described in "An Introduction to Programming in Emacs Lisp".  It is very useful
when starting with lisp.

> Sent: Thursday, December 17, 2020 at 6:02 AM
> From: "Michael Heerdegen" <michael_heerdegen@web.de>
> To: help-gnu-emacs@gnu.org
> Subject: Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
>
> steve-humphreys@gmx.com writes:
>
> > > FWIW, personally I'm quite happy that I can "walk around" with the arrow
> > > keys in ielm buffers.
> >
> > You walk to do what?
>
> To copy parts of an old input, most of the time.  Also C-x C-e
> sometimes.

Have tried it.  It's good.  Did not know it was possible to use C-x C-e
in ielm anh also on previous commands just by moving the location of the cursor.

> Michael.
>
>
>



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-17  4:27 ` Michael Heerdegen
  2020-12-17  4:44   ` steve-humphreys
@ 2020-12-17  8:22   ` Joost Kremers
  2020-12-18 10:20     ` Philip K.
  1 sibling, 1 reply; 25+ messages in thread
From: Joost Kremers @ 2020-12-17  8:22 UTC (permalink / raw)
  To: help-gnu-emacs


On Thu, Dec 17 2020, Michael Heerdegen wrote:
> steve-humphreys@gmx.com writes:
>
>> I have started using ielm and would be useful for it to behave like a
>> terminal That is enabling history on ielm to view all the previous
>> executed commands using the Up Arrow Key.
>
> You know that M-p does that?

Also Ctrl-up. :-)

> FWIW, personally I'm quite happy that I can "walk around" with the arrow
> keys in ielm buffers.

Indeed.

-- 
Joost Kremers
Life has its moments



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  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
  0 siblings, 2 replies; 25+ messages in thread
From: Jean Louis @ 2020-12-17  9:06 UTC (permalink / raw)
  To: steve-humphreys; +Cc: Michael Heerdegen, help-gnu-emacs

* steve-humphreys@gmx.com <steve-humphreys@gmx.com> [2020-12-17 08:20]:
> ielm should be described in "An Introduction to Programming in Emacs
> Lisp".  It is very useful when starting with lisp.

I am often using M-: to evaluate in one line and ielm rarely.

When I need to evaluate I also write it in any buffer and just
evaluate with C-x C-e, including in text buffers.

Then I also use `setq' dynamically many times when debugging:

Then I may do in first step this and get my-var as 1, it becomes
global but I don't care.

(defun my-function ()
  (let* ((setq my-var 1)
	 (new (+ my-var 2)))
    new))

Then I do this and evaluate new to be 4, it becomes global, but I don't care.

(defun my-function ()
  (let* ((my-var 1)
	 (setq new (+ my-var 2)))
    new))

As that is one way of debugging. But I think I will make function
to evaluate those lines without inserting `setq' and deleting
`setq' afterwards as it is repetitive.

(defun eval-with-setq-sexp ()
  (interactive)
  (let* ((sexp (thing-at-point 'list))
	 (end (length sexp))
	 (just-do (set-text-properties 0 end nil sexp))
	 (sexp (replace-regexp-in-string "^(" "(setq " sexp)))
  (message "%s" (eval (car (read-from-string sexp))))))

Then I could just bind this to a key and move into various parts
of (let FORM) to evaluate those variables when debugging. But I
guess I have to move to beginning or first variable like `a' or
`b' here below:

(global-set-key (kbd "<f5>") 'eval-with-setq-sexp)

(let ((a 1) ; <-- go on a and press your key like F5 and A becomes 1
      (something-else "Here") ; <-- on `something-else' with F5 it becomes "Here"
      (b (+ 2 1)))) ; <-- on `b' F5 assigns value 3 to b

Spares me time.

I also use instrumenting of a function when I wish to quickly
debug something. But too often I used (setq slow motion writing
it and typing. I will now switch to key bound debugging with the
above function.

Jean



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-17  9:06         ` Jean Louis
@ 2020-12-17  9:13           ` Jean Louis
  2020-12-17 22:29           ` Michael Heerdegen
  1 sibling, 0 replies; 25+ messages in thread
From: Jean Louis @ 2020-12-17  9:13 UTC (permalink / raw)
  To: GNU Emacs Help; +Cc: Michael Heerdegen, steve-humphreys

But not to fiddle with global variables, I could as well use
setq-local

(defun eval-with-setq-sexp ()
  (interactive)
  (let* ((sexp (thing-at-point 'list))
	 (end (length sexp))
	 (_ (set-text-properties 0 end nil sexp))
	 (sexp (replace-regexp-in-string "^(" "(setq-local " sexp)))
  (message "%s" (eval (car (read-from-string sexp))))))




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  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
  1 sibling, 1 reply; 25+ messages in thread
From: Michael Heerdegen @ 2020-12-17 22:29 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis <bugs@gnu.support> writes:

> Then I also use `setq' dynamically many times when debugging:

Why do you want that?

Michael.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-17 22:29           ` Michael Heerdegen
@ 2020-12-18  5:05             ` Jean Louis
  2020-12-18  9:01               ` Michael Heerdegen
  2020-12-19  1:57               ` Michael Heerdegen
  0 siblings, 2 replies; 25+ messages in thread
From: Jean Louis @ 2020-12-18  5:05 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: help-gnu-emacs

* Michael Heerdegen <michael_heerdegen@web.de> [2020-12-18 01:30]:
> Jean Louis <bugs@gnu.support> writes:
> 
> > Then I also use `setq' dynamically many times when debugging:
> 
> Why do you want that?

That is how I learned it, instruction was somewhere on how to debug
and I used to do it much in Common Lisp that way.

When you have

(let ((some 1)
      (more 2))

How do you go about debugging such function? Of course it is usually
much more complex than above. Error is reported but is not indicating
where exactly is a problem?

Emacs has instrumenting of functions which can help and which is
similar to setting each variable one by one with setq or setq-local

What is your way of debugging it?

Jean






^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18  5:05             ` Jean Louis
@ 2020-12-18  9:01               ` Michael Heerdegen
  2020-12-18 11:19                 ` Jean Louis
  2020-12-18 11:28                 ` Jean Louis
  2020-12-19  1:57               ` Michael Heerdegen
  1 sibling, 2 replies; 25+ messages in thread
From: Michael Heerdegen @ 2020-12-18  9:01 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis <bugs@gnu.support> writes:

> That is how I learned it, instruction was somewhere on how to debug
> and I used to do it much in Common Lisp that way.

I must admit that I did not exhaustively understand how you proceed
because the code examples you had posted are broken (let binding syntax
broken).

> When you have
>
> (let ((some 1)
>       (more 2))
>
> How do you go about debugging such function?

Sometimes I insert `message' calls or something more sophisticated to
output values.  That's the simplest tool.

And then, sure, edebug and the built-in debugger - they allow inspecting
values live so there is no need to change the environment unless you
need to save a value for later inspection or reuse.

> Emacs has instrumenting of functions which can help and which is
> similar to setting each variable one by one with setq or setq-local

Similar, but actually much cooler since Edebug and the debugger have
real access to the debugged environment.

> What is your way of debugging it?

Depends on "it".  Apart from the above ways `debug-on-variable-change'
comes handy when you don't know where a binding changes.  Sometimes I'm
also using the tracer to trace variable bindings - one can implement
that easily using (the quite new) variable watchers.

Regards,

Michael.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-17  8:22   ` Joost Kremers
@ 2020-12-18 10:20     ` Philip K.
  0 siblings, 0 replies; 25+ messages in thread
From: Philip K. @ 2020-12-18 10:20 UTC (permalink / raw)
  To: Joost Kremers; +Cc: help-gnu-emacs

Joost Kremers <joostkremers@fastmail.fm> writes:

> On Thu, Dec 17 2020, Michael Heerdegen wrote:
>> steve-humphreys@gmx.com writes:
>>
>>> I have started using ielm and would be useful for it to behave like a
>>> terminal That is enabling history on ielm to view all the previous
>>> executed commands using the Up Arrow Key.
>>
>> You know that M-p does that?
>
> Also Ctrl-up. :-)

C-c C-p to jump back to the last prompt, that can be modified and
re-evaluated is aoso helpful.

>> FWIW, personally I'm quite happy that I can "walk around" with the arrow
>> keys in ielm buffers.
>
> Indeed.

-- 
	Philip K.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18  9:01               ` Michael Heerdegen
@ 2020-12-18 11:19                 ` Jean Louis
  2020-12-18 17:14                   ` Drew Adams
  2020-12-19  2:07                   ` Michael Heerdegen
  2020-12-18 11:28                 ` Jean Louis
  1 sibling, 2 replies; 25+ messages in thread
From: Jean Louis @ 2020-12-18 11:19 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: help-gnu-emacs

* Michael Heerdegen <michael_heerdegen@web.de> [2020-12-18 12:02]:
> Jean Louis <bugs@gnu.support> writes:
> 
> > That is how I learned it, instruction was somewhere on how to debug
> > and I used to do it much in Common Lisp that way.
> 
> I must admit that I did not exhaustively understand how you proceed
> because the code examples you had posted are broken (let binding syntax
> broken).
> 
> > When you have
> >
> > (let ((some 1)
> >       (more 2))
> >
> > How do you go about debugging such function?
> 
> Sometimes I insert `message' calls or something more sophisticated to
> output values.  That's the simplest tool.

I will discard the rest of your message to understand one part
first. How do you insert message calls? Give me some example.

For me and in my programming somebody from scheme programming,
probably in Guile teached me that I should be making smaller functions
where each function does something and outputs something. And I that
gave me impression of being very simple. But then in Emacs packages I
too often find long and incomprehensible functions that do not follow
the style I have learned before some years.

From all functions I have rarely there is need to have a long
function. But when I do have longer function then the problem is often
to find out which check or variable changes properly and what is going
on. And in Common Lisp explanations on how to debug programs I have
adopted `setq' style. 

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

Third step:

(let* ((mailing-hash (rcd-db-table-id-hash "mailinglistoptions" option *cf*))
       (setq 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)))
       )

Fourth step:

(let* ((mailing-hash (rcd-db-table-id-hash "mailinglistoptions" option *cf*))
       (mid (gethash 'mailinglistoptions_accounts mailing-hash))
       (setq 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)))
       )

That is how I would be going step by step. But now I will change it to
`setq-local' instead of `setq'

How would you do message calls there?







^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18  9:01               ` Michael Heerdegen
  2020-12-18 11:19                 ` Jean Louis
@ 2020-12-18 11:28                 ` Jean Louis
  2020-12-19  1:55                   ` Michael Heerdegen
  1 sibling, 1 reply; 25+ messages in thread
From: Jean Louis @ 2020-12-18 11:28 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: help-gnu-emacs

* Michael Heerdegen <michael_heerdegen@web.de> [2020-12-18 12:02]:
> And then, sure, edebug and the built-in debugger - they allow inspecting
> values live so there is no need to change the environment unless you
> need to save a value for later inspection or reuse.

That makes all my debugging redundant. As edebug-defun allows the same
thing but very finely grained and with more control.

Do you then do SPC and C-x C-e to evaluate or get values debugged step
by step?

Majority of my functions are small and fitting in one screen of 88
columns by 25 lines.

Debugging usually comes when function is more complicated and not
(apparently) easily split into multiple functions.






^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18 11:19                 ` Jean Louis
@ 2020-12-18 17:14                   ` Drew Adams
  2020-12-18 18:36                     ` Jean Louis
  2020-12-19  2:07                   ` Michael Heerdegen
  1 sibling, 1 reply; 25+ messages in thread
From: Drew Adams @ 2020-12-18 17:14 UTC (permalink / raw)
  To: Jean Louis, Michael Heerdegen; +Cc: help-gnu-emacs

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



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18 17:14                   ` Drew Adams
@ 2020-12-18 18:36                     ` Jean Louis
  2020-12-18 19:11                       ` Drew Adams
  0 siblings, 1 reply; 25+ messages in thread
From: Jean Louis @ 2020-12-18 18:36 UTC (permalink / raw)
  To: Drew Adams; +Cc: Michael Heerdegen, help-gnu-emacs

* Drew Adams <drew.adams@oracle.com> [2020-12-18 20:14]:
> > 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".

It was description of my way of debugging programs. I learned it
online from Common Lisp. As I live isolated and not together in one
room with any programmer neither I know ANY in this city and country
where I am located I might catch something that is not common and
continue with it for years just as it would be common.

You cannot evaluate those forms alone or whole, as that is just
description of step by step debugging. Programs do not run with `setq'
there, it is inserted temporary to assign some variables step by step
until I find what is wrong. That way of debugging worked well for
me. But now I explore much easier edebug-defun, but I do not know how
to stop edebugging.

> FYI, that `let' has an empty body - it has only bindings.

Because it was demonstration of step by step rather rudimentary
debugging method. The whole function works just fine, I know that as
3917 emails were sent by using it.

> More importantly, this "binding" is erroneous:
> 
> (setq mailing-hash (rcd-db-table-id-hash ...))

That was demonstration. I insert `setq' to bind temporarily
`mailing-hash' during my debugging process. I wish I would know before
about edebug-defun, but I did not. After inserting setq, I would
delete it. My habit is so strong that I may continue doing that for
months until I get into edebug-defun

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

I have seen it works with _ alone

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

Of course, I do that.

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

Only it does not look nice any more. So often I will jump out of first
let and continue with second let.

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

Which * joker symbol I often forget. That is my major error in Elisp.

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

That is some misunderstanding. I hope you got it now.

How do you debug? You use edebug-defun?

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

That I did not understand. Why now show example of message call? What
is it? Do you mean (message something)?

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

Useful function. Is there anyway to get out of debug and continue the
function? c does not do what I think it should do. I would like to
exit out of debug and continue with the function. Any way?





^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18 18:36                     ` Jean Louis
@ 2020-12-18 19:11                       ` Drew Adams
  2020-12-18 19:53                         ` Jean Louis
  0 siblings, 1 reply; 25+ messages in thread
From: Drew Adams @ 2020-12-18 19:11 UTC (permalink / raw)
  To: Jean Louis; +Cc: Michael Heerdegen, help-gnu-emacs

> Programs do not run with `setq'
> there, it is inserted temporary to assign some variables step by step
> until I find what is wrong.

I see.  I misunderstood.  So you are not evaluating
the `let*' as written.  You are evaluating individual
`setq' sexps you added to it.

> > (_IGNORED  (setq fred  'nope-24))
> 
> I have seen it works with _ alone

Yes, of course.  I want to make it obvious to myself.

It "works" with any symbol whatsoever, no need for
"_" - that's just an informal convention.  It's all
about communicating to human readers (e.g. yourself).

> How do you debug? You use edebug-defun?

I use `debug', not `edebug'.  But many people use
`edebug'.  I use `debug-on-entry', `debug-on-error',
and explicit calls to `debug' inserted as breakpoints.

For the latter, `(debug nil SOME-SEXP)' evaluates
SOME-SEXP in the debugging context, and prints it
at the top of the debugger when it's entered.  So
it acts like an extra call to `message' (more
precisely, it does an implicit `e').

> > > How would you do message calls there?

I showed that in a few places - please review my
message - search for `message'.

> That I did not understand. Why now show example of message call? What
> is it? Do you mean (message something)?

Yes.  And I did show examples of it.

> Useful function. Is there anyway to get out of debug and continue the
> function? c does not do what I think it should do. I would like to
> exit out of debug and continue with the function. Any way?

`j' kind of does that.  `C-h m' in the debugger
tells you what's available.  See also (elisp)
`Invoking the Debugger'.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18 19:11                       ` Drew Adams
@ 2020-12-18 19:53                         ` Jean Louis
  2020-12-18 21:15                           ` Drew Adams
  0 siblings, 1 reply; 25+ messages in thread
From: Jean Louis @ 2020-12-18 19:53 UTC (permalink / raw)
  To: Drew Adams; +Cc: Michael Heerdegen, help-gnu-emacs

* Drew Adams <drew.adams@oracle.com> [2020-12-18 22:12]:
> > Programs do not run with `setq'
> > there, it is inserted temporary to assign some variables step by step
> > until I find what is wrong.
> 
> I see.  I misunderstood.  So you are not evaluating
> the `let*' as written.  You are evaluating individual
> `setq' sexps you added to it.
> 
> > > (_IGNORED  (setq fred  'nope-24))
> > 
> > I have seen it works with _ alone
> 
> Yes, of course.  I want to make it obvious to myself.
> 
> It "works" with any symbol whatsoever, no need for
> "_" - that's just an informal convention.  It's all
> about communicating to human readers (e.g. yourself).

I guess that _ will then not complain when byte compiled as unused
variable or similar.

> > How do you debug? You use edebug-defun?
> 
> I use `debug', not `edebug'.  But many people use
> `edebug'.  I use `debug-on-entry', `debug-on-error',
> and explicit calls to `debug' inserted as breakpoints.

> For the latter, `(debug nil SOME-SEXP)' evaluates
> SOME-SEXP in the debugging context, and prints it
> at the top of the debugger when it's entered.  So
> it acts like an extra call to `message' (more
> precisely, it does an implicit `e').

OK I find `message' example and I see it is not necessary as I anyway
evaluate with one key in my rudimentary method. It uses message
basically.

(defun eval-with-setq-sexp ()
  (interactive)
  (let* ((sexp (thing-at-point 'list))
	 (end (length sexp))
	 (_ (set-text-properties 0 end nil sexp))
	 (sexp (replace-regexp-in-string "^(" "(setq-local " sexp)))
  (message "%s" (eval (car (read-from-string sexp))))))

If I move cursor to sexp above, it will assign the rest of the form to
variable `sexp' and there will be no change of the code.

I can see in minibuffer: (sexp (thing-at-point 'list)) but then I have
not used `message'. I do use message and I open separate buffer for my
particular messages when program is running that I can see if there is
some problem overall. Sometimes program finds comma , in the name and
cannot send it as email. Messages come there handy. For that I use
this function to add to special buffer my private messages and not to
mix it with Emacs messages.

(defun rcd-mailing-message (s)
  (let ((buffer "*RCD Mailings Messages and Errors*")
	(current (current-buffer)))
    (get-buffer-create buffer)
    (switch-to-buffer buffer)
    (goto-char (point-max))
    (insert (concat (prin1-to-string s) "\n"))
    (switch-to-buffer current)))

From there I understand it. Basically I do the same but I was
referring to individual line debugging of let form rather than
debugging in continual run of the program. I got it now what you
mean in regards to `message'.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18 19:53                         ` Jean Louis
@ 2020-12-18 21:15                           ` Drew Adams
  0 siblings, 0 replies; 25+ messages in thread
From: Drew Adams @ 2020-12-18 21:15 UTC (permalink / raw)
  To: Jean Louis; +Cc: Michael Heerdegen, help-gnu-emacs

> From there I understand it. Basically I do the same but I was
> referring to individual line debugging of let form rather than
> debugging in continual run of the program. 

The use of `message' that you just showed doesn't
do that.  The use of `message' that I spoke of does
do it - use `message' in the binding forms:

(let* ((fred      42)
       (_IGNORED  (setq fred  'nope-24))
       (_NADA     (message "FRED: %S" fred))
       ;; ...
       (_NADA     (message "FRED: %S, "FROG: %S" fred frog))
       ;; ...
       )
  ;; ...
  )



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18 11:28                 ` Jean Louis
@ 2020-12-19  1:55                   ` Michael Heerdegen
  2020-12-19  2:45                     ` Drew Adams
  0 siblings, 1 reply; 25+ messages in thread
From: Michael Heerdegen @ 2020-12-19  1:55 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis <bugs@gnu.support> writes:

> Do you then do SPC and C-x C-e to evaluate or get values debugged step
> by step?

For Edebug:

SPC, yes, and that prints the values of the currently evaluated
expression to the echo area all the time (including variable bindings),
no need for extra evaluations all the time.

Generally, if you want to evaluate something in the context of the
debugged code, for whatever reason, situational: `e' to get a prompt for
an expression to eval, C-x C-e to evaluate parts of the code.

For the built-in debugger, the answer is more or less the same, the key
bindings are different though.

I encourage to learn about both Elisp debuggers, they shine in different
situations, both are great tools.  For the built-in debugger note that
you still may need to evaluate the sources of the debugged code so that
you don't debug byte-code (which is possible but painful).


Michael.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18  5:05             ` Jean Louis
  2020-12-18  9:01               ` Michael Heerdegen
@ 2020-12-19  1:57               ` Michael Heerdegen
  1 sibling, 0 replies; 25+ messages in thread
From: Michael Heerdegen @ 2020-12-19  1:57 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis <bugs@gnu.support> writes:

> (let ((some 1)
>       (more 2))

Is it intended that this is not an expression (without adding an extra
closing paren)?

Michael.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-18 11:19                 ` Jean Louis
  2020-12-18 17:14                   ` Drew Adams
@ 2020-12-19  2:07                   ` Michael Heerdegen
  2020-12-19  2:51                     ` Drew Adams
  1 sibling, 1 reply; 25+ messages in thread
From: Michael Heerdegen @ 2020-12-19  2:07 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis <bugs@gnu.support> writes:

> For me and in my programming somebody from scheme programming,
> probably in Guile teached me that I should be making smaller functions
> where each function does something and outputs something. And I that
> gave me impression of being very simple. But then in Emacs packages I
> too often find long and incomprehensible functions that do not follow
> the style I have learned before some years.

It's debatable how large defuns should be.  In the Emacs sources, a lot
of them could be split or refactored indeed.  What we have is the result
of a development.  In the repositories, small changes are preferred and
are better traceable with version control systems, and refactoring is an
unrewarding job that even messes git history.  As a consequence, defuns
tend to grow.  I guess that is one side of the phenomenon called "bit
rotting".

The other side is that what one might consider as an ideal size of
defuns (or "factors") in his code might vary with your familiarity and
experience with the language and the project.  Experienced people might
find relatively large units ok that would be not acceptable for somebody
for whom working with that language is not daily business.

Regards,

Michael.




^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-19  1:55                   ` Michael Heerdegen
@ 2020-12-19  2:45                     ` Drew Adams
  0 siblings, 0 replies; 25+ messages in thread
From: Drew Adams @ 2020-12-19  2:45 UTC (permalink / raw)
  To: Michael Heerdegen, help-gnu-emacs

> For the built-in debugger note that
> you still may need to evaluate the sources of the debugged code so that
> you don't debug byte-code (which is possible but painful).

This is a good point.  Load the source code you
want to debug, so you don't skip over steps you
might be interested in.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: Making ielm behave like a shell (getting to previous commands using the up-arrow key)
  2020-12-19  2:07                   ` Michael Heerdegen
@ 2020-12-19  2:51                     ` Drew Adams
  0 siblings, 0 replies; 25+ messages in thread
From: Drew Adams @ 2020-12-19  2:51 UTC (permalink / raw)
  To: Michael Heerdegen, help-gnu-emacs

> It's debatable how large defuns should be.  In the Emacs sources, a lot
> of them could be split or refactored indeed.  What we have is the result
> of a development.  In the repositories, small changes are preferred and
> are better traceable with version control systems, and refactoring is an
> unrewarding job that even messes git history.  As a consequence, defuns
> tend to grow.  I guess that is one side of the phenomenon called "bit
> rotting".
> 
> The other side is that what one might consider as an ideal size of
> defuns (or "factors") in his code might vary with your familiarity and
> experience with the language and the project.  Experienced people might
> find relatively large units ok that would be not acceptable for somebody
> for whom working with that language is not daily business.

All good points.  For the last bit: familiarity
with the language, yes.  But even familiarity
with the particular code can make a difference.

Understandability and changeability are affected
by function def size, and even library size
generally.  But the structure and complexity of
the code can make an even bigger difference.

E.g., a long function def that's simple, clean
and straightforward might well be easier to deal
with than a set of small functions that are not
so clean and clear but that have equivalent
behavior.  It all depends...



^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2020-12-19  2:51 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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.

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).