unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* how to speed up Lisp devel time
@ 2024-08-09  7:16 Emanuel Berg
  2024-08-09  7:24 ` Eli Zaretskii
  0 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09  7:16 UTC (permalink / raw)
  To: emacs-devel

One thing one could try is to replace boring, trivial stuff
with non-Lisp syntax and have that embedded.

For example setting up the interface.

Note: Over one in five interfaces in the Emacs source uses
Lisp and not the `interactive' format string. So it isn't just
me. It takes _a lot_ of time setting up the interface,
assigning default values, verifying indata, setting up
collections for completion, and so on.

Here is one example from my own code:

  ;; ...
  (interactive (if (numberp current-prefix-arg)
                   (list current-prefix-arg)
                 current-prefix-arg))
  (unless end
    (setq end 73))
  (unless step
    (setq step (min 10 (max 2 (/ end 10)))))
  (unless i
    (setq i 0))
  (unless (and (numberp i)    (<= 0 i)
               (numberp end)  (<  0 end)
               (numberp step) (<  0 step))
    (error "Bogus indata"))

This is 402 chars!

But here is a 135-char solution that expresses the same:

[
  end  :range     0<   :default 73         :prefix-arg
  step :range-cut 2-10 :default (/ end 10)
  i    :range     0<=  :default 0
]

And here is a 88 char solution:

[
  end  :r  0<   :d 73         :pa
  step :rc 2-10 :d (/ end 10)
  i    :r  0<=  :d 0
]

Also with: :prompt-string (:ps), :doc-string (:ds) ...

That way, we could keep Lisps elegance and power for where
people cared about it, for example solving interesting
algorithmic problems.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09  7:16 how to speed up Lisp devel time Emanuel Berg
@ 2024-08-09  7:24 ` Eli Zaretskii
  2024-08-09  7:39   ` Emanuel Berg
  2024-08-09  8:24   ` Emanuel Berg
  0 siblings, 2 replies; 32+ messages in thread
From: Eli Zaretskii @ 2024-08-09  7:24 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-devel

> From: Emanuel Berg <incal@dataswamp.org>
> Date: Fri, 09 Aug 2024 09:16:52 +0200
> 
> One thing one could try is to replace boring, trivial stuff
> with non-Lisp syntax and have that embedded.
> 
> For example setting up the interface.
> 
> Note: Over one in five interfaces in the Emacs source uses
> Lisp and not the `interactive' format string. So it isn't just
> me. It takes _a lot_ of time setting up the interface,
> assigning default values, verifying indata, setting up
> collections for completion, and so on.
> 
> Here is one example from my own code:
> 
>   ;; ...
>   (interactive (if (numberp current-prefix-arg)
>                    (list current-prefix-arg)
>                  current-prefix-arg))
>   (unless end
>     (setq end 73))
>   (unless step
>     (setq step (min 10 (max 2 (/ end 10)))))
>   (unless i
>     (setq i 0))
>   (unless (and (numberp i)    (<= 0 i)
>                (numberp end)  (<  0 end)
>                (numberp step) (<  0 step))
>     (error "Bogus indata"))
> 
> This is 402 chars!

Why do you need that?  Interactive functions can supply the arguments
inside the 'interactive' spec, where no tests are needed.  And
non-interactive functions need not provide defaults for each argument,
at least not usually.

And finally, Emacs does have keyword arguments and cl-defun, if and
when you need these facilities.

Just look at the Emacs sources: you will rarely if ever find such long
sequences of setting missing arguments to their defaults.  That's no
accident.



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

* Re: how to speed up Lisp devel time
  2024-08-09  7:24 ` Eli Zaretskii
@ 2024-08-09  7:39   ` Emanuel Berg
  2024-08-09 10:43     ` Eli Zaretskii
  2024-08-09  8:24   ` Emanuel Berg
  1 sibling, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09  7:39 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii wrote:

>>   ;; ...
>>   (interactive (if (numberp current-prefix-arg)
>>                    (list current-prefix-arg)
>>                  current-prefix-arg))
>>   (unless end
>>     (setq end 73))
>>   (unless step
>>     (setq step (min 10 (max 2 (/ end 10)))))
>>   (unless i
>>     (setq i 0))
>>   (unless (and (numberp i)    (<= 0 i)
>>                (numberp end)  (<  0 end)
>>                (numberp step) (<  0 step))
>>     (error "Bogus indata"))
>> 
>> This is 402 chars!
>
> Why do you need that?

I want it to work with M-x, C-u M-x, and C-u 100 M-x.

Then I want the same defaults for interactive and
non-interactive use.

Then I want the same final verification for interactive and
non-interactive use.

Not so radical things to wish for, are they?

> inside the 'interactive' spec, where no tests are needed.
> And non-interactive functions need not provide defaults for
> each argument, at least not usually.
>
> And finally, Emacs does have keyword arguments and cl-defun,
> if and when you need these facilities.

> Just look at the Emacs sources: you will rarely if ever find
> such long sequences of setting missing arguments to their
> defaults. That's no accident.

Oh, there are long sequences setting up the interface in the
Emacs source alright. Sometimes they are so long they have
become separate functions of their own.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09  7:24 ` Eli Zaretskii
  2024-08-09  7:39   ` Emanuel Berg
@ 2024-08-09  8:24   ` Emanuel Berg
  2024-08-09 10:36     ` Christopher Dimech
  1 sibling, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09  8:24 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii wrote:

>> One thing one could try is to replace boring, trivial stuff
>> with non-Lisp syntax and have that embedded. [...]
>
> Why do you need that?

It is faster to type (fewer chars), and easier to edit, and
more easy to read because not so packed with parenthesis.
Overall faster, less error-prone.

Another example could be, instead `let'/`let*', "wet":

(wet
  var1 0
  var2 (some-lisp)
  )

It is always like `let*' so no more annoying errors based
on that!

It comes in two forms, either

(wet
  var1 0
  var2 (some-lisp)
    (some-lisp-body)
  )

where var1 and var2 would be bound in the Lisp
(some-lisp-body), or just

(wet
  var1 0
  var2 (some-lisp)
  )

Where they would be valid for the rest of where ever you place
it - the rest of the `defun', for example.
  
-- 
underground experts united
https://dataswamp.org/~incal




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

* how to speed up Lisp devel time
  2024-08-09  8:24   ` Emanuel Berg
@ 2024-08-09 10:36     ` Christopher Dimech
  0 siblings, 0 replies; 32+ messages in thread
From: Christopher Dimech @ 2024-08-09 10:36 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-devel



> Sent: Friday, August 09, 2024 at 8:24 PM
> From: "Emanuel Berg" <incal@dataswamp.org>
> To: emacs-devel@gnu.org
> Subject: Re: how to speed up Lisp devel time
>
> Eli Zaretskii wrote:
>
> >> One thing one could try is to replace boring, trivial stuff
> >> with non-Lisp syntax and have that embedded. [...]
> >
> > Why do you need that?
>
> It is faster to type (fewer chars), and easier to edit, and
> more easy to read because not so packed with parenthesis.
> Overall faster, less error-prone.
>
> Another example could be, instead `let'/`let*', "wet":
>
> (wet
>   var1 0
>   var2 (some-lisp)
>   )
>
> It is always like `let*' so no more annoying errors based
> on that!

We simple need the additional tools that go beyond the traditional ways
of reading source code.  I suggest incorporating the functionality
of rainbow-delimiters into core emacs so that the functionality is automatic.

That solves the difficulties mentioned.



> It comes in two forms, either
>
> (wet
>   var1 0
>   var2 (some-lisp)
>     (some-lisp-body)
>   )
>
> where var1 and var2 would be bound in the Lisp
> (some-lisp-body), or just
>
> (wet
>   var1 0
>   var2 (some-lisp)
>   )
>
> Where they would be valid for the rest of where ever you place
> it - the rest of the `defun', for example.
>
> --
> underground experts united
> https://dataswamp.org/~incal
>
>
>



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

* Re: how to speed up Lisp devel time
  2024-08-09  7:39   ` Emanuel Berg
@ 2024-08-09 10:43     ` Eli Zaretskii
  2024-08-09 11:18       ` Emanuel Berg
  0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2024-08-09 10:43 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-devel

> From: Emanuel Berg <incal@dataswamp.org>
> Date: Fri, 09 Aug 2024 09:39:01 +0200
> 
> Eli Zaretskii wrote:
> 
> >>   ;; ...
> >>   (interactive (if (numberp current-prefix-arg)
> >>                    (list current-prefix-arg)
> >>                  current-prefix-arg))
> >>   (unless end
> >>     (setq end 73))
> >>   (unless step
> >>     (setq step (min 10 (max 2 (/ end 10)))))
> >>   (unless i
> >>     (setq i 0))
> >>   (unless (and (numberp i)    (<= 0 i)
> >>                (numberp end)  (<  0 end)
> >>                (numberp step) (<  0 step))
> >>     (error "Bogus indata"))
> >> 
> >> This is 402 chars!
> >
> > Why do you need that?
> 
> I want it to work with M-x, C-u M-x, and C-u 100 M-x.

This is rather unusual, and you should expect to have some
more-than-normally complicate code in that case.

Also, someone pointed out that you could write this in just 83
characters.

> Then I want the same defaults for interactive and
> non-interactive use.

That usually makes little sense in Emacs.  Interactive and
non-interactive uses have different semantics.

> Not so radical things to wish for, are they?

Actually, it is quite unusual.

> > Just look at the Emacs sources: you will rarely if ever find
> > such long sequences of setting missing arguments to their
> > defaults. That's no accident.
> 
> Oh, there are long sequences setting up the interface in the
> Emacs source alright. Sometimes they are so long they have
> become separate functions of their own.

That happens, but very rarely.  Well-designed clean code should avoid
that.



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

* Re: how to speed up Lisp devel time
  2024-08-09 10:43     ` Eli Zaretskii
@ 2024-08-09 11:18       ` Emanuel Berg
  2024-08-09 12:02         ` Eli Zaretskii
  0 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 11:18 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii wrote:

>>>>   (interactive (if (numberp current-prefix-arg)
>>>>                    (list current-prefix-arg)
>>>>                  current-prefix-arg))
>>>>   (unless end
>>>>     (setq end 73))
>>>>   (unless step
>>>>     (setq step (min 10 (max 2 (/ end 10)))))
>>>>   (unless i
>>>>     (setq i 0))
>>>>   (unless (and (numberp i)    (<= 0 i)
>>>>                (numberp end)  (<  0 end)
>>>>                (numberp step) (<  0 step))
>>>>     (error "Bogus indata"))
>>>> 
>>>> This is 402 chars!
>>>
>>> Why do you need that?
>> 
>> I want it to work with M-x, C-u M-x, and C-u 100 M-x.
>
> This is rather unusual, and you should expect to have some
> more-than-normally complicate code in that case.

What do you mean? It is the same for `forward-line'

C-u   M-x forward-line RET
C-u 4 M-x forward-line RET

> Also, someone pointed out that you could write this in just
> 83 characters.

Really? Well, well, let's see the code then!

It is 402 chars now so that is quite an achievement!

>> Then I want the same defaults for interactive and
>> non-interactive use.
>
> That usually makes little sense in Emacs. Interactive and
> non-interactive uses have different semantics.

Same default for any kind of call makes little sense. Usually!

I OTOH thinks that is the first policy I can think of.

Since the interface is just the interface, if something is
unset that is needed by the function, regardless of what
interface didn't set it, just set it to the default.
That works.

>>> Just look at the Emacs sources: you will rarely if ever
>>> find such long sequences of setting missing arguments to
>>> their defaults. That's no accident.
>> 
>> Oh, there are long sequences setting up the interface in
>> the Emacs source alright. Sometimes they are so long they
>> have become separate functions of their own.
>
> That happens, but very rarely. Well-designed clean code
> should avoid that.

It is better if everyone, well-designers or not, could use
a clean interface to do that. Then one could simply use it and
not having to rely on people writing great Elisp for
everything.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 11:18       ` Emanuel Berg
@ 2024-08-09 12:02         ` Eli Zaretskii
  2024-08-09 13:54           ` Emanuel Berg
  0 siblings, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2024-08-09 12:02 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-devel

> From: Emanuel Berg <incal@dataswamp.org>
> Date: Fri, 09 Aug 2024 13:18:25 +0200
> 
> Eli Zaretskii wrote:
> 
> >>> Why do you need that?
> >> 
> >> I want it to work with M-x, C-u M-x, and C-u 100 M-x.
> >
> > This is rather unusual, and you should expect to have some
> > more-than-normally complicate code in that case.
> 
> What do you mean? It is the same for `forward-line'
> 
> C-u   M-x forward-line RET
> C-u 4 M-x forward-line RET

No, it isn't.  forward-line accepts a numeric argument, and that's
all.  All you need to do to support that is use the corresponding
'interactive' code.

> > Also, someone pointed out that you could write this in just
> > 83 characters.
> 
> Really? Well, well, let's see the code then!

It was posted, I just counted the characters.

> > That usually makes little sense in Emacs. Interactive and
> > non-interactive uses have different semantics.
> 
> Same default for any kind of call makes little sense. Usually!
> 
> I OTOH thinks that is the first policy I can think of.

Then your code is unlikely to be accepted into Emacs.

> > That happens, but very rarely. Well-designed clean code
> > should avoid that.
> 
> It is better if everyone, well-designers or not, could use
> a clean interface to do that. Then one could simply use it and
> not having to rely on people writing great Elisp for
> everything.

Code doesn't write itself.  Good design is always needed for elegant
code.



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

* Re: how to speed up Lisp devel time
  2024-08-09 12:02         ` Eli Zaretskii
@ 2024-08-09 13:54           ` Emanuel Berg
  2024-08-09 14:58             ` Eli Zaretskii
  2024-08-09 14:59             ` Eduardo Ochs
  0 siblings, 2 replies; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 13:54 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii wrote:

>>> This is rather unusual, and you should expect to have some
>>> more-than-normally complicate code in that case.
>> 
>> What do you mean? It is the same for `forward-line'
>> 
>> C-u   M-x forward-line RET
>> C-u 4 M-x forward-line RET
>
> No, it isn't. forward-line accepts a numeric argument, and
> that's all. All you need to do to support that is use the
> corresponding 'interactive' code.

Okay, bad example.

What about this one, then?

C-u C-u a
aaaaaaaaaaaaaaaa 

C-u 17 a
aaaaaaaaaaaaaaaaa

>>> Also, someone pointed out that you could write this in
>>> just 83 characters.
>> 
>> Really? Well, well, let's see the code then!
>
> It was posted, I just counted the characters.

Here is the original code [last], I said it was 402 chars but
excluding the initial whitespace every line it is 376 chars.

One can make it shorter here and there, but to write that in
83 chars of Elisp - well, let's see it.

BTW that interface isn't complete/optimal I see now, there
are more stuff, also uncontroversial as you will see, that
I can add. Maybe later.

Right now - conceptually, not thinking about the details - it
supports

* Interactive use with M-x, including C-u M-x and C-u x M-x.

* Default values, for the _function_, not the interfaces.

* Verification of all args, again for the _function_ and not
  for any particular interface.

>>> That usually makes little sense in Emacs. Interactive and
>>> non-interactive uses have different semantics.
>> 
>> Same default for any kind of call makes little
>> sense. Usually!
>> 
>> I OTOH thinks that is the first policy I can think of.
>
> Then your code is unlikely to be accepted into Emacs.

The default values I speak of here isn't the default of any
particular _interface_, it is values for which _the function_
- regardless of interface - can fall back upon if the value
is unset.

I know that isn't at all any kind of radical or original
thought, it is a very basic idea and I don't care if you -
based on how it is done in Emacs - disagree.

>>> That happens, but very rarely. Well-designed clean code
>>> should avoid that.
>> 
>> It is better if everyone, well-designers or not, could use
>> a clean interface to do that. Then one could simply use it
>> and not having to rely on people writing great Elisp
>> for everything.
>
> Code doesn't write itself. Good design is always needed for
> elegant code.

The Emacs design in this case isn't good. In fact it is
a mess. The interactive and non-interactive stuff are both
tangled up sometimes and parallel sometimes.

The functions should not be branching mid-way based on that
and there shouldn't be a separate set of functions for this or
the other interface. "This is for interactive use" and all.

Interactive/non-interactive should _only_ matter in setting up
and executing _the interface_, after that the functions should
run the same based on the present data, regardless of how that
data is obtained.

Just imagine if we were to add a third interface? Would be
branch on that mid-way into functions as well, and have
a third set of functions, just for that interface?

But be that as it may, the way you do it with the
`interactive' format string still isn't good - not powerful
enough, which is way so often people have to use Lisp instead.
And, too cryptic in that tiny string which makes it
error-prone to write, and difficult to read.

[code]

(interactive (if (numberp current-prefix-arg)
                 (list current-prefix-arg)
               current-prefix-arg))
(unless end
  (setq end 73))
(unless step
  (setq step (min 10 (max 2 (/ end 10)))))
(unless i
  (setq i 0))
(unless (and (numberp i)    (<= 0 i)
             (numberp end)  (<  0 end)
             (numberp step) (<  0 step))
  (error "Bogus indata"))

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 13:54           ` Emanuel Berg
@ 2024-08-09 14:58             ` Eli Zaretskii
  2024-08-09 16:03               ` Emanuel Berg
  2024-08-09 14:59             ` Eduardo Ochs
  1 sibling, 1 reply; 32+ messages in thread
From: Eli Zaretskii @ 2024-08-09 14:58 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-devel

> From: Emanuel Berg <incal@dataswamp.org>
> Date: Fri, 09 Aug 2024 15:54:40 +0200
> 
> Eli Zaretskii wrote:
> 
> >>> This is rather unusual, and you should expect to have some
> >>> more-than-normally complicate code in that case.
> >> 
> >> What do you mean? It is the same for `forward-line'
> >> 
> >> C-u   M-x forward-line RET
> >> C-u 4 M-x forward-line RET
> >
> > No, it isn't. forward-line accepts a numeric argument, and
> > that's all. All you need to do to support that is use the
> > corresponding 'interactive' code.
> 
> Okay, bad example.
> 
> What about this one, then?
> 
> C-u C-u a
> aaaaaaaaaaaaaaaa 
> 
> C-u 17 a
> aaaaaaaaaaaaaaaaa

These all are handled by the 'p' interactive code.  So all you need is
this:

  (defun some-fun (arg)
    (interactive "p")

> >>> Also, someone pointed out that you could write this in
> >>> just 83 characters.
> >> 
> >> Really? Well, well, let's see the code then!
> >
> > It was posted, I just counted the characters.
> 
> Here is the original code [last], I said it was 402 chars but
> excluding the initial whitespace every line it is 376 chars.
> 
> One can make it shorter here and there, but to write that in
> 83 chars of Elisp - well, let's see it.

  https://lists.gnu.org/archive/html/emacs-devel/2024-08/msg00314.html



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

* Re: how to speed up Lisp devel time
  2024-08-09 13:54           ` Emanuel Berg
  2024-08-09 14:58             ` Eli Zaretskii
@ 2024-08-09 14:59             ` Eduardo Ochs
  2024-08-09 16:19               ` Emanuel Berg
  1 sibling, 1 reply; 32+ messages in thread
From: Eduardo Ochs @ 2024-08-09 14:59 UTC (permalink / raw)
  To: emacs-devel

On Fri, 9 Aug 2024 at 11:52, Emanuel Berg <incal@dataswamp.org> wrote:
>
> (interactive (if (numberp current-prefix-arg)
>                  (list current-prefix-arg)
>                current-prefix-arg))
> (unless end
>   (setq end 73))
> (unless step
>   (setq step (min 10 (max 2 (/ end 10)))))
> (unless i
>   (setq i 0))
> (unless (and (numberp i)    (<= 0 i)
>              (numberp end)  (<  0 end)
>              (numberp step) (<  0 step))
>   (error "Bogus indata"))

Can you show the complete function?
  Cheers,
    Eduardo



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

* Re: how to speed up Lisp devel time
  2024-08-09 14:58             ` Eli Zaretskii
@ 2024-08-09 16:03               ` Emanuel Berg
  2024-08-09 16:16                 ` Emanuel Berg
  2024-08-09 17:27                 ` Yuri Khan
  0 siblings, 2 replies; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 16:03 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii wrote:

> These all are handled by the 'p' interactive code. So all
> you need is this:
>
> (interactive "p")

Okay, that is some improvement at last.

But actually it should be like this for interactive use:

- With M-x: Prompt string for all three variables using their
  default values as suggestions.

  It should prompt again for each variable if it fails its
  validation until it is OK. Whenever failing it should say
  for example "end must be: (<= 0 end)" so the user knows what
  went wrong.

- With C-u M-x or C-u n M-x OTOH: one should set this value to
  'end', and if it validates, then set 'step' and 'i' to their
  default values. The reason is the user shouldn't be asked to
  input data in more than one form.

For non-interactive use, or generally in the function for any
interface:

1. Set all to their defaults if unset

2. Validate all three.

Code rules: Default values, and functions to verify etc,
should be stated once each, not once in here and then the same
value somewhere else.

>> One can make it shorter here and there, but to write that
>> in 83 chars of Elisp - well, let's see it.
>
>   https://lists.gnu.org/archive/html/emacs-devel/2024-08/msg00314.html

It only sets the default values.

I do that in 120 chars, I don't like multiple-binding `setq'
and `unless' (not `or') is prefered at ELPA, I know from
submitting, so I'll go for that.

Writing compact Elisp is hardly going to be more standardized,
less error-prone and more relaxing to write, but sure, it
is shorter.

Now, see the complete description above! As you see, there is
nothing controversial there. It is arguably a very sound
approach. Let's see it in - how many chars?

Actually, if anyone can do it _at all_ I'll be impressed.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 16:03               ` Emanuel Berg
@ 2024-08-09 16:16                 ` Emanuel Berg
  2024-08-09 17:54                   ` Eli Zaretskii
  2024-08-09 17:27                 ` Yuri Khan
  1 sibling, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 16:16 UTC (permalink / raw)
  To: emacs-devel

>> These all are handled by the 'p' interactive code. So all
>> you need is this:
>>
>> (interactive "p")
>
> Okay, that is some improvement at last.

I spoke to soon. That is not the same as

(interactive (if (numberp current-prefix-arg)
                 (list current-prefix-arg)
               current-prefix-arg))

That, (interactive "p"), is the same as sending 1 on M-x, but
here we want it to be the default behavior. Since nothing is
stated explicitely.

M-x should be default, just as (function-name) should
be default.

But it should be possible to do C-u 1 M-x to set 'end' to 1.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 14:59             ` Eduardo Ochs
@ 2024-08-09 16:19               ` Emanuel Berg
  2024-08-09 18:00                 ` Eli Zaretskii
  0 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 16:19 UTC (permalink / raw)
  To: emacs-devel

Eduardo Ochs wrote:

>> (interactive [...]
>
> Can you show the complete function?

Sure, see the seven test cases as well.

;; -----------------------------------------------------------------------
;; Scale, `draw-scale'
;; ~~~~~~~~~~~~~~~~~~~
;;
;; (draw-scale)                0......7......14.....21.....28.....35...
;; (draw-scale 10 3)           0..3..6..9.
;; (draw-scale 16 4 1)         1...5...9...13..
;; M-x draw-scale RET          0......7......14.....21.....28.....35...
;; C-u M-x draw-scale RET      0.2.4
;; C-u   1 draw-scale RET      0.
;; C-u 300 M-x draw-scale RET  0.........10........20........30........
;; -----------------------------------------------------------------------

(require 'cl-lib)

(defun draw-scale (&optional end step i)
  (interactive (if (numberp current-prefix-arg)
                   (list current-prefix-arg)
                 current-prefix-arg))
  (unless end
    (setq end 73))
  (unless step
    (setq step (min 10 (max 2 (/ end 10)))))
  (unless i
    (setq i 0))
  (unless (and (numberp i)    (<= 0 i)
               (numberp end)  (<  0 end)
               (numberp step) (<  0 step))
    (error "Bogus indata"))
  (cl-loop
    with cur = i
    for  dig = (format "%s" (if (zerop (% (- cur i) step)) cur "."))
    while (<= cur end) do
      (insert dig)
      (cl-incf cur (length dig))))

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 16:03               ` Emanuel Berg
  2024-08-09 16:16                 ` Emanuel Berg
@ 2024-08-09 17:27                 ` Yuri Khan
  2024-08-09 21:21                   ` Emanuel Berg
                                     ` (2 more replies)
  1 sibling, 3 replies; 32+ messages in thread
From: Yuri Khan @ 2024-08-09 17:27 UTC (permalink / raw)
  To: emacs-devel

On Fri, 9 Aug 2024 at 23:09, Emanuel Berg <incal@dataswamp.org> wrote:

> But actually it should be like this for interactive use:
>
> - With M-x: Prompt string for all three variables using their
>   default values as suggestions.
>
>   It should prompt again for each variable if it fails its
>   validation until it is OK. Whenever failing it should say
>   for example "end must be: (<= 0 end)" so the user knows what
>   went wrong.

If your command has three arguments, asking for them in succession
with validation and re-asking is the wrong UI/UX.

* A user may want to see the values entered for the first N arguments
when typing the (N+1)th.
* A user may want to fix a typo in the Nth argument when typing the (N+1)th.
* A user may want to recall the whole set of arguments from the
history, and optionally modify one or more of them.
* A user may want to switch to a different window or frame while
composing one of the arguments.

Interactive interface for more than one argument must be explicitly
designed. Asking for a more defaulting, more validating sequential
‘read-*’ is like asking Henry Ford for a faster horse.



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

* Re: how to speed up Lisp devel time
  2024-08-09 16:16                 ` Emanuel Berg
@ 2024-08-09 17:54                   ` Eli Zaretskii
  2024-08-09 18:56                     ` Christopher Dimech
  2024-08-09 21:47                     ` Emanuel Berg
  0 siblings, 2 replies; 32+ messages in thread
From: Eli Zaretskii @ 2024-08-09 17:54 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-devel

> From: Emanuel Berg <incal@dataswamp.org>
> Date: Fri, 09 Aug 2024 18:16:08 +0200
> 
> >> These all are handled by the 'p' interactive code. So all
> >> you need is this:
> >>
> >> (interactive "p")
> >
> > Okay, that is some improvement at last.
> 
> I spoke to soon. That is not the same as
> 
> (interactive (if (numberp current-prefix-arg)
>                  (list current-prefix-arg)
>                current-prefix-arg))

If you need to support a numeric optional argument, "p" is all you
need.  Anything else is redundant over-engineering at best.

> That, (interactive "p"), is the same as sending 1 on M-x, but
> here we want it to be the default behavior. Since nothing is
> stated explicitely.
> 
> M-x should be default, just as (function-name) should
> be default.
> 
> But it should be possible to do C-u 1 M-x to set 'end' to 1.

It makes no sense to have "M-x" do something different from
"C-u 1 M-x", when the argument says how many times to do some job.
This is why in Emacs we use this convention consistently in all
the commands.  You are free to use other conventions in your code,
but that's not how Emacs commands work, and we require any command
to adhere to that convention.

When you want to allow the user to specify more than a single argument
to a command, things usually become much more complicated, so it is
best to avoid such commands.  If you must do that, a separate prompt
for each argument is better than tricky conventions regarding the
value of prefix arg.



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

* Re: how to speed up Lisp devel time
  2024-08-09 16:19               ` Emanuel Berg
@ 2024-08-09 18:00                 ` Eli Zaretskii
  2024-08-09 18:54                   ` Christopher Dimech
  2024-08-09 22:00                   ` Emanuel Berg
  0 siblings, 2 replies; 32+ messages in thread
From: Eli Zaretskii @ 2024-08-09 18:00 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-devel

> From: Emanuel Berg <incal@dataswamp.org>
> Date: Fri, 09 Aug 2024 18:19:58 +0200
> 
> (defun draw-scale (&optional end step i)
>   (interactive (if (numberp current-prefix-arg)
>                    (list current-prefix-arg)
>                  current-prefix-arg))

Using "p" doesn't prevent you from testing the value of
current-prefix-arg, if that is what you want to do.

But in general, having commands with more than one optional argument
(two when the command acts on a region) is not recommended, because it
complicates the interactive usage.



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

* how to speed up Lisp devel time
  2024-08-09 18:00                 ` Eli Zaretskii
@ 2024-08-09 18:54                   ` Christopher Dimech
  2024-08-09 22:17                     ` Emanuel Berg
  2024-08-09 22:00                   ` Emanuel Berg
  1 sibling, 1 reply; 32+ messages in thread
From: Christopher Dimech @ 2024-08-09 18:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Emanuel Berg, emacs-devel


> Sent: Saturday, August 10, 2024 at 6:00 AM
> From: "Eli Zaretskii" <eliz@gnu.org>
> To: "Emanuel Berg" <incal@dataswamp.org>
> Cc: emacs-devel@gnu.org
> Subject: Re: how to speed up Lisp devel time
>
> > From: Emanuel Berg <incal@dataswamp.org>
> > Date: Fri, 09 Aug 2024 18:19:58 +0200
> >
> > (defun draw-scale (&optional end step i)
> >   (interactive (if (numberp current-prefix-arg)
> >                    (list current-prefix-arg)
> >                  current-prefix-arg))
>
> Using "p" doesn't prevent you from testing the value of
> current-prefix-arg, if that is what you want to do.
>
> But in general, having commands with more than one optional argument
> (two when the command acts on a region) is not recommended, because it
> complicates the interactive usage.

This complexity is not inherently negative, and there are compelling
reasons to embrace it in certain situations.  Commands with multiple
optional arguments offer greater flexibility.

They allow users to fine-tune the behavior of a command without needing
multiple versions of the same command.  For example, a command that
processes text in a region might need to handle different edge cases or
modes of operation.  Providing multiple optional arguments, users can
specify exactly how they want the command to behave, which can be more
efficient and powerful than using multiple commands or a simpler interface.
And more advanced users often seek out commands that provide granular control.

In an environment like Emacs, which is known for its powerful, customizable,
and sometimes complex commands, advanced users often appreciate the ability
to use optional arguments.

Embrace complexity, complexity is not inherently bad, it's a trade-off.
Proper documentation, intuitive default behaviors, and a clear understanding
of when and how to use optional arguments can ensure that this complexity
enhances the user experience rather than detracting from it.




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

* how to speed up Lisp devel time
  2024-08-09 17:54                   ` Eli Zaretskii
@ 2024-08-09 18:56                     ` Christopher Dimech
  2024-08-09 21:57                       ` Emanuel Berg
  2024-08-09 21:47                     ` Emanuel Berg
  1 sibling, 1 reply; 32+ messages in thread
From: Christopher Dimech @ 2024-08-09 18:56 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Emanuel Berg, emacs-devel

> Sent: Saturday, August 10, 2024 at 5:54 AM
> From: "Eli Zaretskii" <eliz@gnu.org>
> To: "Emanuel Berg" <incal@dataswamp.org>
> Cc: emacs-devel@gnu.org
> Subject: Re: how to speed up Lisp devel time
>
> > From: Emanuel Berg <incal@dataswamp.org>
> > Date: Fri, 09 Aug 2024 18:16:08 +0200
> >
> > >> These all are handled by the 'p' interactive code. So all
> > >> you need is this:
> > >>
> > >> (interactive "p")
> > >
> > > Okay, that is some improvement at last.
> >
> > I spoke to soon. That is not the same as
> >
> > (interactive (if (numberp current-prefix-arg)
> >                  (list current-prefix-arg)
> >                current-prefix-arg))
>
> If you need to support a numeric optional argument, "p" is all you
> need.  Anything else is redundant over-engineering at best.
>
> > That, (interactive "p"), is the same as sending 1 on M-x, but
> > here we want it to be the default behavior. Since nothing is
> > stated explicitely.
> >
> > M-x should be default, just as (function-name) should
> > be default.
> >
> > But it should be possible to do C-u 1 M-x to set 'end' to 1.
>
> It makes no sense to have "M-x" do something different from
> "C-u 1 M-x", when the argument says how many times to do some job.
> This is why in Emacs we use this convention consistently in all
> the commands.  You are free to use other conventions in your code,
> but that's not how Emacs commands work, and we require any command
> to adhere to that convention.
>
> When you want to allow the user to specify more than a single argument
> to a command, things usually become much more complicated, so it is
> best to avoid such commands.  If you must do that, a separate prompt
> for each argument is better than tricky conventions regarding the
> value of prefix arg.

I fully agree.  Separate prompts for each argument is better, the way things
should be.



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

* Re: how to speed up Lisp devel time
  2024-08-09 17:27                 ` Yuri Khan
@ 2024-08-09 21:21                   ` Emanuel Berg
  2024-08-10  2:14                   ` Emanuel Berg
  2024-08-10  4:32                   ` Emanuel Berg
  2 siblings, 0 replies; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 21:21 UTC (permalink / raw)
  To: emacs-devel

Yuri Khan wrote:

> If your command has three arguments, asking for them in
> succession with validation and re-asking is the wrong UI/UX.

? "Wrong"

How should one deal with inputted data that doesn't validate?

Saying this is wrong, and failed here, ask for another value.
Abort with C-g. I could use such an interface anyway and see
nothing wrong with it.

In a way, it already does that:

  (read-number "enter a string: ")

If I enter a string it says "Please enter a number.' It is the
same I suggest only one tiny step more involved to work for
arbitrary validation and not just for `numberp' or however
that works.

But one could also use the default value, or just do `error'.

> * A user may want to see the values entered for the first
> N arguments when typing the (N+1)th.
> * A user may want to fix a typo in the Nth argument when
> typing the (N+1)th.
> * A user may want to recall the whole set of arguments from
> the history, and optionally modify one or more of them.
> * A user may want to switch to a different window or frame
> while composing one of the arguments.

Okay? It will be even more "82 Elisp lines" but that would be
even better, sure.

> Interactive interface for more than one argument must be
> explicitly designed.

Oh, no. If you, or someone else, writes a great function,
macro or whatever to solve this it and setup a great
"interface interface" will all the fixings, will solve it for
many, many, many cases of one, two, three and so
on combinations.

There will always be one "odd man out" or bad apple, but just
because it is more than a certain number, then it can't be
automated, I don't believe that at all and I trust good
automation much more than (n) Elispers to all setup their own
stuff explicitely.

As for using it, no problem, especially with default values,
or history, one can just hit RET RET RET.

Depending on the command, there maybe should be a quicker way
to not have to do that as well, but that's another thing.

Inputting two or three values, well, to me anyway, that isn't
a problem.

Four or five - then it gets too boring so cannot be used for
functions that are used often, but of course that would be
possible as well. For example, to setup some LaTeX table with
tons of parameters. Absolutely possible and again, this can be
automated with an "interface interface", not to cover 100% but
that will cover many, many cases and can be tweaked for
many more.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 17:54                   ` Eli Zaretskii
  2024-08-09 18:56                     ` Christopher Dimech
@ 2024-08-09 21:47                     ` Emanuel Berg
  1 sibling, 0 replies; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 21:47 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii wrote:

>> (interactive (if (numberp current-prefix-arg)
>>                  (list current-prefix-arg)
>>                current-prefix-arg))
>
> If you need to support a numeric optional argument, "p" is
> all you need. Anything else is redundant over-engineering
> at best.

Not here, I want M-x to be the default behavior since the 1 is
implicit. The code you suggested isn't equivalent to mine.

>> That, (interactive "p"), is the same as sending 1 on M-x, but
>> here we want it to be the default behavior. Since nothing is
>> stated explicitely.
>> 
>> M-x should be default, just as (function-name) should
>> be default.
>> 
>> But it should be possible to do C-u 1 M-x to set 'end' to 1.
>
> It makes no sense to have "M-x" do something different from
> "C-u 1 M-x", when the argument says how many times to do
> some job.

The interface is very consistent and easy to understand:

For interactive as well as non-interactive use:

- no explicit data -> use default value;
  explicit data -> use it

- same default values

- same validation checks

> This is why in Emacs we use this convention consistently in
> all the commands.

Emacs has tons of conventions and I don't believe in that
method, to some extent - maybe - instead I believe in
automating stuff and have *the computer* check the soundness
of things rather than to put it as list in the documentation
and expect people to do it ever on.

;; This is a comment. Every comment should look like it

That is another thing, but no, I don't believe in that method.

But that besides the point, this whole thread isn't about
_this_ interface!

> You are free to use other conventions in your code, but
> that's not how Emacs commands work, and we require any
> command to adhere to that convention.

*sigh*

> When you want to allow the user to specify more than
> a single argument to a command, things usually become much
> more complicated, so it is best to avoid such commands.

...

> If you must do that, a separate prompt for each argument is
> better than tricky conventions regarding the value of
> prefix arg.

Tricky conventions that is

        M-x -  (expt 4 0) -  1 (instead, since implicit, use default) 
    C-u M-x -  (expt 4 1) -  4 (same)
C-u C-u M-x -  (expt 4 2) - 16 (same)
  C-u n M-x -                n (same)

Too tricky for you, okay. Whatever, it isn't for me and the
thread was, again, not about this particular interface, but
... ah, forget it.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 18:56                     ` Christopher Dimech
@ 2024-08-09 21:57                       ` Emanuel Berg
  0 siblings, 0 replies; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 21:57 UTC (permalink / raw)
  To: emacs-devel

Christopher Dimech wrote:

>> When you want to allow the user to specify more than
>> a single argument to a command, things usually become much
>> more complicated, so it is best to avoid such commands.
>> If you must do that, a separate prompt for each argument is
>> better than tricky conventions regarding the value of
>> prefix arg.
>
> I fully agree. Separate prompts for each argument is better,
> the way things should be.

"Separate prompts for each argument" is better than what?

Here, it isn't anything that _I want_.

And this thread isn't even about that. Emacs is underpowered
in this respect, and this simple interface setting a bunch of
default values and checking for some nonzero digits - 376
chars and cryptic Elisp - the `interactive' - just for that,
then just imagine if we would be prompting each variable! as you
suggest.

It is yet another area where Emacs is underpowered and this
shows it.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 18:00                 ` Eli Zaretskii
  2024-08-09 18:54                   ` Christopher Dimech
@ 2024-08-09 22:00                   ` Emanuel Berg
  1 sibling, 0 replies; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 22:00 UTC (permalink / raw)
  To: emacs-devel

Eli Zaretskii wrote:

> But in general, having commands with more than one optional
> argument (two when the command acts on a region) is not
> recommended, because it complicates the interactive usage.

Okay, I've had it with this routine.

I don't know who set you up, or why you feel the need to say
I'm wrong 20 times for every single thread where I'm active,
but so be it.

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 18:54                   ` Christopher Dimech
@ 2024-08-09 22:17                     ` Emanuel Berg
  0 siblings, 0 replies; 32+ messages in thread
From: Emanuel Berg @ 2024-08-09 22:17 UTC (permalink / raw)
  To: emacs-devel

Christopher Dimech wrote:

> This complexity is not inherently negative, and there are
> compelling reasons to embrace it in certain situations.
> Commands with multiple optional arguments offer
> greater flexibility.

Eh, three arguments with default values, "this complexity"?

Actually, because of the Elisp limitation that optional
arguments must be last, in sequence, there are many functions
with three - or more - optional arguments.

If this is news to you:

 - there are 2058 hits for '&optional .* .* .*' in the
   Emacs source,

- 194 seems to be interactive.

Yeah, these commands are imperfect by definition but it is
clear there are many, many such cases of Elisp, not the least
in the Emacs core source.

~/src/emacs $ grep '&optional .* .* .*' **/*.el | wc -l
2058

~/serc/emacs $ grep -A 3 '&optional .* .*' **/*.el | grep '(interactive' | wc -l
194

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 17:27                 ` Yuri Khan
  2024-08-09 21:21                   ` Emanuel Berg
@ 2024-08-10  2:14                   ` Emanuel Berg
  2024-08-10  6:01                     ` Yuri Khan
  2024-08-10  4:32                   ` Emanuel Berg
  2 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-10  2:14 UTC (permalink / raw)
  To: emacs-devel

Yuri Khan wrote:

> Interactive interface for more than one argument must be explicitly
> designed. Asking for a more defaulting, more validating sequential
> 'read-*'

What do you mean by that, at some point a human has to do it?

And that point is more than one?

Hardly, even in the Emacs source, using `interface', there are
tons of such interfaces setup with easy.

And, note that I'm not proposing what you say, I'm proposing
an interface interface so that you can set it up the way
you like.

That's an explicit setup. Or, can only Lisp do that? But yes,
many interfaces would be similar.

Let me hear it then, can you show me a bunch of "impossible"
interfaces of three (well, one is enough) that cannot be
automated, cannot be derived, and cannot be setup by a tool?

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




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

* Re: how to speed up Lisp devel time
  2024-08-09 17:27                 ` Yuri Khan
  2024-08-09 21:21                   ` Emanuel Berg
  2024-08-10  2:14                   ` Emanuel Berg
@ 2024-08-10  4:32                   ` Emanuel Berg
  2024-08-10  5:58                     ` Eli Zaretskii
  2 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-10  4:32 UTC (permalink / raw)
  To: emacs-devel

Yuri Khan wrote:

> Asking for a more defaulting, more validating sequential
> 'read-*' is like asking Henry Ford for a faster horse.

Work on realizing the DRAW syntax has begun. (DRAW stands for
Dorks Run Away when they face a Warrior.)

The actual tool OTOH is called iihf, or "imbecille individuals
have fled".

But this is just a sneak peak, no Emacs devel on emacs-devel.

But again please post the "impossible" interfaces that cannot
be automated, but must be setup explicitly with Lisp, if that
is what you meant (?).

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

(require 'calc-ext)

;; [
;;   end  :d 73     :r 0<            :pa mxd od
;;   step :d end/10 :r 0<  :r 2-10 c
;;   i    :d 0      :r 0<=
;; ]

(defalias '^ #'expt)

(defun infx (str)
  (let* ((exp (math-read-expr str))
         (fun (car exp))
         (new (cons (intern (caar (cl-member fun math-expr-opers :key #'cadr :test #'equal)))
                    (cdr exp))))
    (apply (car new) (cdr new))))

;; (infx "2 < 3") ; t
;; (infx "2 + 3") ; 5
;; (infx "2 * 3") ; 6
;; (infx   "2^3") ; 8  (must have above alias for this)
;; (infx  "2**3") ; 8  (same)

(defun in-intv (n lo hi &optional mask)
  (unless mask
    (setq mask 3))
  (= 1 (calcFunc-in n (calcFunc-intv mask lo hi))))

;; mask: (< < 0) (<= < 1) (< <= 2) (<= <= 3)

;; (in-intv   2 2 10) ; t
;; (in-intv  10 2 10) ; t
;; (in-intv   0 2 10) ; nil
;; (in-intv 700 2 10) ; nil

(provide 'iihf)

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




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

* Re: how to speed up Lisp devel time
  2024-08-10  4:32                   ` Emanuel Berg
@ 2024-08-10  5:58                     ` Eli Zaretskii
  0 siblings, 0 replies; 32+ messages in thread
From: Eli Zaretskii @ 2024-08-10  5:58 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: emacs-devel

> From: Emanuel Berg <incal@dataswamp.org>
> Date: Sat, 10 Aug 2024 06:32:24 +0200
> 
> The actual tool OTOH is called iihf, or "imbecille individuals
> have fled".

Please stop offending people here, if you want your posts to be
allowed on the list.  This kind of language, when aimed at others, is
unacceptable here.



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

* Re: how to speed up Lisp devel time
  2024-08-10  2:14                   ` Emanuel Berg
@ 2024-08-10  6:01                     ` Yuri Khan
  2024-08-10  6:08                       ` Emanuel Berg
  0 siblings, 1 reply; 32+ messages in thread
From: Yuri Khan @ 2024-08-10  6:01 UTC (permalink / raw)
  To: emacs-devel

On Sat, 10 Aug 2024 at 12:21, Emanuel Berg <incal@dataswamp.org> wrote:

> > Interactive interface for more than one argument must be explicitly
> > designed. Asking for a more defaulting, more validating sequential
> > 'read-*'
>
> What do you mean by that, at some point a human has to do it?
>
> And that point is more than one?
>
> Hardly, even in the Emacs source, using `interface', there are
> tons of such interfaces setup with easy.
>
> And, note that I'm not proposing what you say, I'm proposing
> an interface interface so that you can set it up the way
> you like.

I am not against a way to describe a function’s argument types,
validation conditions and defaults per se.

I *am* against a specific user interface technique that takes those
descriptions and asks for each argument in a sequence of modal
prompts.

In my opinion, a prompt is okay for one single argument. Two, like in
‘query-replace’, is straining it somewhat; a recent version of Emacs
made it possible to recall both arguments from history at the same
time, and that was an improvement. Three prompts in a sequence is
something I would not be able to use without irritation. Now that
‘transient’ is in core, some kinds of complex interactive interfaces
can be based on it where necessary.



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

* Re: how to speed up Lisp devel time
  2024-08-10  6:01                     ` Yuri Khan
@ 2024-08-10  6:08                       ` Emanuel Berg
  2024-08-10  6:44                         ` Yuri Khan
  0 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-10  6:08 UTC (permalink / raw)
  To: emacs-devel

Yuri Khan wrote:

> In my opinion, a prompt is okay for one single argument.
> Two, like in 'query-replace', is straining it somewhat;
> a recent version of Emacs made it possible to recall both
> arguments from history at the same time, and that was an
> improvement. Three prompts in a sequence is something
> I would not be able to use without irritation.

Yes, doing many times but like a few times a day?

Also, with default it can be just RET RET RET.

> Now that 'transient' is in core, some kinds of complex
> interactive interfaces can be based on it where necessary.

How do you want to input 3 args then, on the same line

arg1 arg2 arg3 RET
--------------

That is, of course, possible. What information would you like
outputted, and how, for three integers with default values and
some tests to validate?

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




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

* Re: how to speed up Lisp devel time
  2024-08-10  6:08                       ` Emanuel Berg
@ 2024-08-10  6:44                         ` Yuri Khan
  2024-08-10  7:22                           ` Emanuel Berg
  0 siblings, 1 reply; 32+ messages in thread
From: Yuri Khan @ 2024-08-10  6:44 UTC (permalink / raw)
  To: emacs-devel

On Sat, 10 Aug 2024 at 13:11, Emanuel Berg <incal@dataswamp.org> wrote:

> > Now that 'transient' is in core, some kinds of complex
> > interactive interfaces can be based on it where necessary.
>
> How do you want to input 3 args then, on the same line
>
> arg1 arg2 arg3 RET
> --------------

I do not necessarily want them on the same line. Depending on how
often or rarely I use that command, I might want labels reminding me
what each argument is for. Depending on how short or long the typical
value is, I might want separate lines or even separate multi-line
inputs.

Do a query-replace. Then invoke it again and press M-p. The last
search string and replacement string are recalled to the prompt at the
same time, separated with an intangible arrow label.

> That is, of course, possible. What information would you like
> outputted, and how, for three integers with default values and
> some tests to validate?

If defaults are reasonable and I rarely need to stray from them
(alternatively, if the last used value gets saved in history and
automatically reused), I would like not to enter them at all, and not
even a RET to acknowledge the default. When I do need to change them,
I’d see that option at the transient screen, type the corresponding
key and type the new value, and press RET. At that point, validation
can be performed, as long as C-g returns me to the transient with the
value reverted to its previous valid value (rather than canceling the
whole command).

Have you used Magit? Do a diff or log, see all the options they offer.



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

* Re: how to speed up Lisp devel time
  2024-08-10  6:44                         ` Yuri Khan
@ 2024-08-10  7:22                           ` Emanuel Berg
  2024-08-10  7:51                             ` Emanuel Berg
  0 siblings, 1 reply; 32+ messages in thread
From: Emanuel Berg @ 2024-08-10  7:22 UTC (permalink / raw)
  To: emacs-devel

Yuri Khan wrote:

> I do not necessarily want them on the same line.
> Depending on how often or rarely I use that command, I might
> want labels reminding me what each argument is for.

You got: same line, with labels.

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

(require 'cl-lib)

;; [
;;   end  :d 73     :r 0<            :pa mxd od
;;   step :d end/10 :r 0<  :r 2-10 c
;;   i    :d 0      :r 0<=
;; ]

(defun input-args (&optional num-str)
  (interactive)
  (let* (( end-def 73)
         (step-def (max 10 (min 2 (/ end-def 10))))
         (   i-def 0)
         (def (list end-def step-def i-def))
         (def-str (format "%s %s %s" (nth 0 def) (nth 1 def) (nth 2 def)))
         (str (or num-str
                  (read-string (format "1-3 numbers [RET %s]: " def-str)
                               nil nil def-str)))
         (spl (split-string str " "))
         (res (cl-mapcar (lambda (a) (string-to-number a)) spl))
         (all `(,@res ,@(cl-subseq def (length res))))
         (end  (nth 0 all))
         (step (nth 1 all))
         (   i (nth 2 all)))
    (unless (and (<  0  end)
                 (<  0 step)
                 (<= 0    i))
      (error "DNC"))
    (let ((min  2)
          (max 10))
      (setq step (cond ( (< step min)  min )
                       ( (< max  step) max )
                       ( step )))
      (list end step i))))

;; (input-args) RET        ; 73 10 0
;; (input-args) 73 100 RET ; 73 10 0
;; (input-args) 73 1 RET   ; 73  2 0
;; (input-args) 55 RET     ; 55 10 0
;; (input-args "1 2 3")    ;  1  2 3
;; (input-args "1 2")      ;  1  2 0
;; (input-args "1")        ;  1 10 0
;; (input-args "-1")       ;     DNC
;; (input-args "1 -1")     ;     DNC
;; (input-args "1 1 0")    ;   1 2 0
;; (input-args "1 1 -1")   ;     DNC

(provide 'iihf)

> Do a query-replace. Then invoke it again and press M-p.
> The last search string and replacement string are recalled
> to the prompt at the same time, separated with an intangible
> arrow label.

Yes, I see. I am good at → it :)

>> That is, of course, possible. What information would you
>> like outputted, and how, for three integers with default
>> values and some tests to validate?
>
> If defaults are reasonable and I rarely need to stray from
> them (alternatively, if the last used value gets saved in
> history and automatically reused), I would like not to enter
> them at all, and not even a RET to acknowledge the default.
> When I do need to change them, I'd see that option at the
> transient screen, type the corresponding key and type the
> new value, and press RET. At that point, validation can be
> performed, as long as C-g returns me to the transient with
> the value reverted to its previous valid value (rather than
> canceling the whole command).
>
> Have you used Magit? Do a diff or log, see all the options
> they offer.

I'm not familiar with transient and Magit, but default values
and validation are all solved above.

But do tell exactly what interface you like, after you try it.

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




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

* Re: how to speed up Lisp devel time
  2024-08-10  7:22                           ` Emanuel Berg
@ 2024-08-10  7:51                             ` Emanuel Berg
  0 siblings, 0 replies; 32+ messages in thread
From: Emanuel Berg @ 2024-08-10  7:51 UTC (permalink / raw)
  To: emacs-devel

>> I do not necessarily want them on the same line.
>> Depending on how often or rarely I use that command,
>> I might want labels reminding me what each argument is for.
>
> You got: same line, with labels.

There, at least we solved the problem for my function, now
with an interface setup of 1079 chars :)

Usually it isn't that hard to go from hard-coded individual
case to the general case, well, it isn't as hard as one
thinks anyway. 

Good, because this time - I think it's gonna be pretty hard :)

Zzz

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

(require 'cl-lib)

;; [
;;   end  :d 73     :r 0<            :pa mxd od
;;   step :d end/10 :r 0<  :r 2-10 c
;;   i    :d 0      :r 0<=
;; ]

(defun input-args (&optional do-ps end step i)
  (interactive)
  (let* (( end-def 73)
         (step-def (max 10 (min 2 (/ end-def 10))))
         (   i-def 0)
         (def (list end-def step-def i-def))
         (num-str (format "%s %s %s" (or end end-def) (or step step-def) (or i i-def)))
         (def-str (format "%s %s %s" (nth 0 def) (nth 1 def) (nth 2 def)))
         (str (if do-ps
                  (read-string (format "end step i [RET %s]: " def-str)
                               nil nil def-str)
                num-str))
         (spl (split-string str " "))
         (res (cl-mapcar (lambda (a) (string-to-number a)) spl))
         (all `(,@res ,@(cl-subseq def (length res))))
         (end  (nth 0 all))
         (step (nth 1 all))
         (   i (nth 2 all)))
    (unless (and (<  0  end)
                 (<  0 step)
                 (<= 0    i))
      (error "DNC"))
    (let ((min  2)
          (max 10))
      (setq step (cond ( (< step min)  min )
                       ( (< max  step) max )
                       ( step )))
      (list end step i))))

;; (input-args t)          RET  ; 73 10 0
;; (input-args t)  73 100  RET  ; 73 10 0
;; (input-args t)  73   1  RET  ; 73  2 0
;; (input-args t)  55      RET  ; 55 10 0
;; (input-args nil  1   2    3) ;  1  2 3
;; (input-args nil  1   2)      ;  1  2 0
;; (input-args nil  1)          ;  1 10 0
;; (input-args nil -1)          ;     DNC
;; (input-args nil  1  -1)      ;     DNC
;; (input-args nil  1   1   -1) ;     DNC
;; (input-args nil  1   1    0) ;  1  2 0

(provide 'iihf)

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




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

end of thread, other threads:[~2024-08-10  7:51 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-09  7:16 how to speed up Lisp devel time Emanuel Berg
2024-08-09  7:24 ` Eli Zaretskii
2024-08-09  7:39   ` Emanuel Berg
2024-08-09 10:43     ` Eli Zaretskii
2024-08-09 11:18       ` Emanuel Berg
2024-08-09 12:02         ` Eli Zaretskii
2024-08-09 13:54           ` Emanuel Berg
2024-08-09 14:58             ` Eli Zaretskii
2024-08-09 16:03               ` Emanuel Berg
2024-08-09 16:16                 ` Emanuel Berg
2024-08-09 17:54                   ` Eli Zaretskii
2024-08-09 18:56                     ` Christopher Dimech
2024-08-09 21:57                       ` Emanuel Berg
2024-08-09 21:47                     ` Emanuel Berg
2024-08-09 17:27                 ` Yuri Khan
2024-08-09 21:21                   ` Emanuel Berg
2024-08-10  2:14                   ` Emanuel Berg
2024-08-10  6:01                     ` Yuri Khan
2024-08-10  6:08                       ` Emanuel Berg
2024-08-10  6:44                         ` Yuri Khan
2024-08-10  7:22                           ` Emanuel Berg
2024-08-10  7:51                             ` Emanuel Berg
2024-08-10  4:32                   ` Emanuel Berg
2024-08-10  5:58                     ` Eli Zaretskii
2024-08-09 14:59             ` Eduardo Ochs
2024-08-09 16:19               ` Emanuel Berg
2024-08-09 18:00                 ` Eli Zaretskii
2024-08-09 18:54                   ` Christopher Dimech
2024-08-09 22:17                     ` Emanuel Berg
2024-08-09 22:00                   ` Emanuel Berg
2024-08-09  8:24   ` Emanuel Berg
2024-08-09 10:36     ` Christopher Dimech

Code repositories for project(s) associated with this public inbox

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

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