unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Making a function than can only be used interactively
@ 2022-07-03 19:16 carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 19:28 ` Bruno Barbier
       [not found] ` <N64WnlX--3-2@missing-mail-id>
  0 siblings, 2 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-03 19:16 UTC (permalink / raw)
  To: Help Gnu Emacs


Is it possible to make an interactive function than can only be used interactively?


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

* Re: Making a function than can only be used interactively
  2022-07-03 19:16 carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-03 19:28 ` Bruno Barbier
       [not found] ` <N64WnlX--3-2@missing-mail-id>
  1 sibling, 0 replies; 58+ messages in thread
From: Bruno Barbier @ 2022-07-03 19:28 UTC (permalink / raw)
  To: carlmarcos, Help Gnu Emacs


carlmarcos--- via Users list for the GNU Emacs text editor
<help-gnu-emacs@gnu.org> writes:

> Is it possible to make an interactive function than can only be used interactively?

I'm not sure I understand your question. A function, that may be called
interactively, is called a "command" in Emacs.  And a command can
definitely be called interactively, either by using it's name (using
M-x) or binding it to a key.

See:
    (info "(elisp) Defining Commands")

Does it answer your question ?


Bruno



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

* Re: Making a function than can only be used interactively
       [not found] ` <N64WnlX--3-2@missing-mail-id>
@ 2022-07-03 19:36   ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 19:53     ` Tassilo Horn
                       ` (2 more replies)
  0 siblings, 3 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-03 19:36 UTC (permalink / raw)
  To: Bruno Barbier; +Cc: Help Gnu Emacs


Jul 3, 2022, 19:28 by brubar.cs@gmail.com:

>
> carlmarcos--- via Users list for the GNU Emacs text editor
> <help-gnu-emacs@gnu.org> writes:
>
>> Is it possible to make an interactive function than can only be used interactively?
>>
>
> I'm not sure I understand your question. A function, that may be called
> interactively, is called a "command" in Emacs.  And a command can
> definitely be called interactively, either by using it's name (using
> M-x) or binding it to a key.
>
I do not want people to use the function non-interactively.


> See:
>  (info "(elisp) Defining Commands")
>
> Does it answer your question ?
>
>
> Bruno
>



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

* Re: Making a function than can only be used interactively
  2022-07-03 19:36   ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-03 19:53     ` Tassilo Horn
  2022-07-03 20:17       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-05 23:13       ` Emanuel Berg
  2022-07-03 20:14     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-07-04  1:06     ` Po Lu
  2 siblings, 2 replies; 58+ messages in thread
From: Tassilo Horn @ 2022-07-03 19:53 UTC (permalink / raw)
  To: carlmarcos; +Cc: Bruno Barbier, help-gnu-emacs

carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes:

>>> Is it possible to make an interactive function than can only be used
>>> interactively?
>>
>> I'm not sure I understand your question. A function, that may be
>> called interactively, is called a "command" in Emacs.  And a command
>> can definitely be called interactively, either by using it's name
>> (using M-x) or binding it to a key.
>>
> I do not want people to use the function non-interactively.

How restrictive is that! :-)

--8<---------------cut here---------------start------------->8---
(defun only-interactive ()
  (interactive)
  (if (called-interactively-p 'interactive)
      42
    (error "You may not call me")))

(only-interactive)
;;=> Debugger entered--Lisp error: (error "You may not call me")

(call-interactively 'only-interactive)
;;=> 42

(cl-letf (((symbol-function 'called-interactively-p)
           (lambda (&rest _args) t)))
  (only-interactive))
;;=> 42
--8<---------------cut here---------------end--------------->8---

So as you see, there are many ways around it.

Bye,
Tassilo



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

* Re: Making a function than can only be used interactively
  2022-07-03 19:36   ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 19:53     ` Tassilo Horn
@ 2022-07-03 20:14     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-07-03 20:27       ` carlmarcos--- via Users list for the GNU Emacs text editor
                         ` (2 more replies)
  2022-07-04  1:06     ` Po Lu
  2 siblings, 3 replies; 58+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-07-03 20:14 UTC (permalink / raw)
  To: help-gnu-emacs

> I do not want people to use the function non-interactively.

An interactive call is fundamentally a combination of "run the
interactive spec to get the args, and then call the function with those
args".  So, in a sense you can't avoid it.

But you can discourage non-interactive calls in various ways, depending
on how important you think it is.  The most standard way is to use

    (declare (interactive-only <foo>))

so that the compiler will emit a warning when it sees a non-interactive
call to that function (<foo> is the replacement you recommend for
non-interactive calls).

A more "forceful" way is to wrap your interactive function inside
a trivial keyboard macro:

    (defalias 'my-command
              (vector (lambda (...)
                        (interactive ..)
                        ...)))

this way `my-command` is a valid command but it's not a valid function.
I'd not recommend such a measure, tho.


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-03 19:53     ` Tassilo Horn
@ 2022-07-03 20:17       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-04  4:51         ` Tassilo Horn
  2022-07-05 23:13       ` Emanuel Berg
  1 sibling, 1 reply; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-03 20:17 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Bruno Barbier, help-gnu-emacs


Jul 3, 2022, 19:53 by tsdh@gnu.org:

> carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes:
>
>>>> Is it possible to make an interactive function than can only be used
>>>> interactively?
>>>>
>>>
>>> I'm not sure I understand your question. A function, that may be
>>> called interactively, is called a "command" in Emacs.  And a command
>>> can definitely be called interactively, either by using it's name
>>> (using M-x) or binding it to a key.
>>>
>> I do not want people to use the function non-interactively.
>>
>
> How restrictive is that! :-)
>
> --8<---------------cut here---------------start------------->8---
> (defun only-interactive ()
>  (interactive)
>  (if (called-interactively-p 'interactive)
>  42
>  (error "You may not call me")))
>
> (only-interactive)
> ;;=> Debugger entered--Lisp error: (error "You may not call me")
>

Focusing on the former two `(if (called-interactively-p 'interactive)` and
`(only-interactive)`.  I would need some meatier examples.  

Using `(if (called-interactively-p 'interactive)`, would I need to put the entire 
implementations inside the if `statement`?


> (call-interactively 'only-interactive)
> ;;=> 42
>
> (cl-letf (((symbol-function 'called-interactively-p)
>  (lambda (&rest _args) t)))
>  (only-interactive))
> ;;=> 42
> --8<---------------cut here---------------end--------------->8---
>
> So as you see, there are many ways around it.
>
> Bye,
> Tassilo
>



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

* Re: Making a function than can only be used interactively
  2022-07-03 20:14     ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-07-03 20:27       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 20:51       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 21:29       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2 siblings, 0 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-03 20:27 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs


Jul 3, 2022, 20:14 by help-gnu-emacs@gnu.org:

>> I do not want people to use the function non-interactively.
>>
>
> An interactive call is fundamentally a combination of "run the
> interactive spec to get the args, and then call the function with those
> args".  So, in a sense you can't avoid it.
>
> But you can discourage non-interactive calls in various ways, depending
> on how important you think it is.  The most standard way is to use
>
>  (declare (interactive-only <foo>))
>
> so that the compiler will emit a warning when it sees a non-interactive
> call to that function (<foo> is the replacement you recommend for
> non-interactive calls).
>
What I have done is make a non-interactive function, followed by an interactive wrapper.
Some experience showed me that handling everything in a single function can get extremely
complicated.


> A more "forceful" way is to wrap your interactive function inside
> a trivial keyboard macro:
>
>  (defalias 'my-command
>  (vector (lambda (...)
>  (interactive ..)
>  ...)))
>
> this way `my-command` is a valid command but it's not a valid function.
> I'd not recommend such a measure, tho.
>
>
>  Stefan
>



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

* Re: Making a function than can only be used interactively
  2022-07-03 20:14     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-07-03 20:27       ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-03 20:51       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 21:18         ` Stefan Monnier
  2022-07-03 21:29       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2 siblings, 1 reply; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-03 20:51 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs


Jul 3, 2022, 20:14 by help-gnu-emacs@gnu.org:

>> I do not want people to use the function non-interactively.
>>
>
> An interactive call is fundamentally a combination of "run the
> interactive spec to get the args, and then call the function with those
> args".  So, in a sense you can't avoid it.
>
> But you can discourage non-interactive calls in various ways, depending
> on how important you think it is.  The most standard way is to use
>
>  (declare (interactive-only <foo>))
>
Others have suggested 

(if (called-interactively-p 'interactive)

and

(only-interactive)

But I see how your `(declare (interactive-only <foo>))` statement would work better.


> so that the compiler will emit a warning when it sees a non-interactive
> call to that function (<foo> is the replacement you recommend for
> non-interactive calls).
>
> A more "forceful" way is to wrap your interactive function inside
> a trivial keyboard macro:
>
>  (defalias 'my-command
>  (vector (lambda (...)
>  (interactive ..)
>  ...)))
>
> this way `my-command` is a valid command but it's not a valid function.
> I'd not recommend such a measure, tho.
>
>
>  Stefan
>



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

* Re: Making a function than can only be used interactively
  2022-07-03 20:51       ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-03 21:18         ` Stefan Monnier
  0 siblings, 0 replies; 58+ messages in thread
From: Stefan Monnier @ 2022-07-03 21:18 UTC (permalink / raw)
  To: carlmarcos; +Cc: help-gnu-emacs

> Others have suggested 
>
> (if (called-interactively-p 'interactive)

`called-interactively-p` is inherently hackish and brittle, so better
stay away from it unless you're really stuck with no other way out.


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-03 20:14     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-07-03 20:27       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 20:51       ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-03 21:29       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 22:01         ` Stefan Monnier via Users list for the GNU Emacs text editor
  2 siblings, 1 reply; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-03 21:29 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs


Jul 3, 2022, 20:14 by help-gnu-emacs@gnu.org:

>> I do not want people to use the function non-interactively.
>>
>
> An interactive call is fundamentally a combination of "run the
> interactive spec to get the args, and then call the function with those
> args".  So, in a sense you can't avoid it.
>
> But you can discourage non-interactive calls in various ways, depending
> on how important you think it is.  The most standard way is to use
>
>  (declare (interactive-only <foo>))
>
> so that the compiler will emit a warning when it sees a non-interactive
> call to that function (<foo> is the replacement you recommend for
> non-interactive calls).
>
I need some clarification about  (<foo> is the replacement you recommend for
non-interactive calls).

Thought that (declare (interactive-only <foo>)) specifies <foo> to work only interactively.
Thus, what is the "replacement" about?




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

* Re: Making a function than can only be used interactively
  2022-07-03 21:29       ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-03 22:01         ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-07-03 22:45           ` carlmarcos--- via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 58+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-07-03 22:01 UTC (permalink / raw)
  To: help-gnu-emacs

> Thought that (declare (interactive-only <foo>)) specifies <foo> to
> work only interactively.  Thus, what is the "replacement" about?

No, the function that's declared to be `interactive-only` is the
function in which you place this `declare`.  The <foo> is used in the
warning's text to say something like "<blabla> is for interactive only;
use <foo> instead".

A `grep '(interactive-only' **/*.el` in Emacs's source code will give
you some examples.


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-03 22:01         ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-07-03 22:45           ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-04  1:13             ` Stefan Monnier
       [not found]             ` <jwvczelllyq.fsf-monnier+emacs@gnu.org-N65lQ2m----2>
  0 siblings, 2 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-03 22:45 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs


Jul 3, 2022, 22:01 by help-gnu-emacs@gnu.org:

>> Thought that (declare (interactive-only <foo>)) specifies <foo> to
>> work only interactively.  Thus, what is the "replacement" about?
>>
>
> No, the function that's declared to be `interactive-only` is the
> function in which you place this `declare`.  The <foo> is used in the
> warning's text to say something like "<blabla> is for interactive only;
> use <foo> instead".
>
> A `grep '(interactive-only' **/*.el` in Emacs's source code will give
> you some examples.
>
I have seen 

(declare (interactive-only t))

(interactive-only "use `font-lock-ensure' or `font-lock-flush' instead."))

(declare (interactive-only delete-char))

I am still unsure because I have done

(declare (interactive-only arktika-automated-workbench))

before `(interactive "P")` in a function `arktika-workbench`.

`arktika-automated-workbench` is the non-interactive function whilst
 `arktika-workbench` is an interactive wrapper.

Yet when I do `(arktika-workbench)` in my init file, the interactive function
`arktika-workbench` still gets executed.


>
>  Stefan
>



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

* Re: Making a function than can only be used interactively
  2022-07-03 19:36   ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-03 19:53     ` Tassilo Horn
  2022-07-03 20:14     ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-07-04  1:06     ` Po Lu
  2 siblings, 0 replies; 58+ messages in thread
From: Po Lu @ 2022-07-04  1:06 UTC (permalink / raw)
  To: carlmarcos--- via Users list for the GNU Emacs text editor
  Cc: Bruno Barbier, carlmarcos

carlmarcos--- via Users list for the GNU Emacs text editor
<help-gnu-emacs@gnu.org> writes:

> I do not want people to use the function non-interactively.

Then throw an error if not `called-interactively-p'.

But see the doc string for caveats.



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

* Re: Making a function than can only be used interactively
  2022-07-03 22:45           ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-04  1:13             ` Stefan Monnier
       [not found]             ` <jwvczelllyq.fsf-monnier+emacs@gnu.org-N65lQ2m----2>
  1 sibling, 0 replies; 58+ messages in thread
From: Stefan Monnier @ 2022-07-04  1:13 UTC (permalink / raw)
  To: carlmarcos; +Cc: help-gnu-emacs

> Yet when I do `(arktika-workbench)` in my init file, the interactive function
> `arktika-workbench` still gets executed.

Why wouldn't it?  As I said the `interactive-only` declaration only
causes the byte-compiler (and hence flymake) to warn about
non-interactive uses of the function.




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

* Re: Making a function than can only be used interactively
  2022-07-03 20:17       ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-04  4:51         ` Tassilo Horn
  0 siblings, 0 replies; 58+ messages in thread
From: Tassilo Horn @ 2022-07-04  4:51 UTC (permalink / raw)
  To: carlmarcos; +Cc: Bruno Barbier, help-gnu-emacs

carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes:

>>> I do not want people to use the function non-interactively.
>>
>> How restrictive is that! :-)
>>
>> --8<---------------cut here---------------start------------->8---
>> (defun only-interactive ()
>>  (interactive)
>>  (if (called-interactively-p 'interactive)
>>  42
>>  (error "You may not call me")))
>>
>> (only-interactive)
>> ;;=> Debugger entered--Lisp error: (error "You may not call me")
>>
>
> Focusing on the former two `(if (called-interactively-p 'interactive)` and
> `(only-interactive)`.  I would need some meatier examples.  
>
> Using `(if (called-interactively-p 'interactive)`, would I need to put
> the entire implementations inside the if `statement`?

Yes, the 42 would become a (progn ...).  Or just do

  (interactive)
  (unless (called-interactively-p 'interactive)
    (error "You may not call me from lisp"))

at the beginning of the defun followed by your "normal" code.

But please have a look at the docs for called-interactively-p which
explain why it's usually a bad idea, e.g., my only-interactive will for
example also signal an error when used in a keyboard macro.  And as my
examples pointed out, it's easy to circumvent your restriction.

The conventional recommended way to do what you want is to just document
in your commands docstring that it's not meant to be called from lisp
using a `(declare interactive-only)' spec.  Have a look at the docstring
and source code for `next-line' as an example.

HTH,
Tassilo



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

* Re: Making a function than can only be used interactively
       [not found]             ` <jwvczelllyq.fsf-monnier+emacs@gnu.org-N65lQ2m----2>
@ 2022-07-04 10:36               ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-04 10:55                 ` Tassilo Horn
  0 siblings, 1 reply; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-04 10:36 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs


Jul 4, 2022, 01:13 by monnier@iro.umontreal.ca:

>> Yet when I do `(arktika-workbench)` in my init file, the interactive function
>> `arktika-workbench` still gets executed.
>>
>
> Why wouldn't it?  As I said the `interactive-only` declaration only
> causes the byte-compiler (and hence flymake) to warn about
> non-interactive uses of the function.
>
Have also done a simpler function 

(defun test ()
  "TODO"
  (declare (interactive-only arktika-automated-workbench))
  (interactive)
  (message "*** test") )

(test)

Loading emacs I can see that the string "*** test" is being printed.  I am using Emacs 27.2.





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

* Re: Making a function than can only be used interactively
  2022-07-04 10:36               ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-04 10:55                 ` Tassilo Horn
  2022-07-04 11:43                   ` Christopher Dimech
  2022-07-04 19:17                   ` carlmarcos--- via Users list for the GNU Emacs text editor
  0 siblings, 2 replies; 58+ messages in thread
From: Tassilo Horn @ 2022-07-04 10:55 UTC (permalink / raw)
  To: carlmarcos; +Cc: Stefan Monnier, help-gnu-emacs

carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes:

>>> Yet when I do `(arktika-workbench)` in my init file, the interactive
>>> function `arktika-workbench` still gets executed.
>>
>> Why wouldn't it?  As I said the `interactive-only` declaration only
>> causes the byte-compiler (and hence flymake) to warn about
>> non-interactive uses of the function.
>>
> Have also done a simpler function 
>
> (defun test ()
>   "TODO"
>   (declare (interactive-only arktika-automated-workbench))
>   (interactive)
>   (message "*** test") )
>
> (test)
>
> Loading emacs I can see that the string "*** test" is being printed. 
> I am using Emacs 27.2.

Sure, the function will be executed.  As Stefan said, the only effect of
the declare spec is that byte-compiling the file will cause a warning
that `test' is only meant for interactive use.

Bye,
Tassilo



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

* Re: Making a function than can only be used interactively
  2022-07-04 10:55                 ` Tassilo Horn
@ 2022-07-04 11:43                   ` Christopher Dimech
  2022-07-04 13:21                     ` Stefan Monnier
  2022-07-04 19:17                   ` carlmarcos--- via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 11:43 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: carlmarcos, Stefan Monnier, help-gnu-emacs



> Sent: Monday, July 04, 2022 at 10:55 PM
> From: "Tassilo Horn" <tsdh@gnu.org>
> To: carlmarcos@tutanota.com
> Cc: "Stefan Monnier" <monnier@iro.umontreal.ca>, help-gnu-emacs@gnu.org
> Subject: Re: Making a function than can only be used interactively
>
> carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes:
> 
> >>> Yet when I do `(arktika-workbench)` in my init file, the interactive
> >>> function `arktika-workbench` still gets executed.
> >>
> >> Why wouldn't it?  As I said the `interactive-only` declaration only
> >> causes the byte-compiler (and hence flymake) to warn about
> >> non-interactive uses of the function.
> >>
> > Have also done a simpler function 
> >
> > (defun test ()
> >   "TODO"
> >   (declare (interactive-only arktika-automated-workbench))
> >   (interactive)
> >   (message "*** test") )
> >
> > (test)
> >
> > Loading emacs I can see that the string "*** test" is being printed. 
> > I am using Emacs 27.2.
> 
> Sure, the function will be executed.  As Stefan said, the only effect of
> the declare spec is that byte-compiling the file will cause a warning
> that `test' is only meant for interactive use.
> 
> Bye,
> Tassilo
> 

"interactive-only" should go far beyond a byte-compilation warning.

I suggest that "interactive-only" does actually make the function work
in an interactive-only way.  That would be much more useful, particularly
to users writing their own functions.  Currently the "interactive-only"
leads to quite some confusion.







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

* Re: Making a function than can only be used interactively
  2022-07-04 11:43                   ` Christopher Dimech
@ 2022-07-04 13:21                     ` Stefan Monnier
  2022-07-04 14:08                       ` Robert Pluim
  2022-07-04 21:40                       ` Christopher Dimech
  0 siblings, 2 replies; 58+ messages in thread
From: Stefan Monnier @ 2022-07-04 13:21 UTC (permalink / raw)
  To: Christopher Dimech; +Cc: Tassilo Horn, carlmarcos, help-gnu-emacs

> "interactive-only" should go far beyond a byte-compilation warning.
>
> I suggest that "interactive-only" does actually make the function work
> in an interactive-only way.

What would be the benefit?


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-04 13:21                     ` Stefan Monnier
@ 2022-07-04 14:08                       ` Robert Pluim
  2022-07-04 21:40                       ` Christopher Dimech
  1 sibling, 0 replies; 58+ messages in thread
From: Robert Pluim @ 2022-07-04 14:08 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Christopher Dimech, Tassilo Horn, carlmarcos, help-gnu-emacs

>>>>> On Mon, 04 Jul 2022 09:21:51 -0400, Stefan Monnier <monnier@iro.umontreal.ca> said:

    >> "interactive-only" should go far beyond a byte-compilation warning.
    >> 
    >> I suggest that "interactive-only" does actually make the function work
    >> in an interactive-only way.

    Stefan> What would be the benefit?

Going down in history as the person who caused peopleʼs Emacs to die a
flaming death? 😜

Robert
-- 



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

* Re: Making a function than can only be used interactively
  2022-07-04 10:55                 ` Tassilo Horn
  2022-07-04 11:43                   ` Christopher Dimech
@ 2022-07-04 19:17                   ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-04 19:40                     ` Stefan Monnier
  1 sibling, 1 reply; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-04 19:17 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Stefan Monnier, help-gnu-emacs

Jul 4, 2022, 10:55 by tsdh@gnu.org:

> carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes:
>
>>>> Yet when I do `(arktika-workbench)` in my init file, the interactive
>>>> function `arktika-workbench` still gets executed.
>>>>
>>>
>>> Why wouldn't it?  As I said the `interactive-only` declaration only
>>> causes the byte-compiler (and hence flymake) to warn about
>>> non-interactive uses of the function.
>>>
>> Have also done a simpler function 
>>
>> (defun test ()
>>   "TODO"
>>   (declare (interactive-only arktika-automated-workbench))
>>   (interactive)
>>   (message "*** test") )
>>
>> (test)
>>
>> Loading emacs I can see that the string "*** test" is being printed. 
>> I am using Emacs 27.2.
>>
>
> Sure, the function will be executed.  As Stefan said, the only effect of
> the declare spec is that byte-compiling the file will cause a warning
> that `test' is only meant for interactive use.
>
> Bye,
> Tassilo
>
Only after byte-compile of a file?  So there is no way to actually make a function interactive only?




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

* Re: Making a function than can only be used interactively
@ 2022-07-04 19:32 Christopher Dimech
  0 siblings, 0 replies; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 19:32 UTC (permalink / raw)
  To: monnier, tsdh, help-gnu-emacs

Jul 4, 2022, 13:21 by monnier@iro.umontreal.ca:

>        "interactive-only" should go far beyond a byte-compilation warning.
>
>        I suggest that "interactive-only" does actually make the function work
>       in an interactive-only way.
>
>>>
>>>    What would be the benefit?
>>>
>>>    Stefan

That it would do what it says.  Defining a function `interactive-only` would only work
interactively.  Currently, even with `interactive-only` the function would still run as
if `interactive-only` did not exist.  Currently it does not seem to me that `interactive-only`
has any operational effect.





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

* Re: Making a function than can only be used interactively
  2022-07-04 19:17                   ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-04 19:40                     ` Stefan Monnier
  2022-07-04 19:50                       ` carlmarcos--- via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 58+ messages in thread
From: Stefan Monnier @ 2022-07-04 19:40 UTC (permalink / raw)
  To: carlmarcos; +Cc: Tassilo Horn, help-gnu-emacs

> Only after byte-compile of a file? 
> So there is no way to actually make a function interactive only?

Please define what it is you mean by "make a function interactive only".

Do you mean that it should be illegal to write code that calls the
function directly, so whoever writes it can be sued?
Would it be acceptable for someone to just think about writing such code
as long as they don't actually write it?

More seriously, what are you trying to gain by "mak[ing] a function
interactive only"?  Usually, the reason why one might want to make
a function "interactive only" is that code that calls this function is
probably incorrect and would likely be served better by some
other function.  So the purpose is to help people write better code.
For this reason the declaration only has an effect in terms of
byte-compiler warnings: those who don't bother to byte-compile their
code presumably don't care about the quality of their code anyway.

Emacs doesn't offer any pre-defined way to really enforce that
a function is only used interactively, and in large parts this is
because, as a matter of design principle, Emacs makes no effort to stop
people from shooting themselves in the foot (instead, it tries to make
it easier for people not to shoot themselves in the foot).


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-04 19:40                     ` Stefan Monnier
@ 2022-07-04 19:50                       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-04 20:45                         ` Stefan Monnier
  2022-07-06  0:07                         ` Jean Louis
  0 siblings, 2 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-04 19:50 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Tassilo Horn, help-gnu-emacs


Jul 4, 2022, 19:40 by monnier@iro.umontreal.ca:

>> Only after byte-compile of a file? 
>> So there is no way to actually make a function interactive only?
>>
>
> Please define what it is you mean by "make a function interactive only".
>
> Do you mean that it should be illegal to write code that calls the
> function directly, so whoever writes it can be sued?
> Would it be acceptable for someone to just think about writing such code
> as long as they don't actually write it?
>
> More seriously, what are you trying to gain by "mak[ing] a function
> interactive only"?  
>
>
For instance, writing an interactive wrapper function calling a non-interactive
mother function.

Technically, you can use `completing-read` and `read-from-minibuffer` if you'd also
 like to set values interactively, while calling the function non-interactively.  One can
 achieve more or less the same effect with setting values of local variables outside
 the interactive expression.  In this scenario, running the function non-interactively would
still force interactive input from the minibuffer.

I am not sure if in practice that is ever desired.

> Usually, the reason why one might want to make
> a function "interactive only" is that code that calls this function is
> probably incorrect and would likely be served better by some
> other function.  So the purpose is to help people write better code.
> For this reason the declaration only has an effect in terms of
> byte-compiler warnings: those who don't bother to byte-compile their
> code presumably don't care about the quality of their code anyway.
>
> Emacs doesn't offer any pre-defined way to really enforce that
> a function is only used interactively, and in large parts this is
> because, as a matter of design principle, Emacs makes no effort to stop
> people from shooting themselves in the foot (instead, it tries to make
> it easier for people not to shoot themselves in the foot).
>
>
>  Stefan
>



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

* Re: Making a function than can only be used interactively
@ 2022-07-04 20:10 Christopher Dimech
  2022-07-04 20:35 ` Stefan Monnier
  0 siblings, 1 reply; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 20:10 UTC (permalink / raw)
  To: monnier, tsdh, help-gnu-emacs

Jul 4, 2022, 19:40 by monnier@iro.umontreal.ca:

>>>        Only after byte-compile of a file?
>>>        So there is no way to actually make a function interactive only?


>    Please define what it is you mean by "make a function interactive only".

>    Do you mean that it should be illegal to write code that calls the
>    function directly, so whoever writes it can be sued?
>    Would it be acceptable for someone to just think about writing such code
>    as long as they don't actually write it?

>    More seriously, what are you trying to gain by "mak[ing] a function
>    interactive only"? Usually, the reason why one might want to make
>    a function "interactive only" is that code that calls this function is
>    probably incorrect and would likely be served better by some
>    other function.

I could envisage a situation where someone wants to concentrate on the
interactive parts, if taking care of non-interactive use would make the
function difficult to maintain.  I am not sure that it will always be
because of bad design.

>    So the purpose is to help people write better code.
>    For this reason the declaration only has an effect in terms of
>    byte-compiler warnings: those who don't bother to byte-compile their
>    code presumably don't care about the quality of their code anyway.

>    Emacs doesn't offer any pre-defined way to really enforce that
>    a function is only used interactively, and in large parts this is
>    because, as a matter of design principle, Emacs makes no effort to stop
>    people from shooting themselves in the foot (instead, it tries to make
>    it easier for people not to shoot themselves in the foot).

>    Stefan

I also say that it would be better to have declarations that are somewhat
safer for the general elisp user as well.




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

* Re: Making a function than can only be used interactively
  2022-07-04 20:10 Christopher Dimech
@ 2022-07-04 20:35 ` Stefan Monnier
  2022-07-04 20:46   ` Christopher Dimech
  0 siblings, 1 reply; 58+ messages in thread
From: Stefan Monnier @ 2022-07-04 20:35 UTC (permalink / raw)
  To: Christopher Dimech; +Cc: tsdh, help-gnu-emacs

> I could envisage a situation where someone wants to concentrate on the
> interactive parts, if taking care of non-interactive use would make the
> function difficult to maintain.  I am not sure that it will always be
> because of bad design.

Indeed, we have many such functions which have been designed
specifically for interactive use and the non-interactive use case has
simply not been considered.  It's not bad design.

And it doesn't require us to make it impossible to call those functions
non-interactively.

> I also say that it would be better to have declarations that are somewhat
> safer for the general elisp user as well.

Not sure what you mean.  Are you saying that (declare (interactive-only <foo>))
is not safe enough?  Can you expand on that?


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-04 19:50                       ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-04 20:45                         ` Stefan Monnier
  2022-07-06  0:07                         ` Jean Louis
  1 sibling, 0 replies; 58+ messages in thread
From: Stefan Monnier @ 2022-07-04 20:45 UTC (permalink / raw)
  To: carlmarcos; +Cc: Tassilo Horn, help-gnu-emacs

>> More seriously, what are you trying to gain by "mak[ing] a function
>> interactive only"?  
> For instance, writing an interactive wrapper function calling a non-interactive
> mother function.

A common enough case, which you can do just fine without having to
prevent non-interactive calls to the interactive wrapper.

> Technically, you can use `completing-read` and `read-from-minibuffer` if you'd also
> like to set values interactively, while calling the function non-interactively.

You mean you can turn

    (defun foo (a b c)
      (interactive ...)
      ...)

into

    (defun foo ()
      (interactive)
      (let ((a ...)
            (b ...)
            (c ...))
        ...))

Indeed.  It's usually discouraged because it's incompatible with
non-interactive uses of the function, but in the case under discussion
you don't care about that because you already have another function to
use for non-interactive calls.

> I am not sure if in practice that is ever desired.

It's done occasionally, typically in cases where it's difficult to
cleanly separate the part of the code that prompts the user from the
part that actually performs the desired operation.


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-04 20:35 ` Stefan Monnier
@ 2022-07-04 20:46   ` Christopher Dimech
  2022-07-04 21:18     ` Stefan Monnier
  0 siblings, 1 reply; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 20:46 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: tsdh, help-gnu-emacs


> Sent: Tuesday, July 05, 2022 at 8:35 AM
> From: "Stefan Monnier" <monnier@iro.umontreal.ca>
> To: "Christopher Dimech" <dimech@gmx.com>
> Cc: tsdh@gnu.org, help-gnu-emacs@gnu.org
> Subject: Re: Making a function than can only be used interactively
>
> > I could envisage a situation where someone wants to concentrate on the
> > interactive parts, if taking care of non-interactive use would make the
> > function difficult to maintain.  I am not sure that it will always be
> > because of bad design.
>
> Indeed, we have many such functions which have been designed
> specifically for interactive use and the non-interactive use case has
> simply not been considered.  It's not bad design.
>
> And it doesn't require us to make it impossible to call those functions
> non-interactively.
>
> > I also say that it would be better to have declarations that are somewhat
> > safer for the general elisp user as well.
>
> Not sure what you mean.  Are you saying that (declare (interactive-only <foo>))
> is not safe enough?  Can you expand on that?
>
>
>         Stefan
>

Another debate is that although one can declare a non-interactive function,
and an interactive function that can run non-interactively; there is no
construct that can define a purely interactive function.

Does a function know whether it was run from lisp code or from the user in
an emacs session?







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

* Re: Making a function than can only be used interactively
@ 2022-07-04 21:07 Christopher Dimech
  2022-07-04 21:45 ` Stefan Monnier
  0 siblings, 1 reply; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 21:07 UTC (permalink / raw)
  To: monnier, tsdh, help-gnu-emacs

> Jul 4, 2022, 20:45 by monnier@iro.umontreal.ca:

>>>>>            More seriously, what are you trying to gain by "mak[ing] a function
>>>>>            interactive only"?

>>>        For instance, writing an interactive wrapper function calling a non-interactive
>>>        mother function.


>    A common enough case, which you can do just fine without having to
>    prevent non-interactive calls to the interactive wrapper.

>>>        Technically, you can use `completing-read` and `read-from-minibuffer` if you'd also
>>>        like to set values interactively, while calling the function non-interactively.


>    You mean you can turn

>    (defun foo (a b c)
>    (interactive ...)
>    ...)

>    into

>    (defun foo ()
>    (interactive)
>    (let ((a ...)
>    (b ...)
>    (c ...))
>    ...))

Yes, that is what I had in mind.

>    Indeed. It's usually discouraged because it's incompatible with
>    non-interactive uses of the function, but in the case under discussion
>    you don't care about that because you already have another function to
>    use for non-interactive calls.

It is indeed incompatible with non-interactive use.  A thing that can be done
is fire the warning even when Lisp Code in not transformed into byte-code.

Although byte compilation in recommended, I wonder how often people actually
byte-compile every file.  Byte compiling will often tell you errors or warning
in your elisp code that you normally wouldn't know, but I think that running
an interactive-only function non-interactively is serious enough to insert the
warning in the warnings buffer anyway.


>>>        I am not sure if in practice that is ever desired.


>    It's done occasionally, typically in cases where it's difficult to
>    cleanly separate the part of the code that prompts the user from the
>    part that actually performs the desired operation.

>    Stefan







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

* Re: Making a function than can only be used interactively
  2022-07-04 20:46   ` Christopher Dimech
@ 2022-07-04 21:18     ` Stefan Monnier
  2022-07-04 21:59       ` Christopher Dimech
  2022-07-05 22:34       ` carlmarcos--- via Users list for the GNU Emacs text editor
  0 siblings, 2 replies; 58+ messages in thread
From: Stefan Monnier @ 2022-07-04 21:18 UTC (permalink / raw)
  To: Christopher Dimech; +Cc: tsdh, help-gnu-emacs

> Another debate is that although one can declare a non-interactive function,
> and an interactive function that can run non-interactively; there is no
> construct that can define a purely interactive function.

That's because an "interactive function" is just a normal function
together with some auxiliary info to tell `call-interactive` how to call
it "interactively".  Internally `call-interactively` will end up calling
the function via `funcall`, i.e. "non-interactively".  So at
a low-level, technically you just can't have a function that can be
called interactively and not non-interactively.  You can try and kludge
it up above if you really want to (like we've seen in a few different
ways), but we're back to the question: what's the benefit?

> Does a function know whether it was run from lisp code or from the user in
> an Emacs session?

Trying to behave differently depending on who/how a function was called
goes against the design principle of functions, so it tends to be kludgy
and unreliable, like `called-interactively-p`.

BTW, here's another way to make a function that "can't" be called
non-interactively:

    (defun foo (a b c &optional extra)
      (interactive
       (list ... 'dont-you-dare-call-me-non-interactively))
      (unless (eql extra 'dont-you-dare-call-me-non-interactively)
        (error "foo called non-interactively"))
      ...)

You can make it "more robust" with something like:

    (defalias 'foo
      (let ((witness (make-symbol "dont-you-dare-call-me-non-interactively")))
        (lambda (a b c &optional extra)
          (interactive
            (list ... witness))
          (unless (eql extra witness)
            (error "foo called non-interactively"))
          ...)))

But again: is it really worth the trouble?  What is there to gain?
Instead of beating the undesired callers with a stick, why not try and
convince them to do something else with  carrot?


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-04 13:21                     ` Stefan Monnier
  2022-07-04 14:08                       ` Robert Pluim
@ 2022-07-04 21:40                       ` Christopher Dimech
  2022-07-05 17:35                         ` Jean Louis
  1 sibling, 1 reply; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 21:40 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Tassilo Horn, carlmarcos, help-gnu-emacs


> Sent: Tuesday, July 05, 2022 at 1:21 AM
> From: "Stefan Monnier" <monnier@iro.umontreal.ca>
> To: "Christopher Dimech" <dimech@gmx.com>
> Cc: "Tassilo Horn" <tsdh@gnu.org>, carlmarcos@tutanota.com, help-gnu-emacs@gnu.org
> Subject: Re: Making a function than can only be used interactively
>
> > "interactive-only" should go far beyond a byte-compilation warning.
> >
> > I suggest that "interactive-only" does actually make the function work
> > in an interactive-only way.
>
> What would be the benefit?
>
>         Stefan

There could be no benefit.  One sure thing is that there are so many ways to use
the interactive clause, that it is difficult to decide what is good design and what is
bad design.  Might be the reason some users think more assistance on its use is fundamental
to their elisp learning.  Mainly because the manual does not include any scenarios for
good design.

Speaking of design.  I can see situations when a sequence of interactive calls could depend
on the specific interactive value supplied through arguments.


(defun foo (a b c)
(interactive ...)

(if (equal a 1)
  (let* (h (read-from-minibuffer ...))
  ... ))
...)

Although discouraged, the above could make sense, but completely wrong to use
non-interactively.

Perhaps there should be something beyond "An Introduction to Programming in Emacs Lisp".




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

* Re: Making a function than can only be used interactively
  2022-07-04 21:07 Christopher Dimech
@ 2022-07-04 21:45 ` Stefan Monnier
  2022-07-04 22:05   ` Christopher Dimech
  0 siblings, 1 reply; 58+ messages in thread
From: Stefan Monnier @ 2022-07-04 21:45 UTC (permalink / raw)
  To: Christopher Dimech; +Cc: tsdh, help-gnu-emacs

>>    Indeed. It's usually discouraged because it's incompatible with
>>    non-interactive uses of the function, but in the case under discussion
>>    you don't care about that because you already have another function to
>>    use for non-interactive calls.
> It is indeed incompatible with non-interactive use.  A thing that can be done
> is fire the warning even when Lisp Code in not transformed into byte-code.

You could emit the warning/error during macro-expansion, indeed.
Something like:

    (defun foo (a b c)
      (interactive ...)
      (declare (compiler-macro (lambda (_) (error "Called non-interactively"))))
      ...)

Not sure what's the benefit, still.

> Although byte compilation in recommended, I wonder how often people actually
> byte-compile every file.

`flymake-mode` will run the compiler for you to get those warnings right
while you're writing the code.  If people don't see the warning because
they don't compile their files, then let's fix it by trying to convince
them to compile their files, which will come with a lot of other benefits.

> Byte compiling will often tell you errors or warning in your elisp
> code that you normally wouldn't know, but I think that running an
> interactive-only function non-interactively is serious enough to
> insert the warning in the warnings buffer anyway.

Usually calling an interactive-only function non-interactively is not
serious *at all* and very often it's The Right Thing to do.


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-04 21:18     ` Stefan Monnier
@ 2022-07-04 21:59       ` Christopher Dimech
  2022-07-05 22:34       ` carlmarcos--- via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 21:59 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: tsdh, help-gnu-emacs



> Sent: Tuesday, July 05, 2022 at 9:18 AM
> From: "Stefan Monnier" <monnier@iro.umontreal.ca>
> To: "Christopher Dimech" <dimech@gmx.com>
> Cc: tsdh@gnu.org, help-gnu-emacs@gnu.org
> Subject: Re: Making a function than can only be used interactively
>
> > Another debate is that although one can declare a non-interactive function,
> > and an interactive function that can run non-interactively; there is no
> > construct that can define a purely interactive function.
>
> That's because an "interactive function" is just a normal function
> together with some auxiliary info to tell `call-interactive` how to call
> it "interactively".  Internally `call-interactively` will end up calling
> the function via `funcall`, i.e. "non-interactively".  So at
> a low-level, technically you just can't have a function that can be
> called interactively and not non-interactively.  You can try and kludge
> it up above if you really want to (like we've seen in a few different
> ways), but we're back to the question: what's the benefit?

Could be that the above is not fully understood.  Reporting warnings when
running a specific function non-interactively, when non-interactive call
is not recommended, would be the way to go.  But users have to program it
that way.


> > Does a function know whether it was run from lisp code or from the user in
> > an Emacs session?
>
> Trying to behave differently depending on who/how a function was called
> goes against the design principle of functions, so it tends to be kludgy
> and unreliable, like `called-interactively-p`.

Can't argue much with that.

> BTW, here's another way to make a function that "can't" be called
> non-interactively:
>
>     (defun foo (a b c &optional extra)
>       (interactive
>        (list ... 'dont-you-dare-call-me-non-interactively))
>       (unless (eql extra 'dont-you-dare-call-me-non-interactively)
>         (error "foo called non-interactively"))
>       ...)

Something like that could be enough.  Also a warning to warning buffer
might help.


> You can make it "more robust" with something like:
>
>     (defalias 'foo
>       (let ((witness (make-symbol "dont-you-dare-call-me-non-interactively")))
>         (lambda (a b c &optional extra)
>           (interactive
>             (list ... witness))
>           (unless (eql extra witness)
>             (error "foo called non-interactively"))
>           ...)))
>
> But again: is it really worth the trouble?  What is there to gain?
> Instead of beating the undesired callers with a stick, why not try and
> convince them to do something else with  carrot?
>
>         Stefan

You can gain an even bigger headache working with such code.






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

* Re: Making a function than can only be used interactively
  2022-07-04 21:45 ` Stefan Monnier
@ 2022-07-04 22:05   ` Christopher Dimech
  2022-07-04 22:35     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-07-04 23:33     ` Christopher Dimech
  0 siblings, 2 replies; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 22:05 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: tsdh, help-gnu-emacs



> Sent: Tuesday, July 05, 2022 at 9:45 AM
> From: "Stefan Monnier" <monnier@iro.umontreal.ca>
> To: "Christopher Dimech" <dimech@gmx.com>
> Cc: tsdh@gnu.org, help-gnu-emacs@gnu.org
> Subject: Re: Making a function than can only be used interactively
>
> >>    Indeed. It's usually discouraged because it's incompatible with
> >>    non-interactive uses of the function, but in the case under discussion
> >>    you don't care about that because you already have another function to
> >>    use for non-interactive calls.
> > It is indeed incompatible with non-interactive use.  A thing that can be done
> > is fire the warning even when Lisp Code in not transformed into byte-code.
>
> You could emit the warning/error during macro-expansion, indeed.
> Something like:
>
>     (defun foo (a b c)
>       (interactive ...)
>       (declare (compiler-macro (lambda (_) (error "Called non-interactively"))))
>       ...)
>
> Not sure what's the benefit, still.
>
> > Although byte compilation in recommended, I wonder how often people actually
> > byte-compile every file.
>
> `flymake-mode` will run the compiler for you to get those warnings right
> while you're writing the code.  If people don't see the warning because
> they don't compile their files, then let's fix it by trying to convince
> them to compile their files, which will come with a lot of other benefits.
>
> > Byte compiling will often tell you errors or warning in your elisp
> > code that you normally wouldn't know, but I think that running an
> > interactive-only function non-interactively is serious enough to
> > insert the warning in the warnings buffer anyway.
>
> Usually calling an interactive-only function non-interactively is not
> serious *at all* and very often it's The Right Thing to do.
>
>         Stefan

Depends whether the person coding that function thinks it is.  What can he
do then?  Issue warning as you suggested with `declare`?



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

* Re: Making a function than can only be used interactively
  2022-07-04 22:05   ` Christopher Dimech
@ 2022-07-04 22:35     ` Stefan Monnier via Users list for the GNU Emacs text editor
  2022-07-04 23:33     ` Christopher Dimech
  1 sibling, 0 replies; 58+ messages in thread
From: Stefan Monnier via Users list for the GNU Emacs text editor @ 2022-07-04 22:35 UTC (permalink / raw)
  To: help-gnu-emacs

> Depends whether the person coding that function thinks it is.
> What can he do then?  Issue warning as you suggested with `declare`?

I don't think we can answer this in the abstract.  So, we'd first need
to have some concrete scenario before we can start discussing it.


        Stefan




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

* Re: Making a function than can only be used interactively
  2022-07-04 22:05   ` Christopher Dimech
  2022-07-04 22:35     ` Stefan Monnier via Users list for the GNU Emacs text editor
@ 2022-07-04 23:33     ` Christopher Dimech
  1 sibling, 0 replies; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 23:33 UTC (permalink / raw)
  To: Christopher Dimech; +Cc: Stefan Monnier, tsdh, help-gnu-emacs


> Sent: Tuesday, July 05, 2022 at 10:05 AM
> From: "Christopher Dimech" <dimech@gmx.com>
> To: "Stefan Monnier" <monnier@iro.umontreal.ca>
> Cc: tsdh@gnu.org, help-gnu-emacs@gnu.org
> Subject: Re: Making a function than can only be used interactively
>
>
>
> > Sent: Tuesday, July 05, 2022 at 9:45 AM
> > From: "Stefan Monnier" <monnier@iro.umontreal.ca>
> > To: "Christopher Dimech" <dimech@gmx.com>
> > Cc: tsdh@gnu.org, help-gnu-emacs@gnu.org
> > Subject: Re: Making a function than can only be used interactively
> >
> > >>    Indeed. It's usually discouraged because it's incompatible with
> > >>    non-interactive uses of the function, but in the case under discussion
> > >>    you don't care about that because you already have another function to
> > >>    use for non-interactive calls.
> > > It is indeed incompatible with non-interactive use.  A thing that can be done
> > > is fire the warning even when Lisp Code in not transformed into byte-code.
> >
> > You could emit the warning/error during macro-expansion, indeed.
> > Something like:
> >
> >     (defun foo (a b c)
> >       (interactive ...)
> >       (declare (compiler-macro (lambda (_) (error "Called non-interactively"))))
> >       ...)
> >
> > Not sure what's the benefit, still.

I am not confident the declare command will always work.

Not for

(defun foo ()
(interactive)
(let ((a ...)
(b ...)
(c ...))
...))


> > > Although byte compilation in recommended, I wonder how often people actually
> > > byte-compile every file.
> >
> > `flymake-mode` will run the compiler for you to get those warnings right
> > while you're writing the code.  If people don't see the warning because
> > they don't compile their files, then let's fix it by trying to convince
> > them to compile their files, which will come with a lot of other benefits.
> >
> > > Byte compiling will often tell you errors or warning in your elisp
> > > code that you normally wouldn't know, but I think that running an
> > > interactive-only function non-interactively is serious enough to
> > > insert the warning in the warnings buffer anyway.
> >
> > Usually calling an interactive-only function non-interactively is not
> > serious *at all* and very often it's The Right Thing to do.
> >
> >         Stefan
>
> Depends whether the person coding that function thinks it is.  What can he
> do then?  Issue warning as you suggested with `declare`?
>
>



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

* Re: Making a function than can only be used interactively
@ 2022-07-04 23:42 Christopher Dimech
  0 siblings, 0 replies; 58+ messages in thread
From: Christopher Dimech @ 2022-07-04 23:42 UTC (permalink / raw)
  To: monnier, help-gnu-emacs

Jul 4, 2022, 22:35 by help-gnu-emacs@gnu.org:

>>>>>        Depends whether the person coding that function thinks it is.
>>>>>        What can he do then? Issue warning as you suggested with `declare`?


>>>    I don't think we can answer this in the abstract. So, we'd first need
>>>    to have some concrete scenario before we can start discussing it.

>>>    Stefan

Even with a concrete example, it is quite likely that we would not be able to capture
the way it was used.  Especially if one uses

(defun foo ()
(interactive)
(let ((a ...)
(b ...)
(c ...))
...))





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

* Re: Making a function than can only be used interactively
  2022-07-04 21:40                       ` Christopher Dimech
@ 2022-07-05 17:35                         ` Jean Louis
  0 siblings, 0 replies; 58+ messages in thread
From: Jean Louis @ 2022-07-05 17:35 UTC (permalink / raw)
  To: Christopher Dimech
  Cc: Stefan Monnier, Tassilo Horn, carlmarcos, help-gnu-emacs

* Christopher Dimech <dimech@gmx.com> [2022-07-05 00:41]:
> (defun foo (a b c)
> (interactive ...)
> 
> (if (equal a 1)
>   (let* (h (read-from-minibuffer ...))
>   ... ))
> ...)
> 
> Although discouraged, the above could make sense, but completely wrong to use
> non-interactively.

I think it is OK to use it non-interactively. 

`interactive' description says "Specify a way of parsing arguments for
interactive use of a function." 

See (info "(elisp) Using Interactive")

Here is sample function that I use:

(defun cf-hyperscope-assign-tasks-for-many (&optional id)
  "Assign tasks with information of many contacts"
  (interactive)
  (when-tabulated-id "people"
      (let* ((assignee (cf-people-search-id nil "Assign to which person? "))
	     (task (rcd-ask "Describe the task to be assigned: "))
	     (prefix (rcd-ask "Prefix for task: " "Call"))
	     (set (hyperscope-select-set)))
	(rcd-tabulated-iterate-generic 
	 id
	 (lambda (id)
	   (let* ((name (concat prefix " " (cf-full-contact-name id)))
		  (description (concat "⟦ (hyperscope-related-contact-contacts-information hyperscope-current-id) ⟧\n\n" task))
		  (hyperscope-id (hyperscope-add-generic name "" nil 31 10 set nil description nil id assignee)))
	     (hlink-update-action-status-1 hyperscope-id 2)))
	 "Assign Tasks"))))

And I may as well invoke function non-interactively, when there is
`interactive`, it means it is a command and accessible through M-x and
may be bound to keys.

-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

* Re: Making a function than can only be used interactively
  2022-07-04 21:18     ` Stefan Monnier
  2022-07-04 21:59       ` Christopher Dimech
@ 2022-07-05 22:34       ` carlmarcos--- via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-05 22:34 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Christopher Dimech, tsdh, help-gnu-emacs


Jul 4, 2022, 21:18 by monnier@iro.umontreal.ca:

>> Another debate is that although one can declare a non-interactive function,
>> and an interactive function that can run non-interactively; there is no
>> construct that can define a purely interactive function.
>>
>
> That's because an "interactive function" is just a normal function
> together with some auxiliary info to tell `call-interactive` how to call
> it "interactively".  Internally `call-interactively` will end up calling
> the function via `funcall`, i.e. "non-interactively".  So at
> a low-level, technically you just can't have a function that can be
> called interactively and not non-interactively.  You can try and kludge
> it up above if you really want to (like we've seen in a few different
> ways), but we're back to the question: what's the benefit?
>
>> Does a function know whether it was run from lisp code or from the user in
>> an Emacs session?
>>
>
> Trying to behave differently depending on who/how a function was called
> goes against the design principle of functions, so it tends to be kludgy
> and unreliable, like `called-interactively-p`.
>
>  Stefan
>
Quite sure now that the plan ought  to be abandoned.



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

* Re: Making a function than can only be used interactively
  2022-07-03 19:53     ` Tassilo Horn
  2022-07-03 20:17       ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-05 23:13       ` Emanuel Berg
  1 sibling, 0 replies; 58+ messages in thread
From: Emanuel Berg @ 2022-07-05 23:13 UTC (permalink / raw)
  To: help-gnu-emacs

Tassilo Horn wrote:

>>>> Is it possible to make an interactive function than can
>>>> only be used interactively?
>>>
>>> I'm not sure I understand your question. A function, that
>>> may be called interactively, is called a "command" in
>>> Emacs. And a command can definitely be called
>>> interactively, either by using it's name (using M-x) or
>>> binding it to a key.
>>
>> I do not want people to use the function non-interactively.
>
> How restrictive is that! :-)

But it would be even more restrictive if it wasn't possible to
do ...

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




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

* Re: Making a function than can only be used interactively
  2022-07-04 19:50                       ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-04 20:45                         ` Stefan Monnier
@ 2022-07-06  0:07                         ` Jean Louis
  2022-07-06 20:00                           ` Christopher Dimech
  1 sibling, 1 reply; 58+ messages in thread
From: Jean Louis @ 2022-07-06  0:07 UTC (permalink / raw)
  To: carlmarcos; +Cc: Stefan Monnier, Tassilo Horn, help-gnu-emacs

* carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-07-04 22:52]:
> Technically, you can use `completing-read` and `read-from-minibuffer` if you'd also
>  like to set values interactively, while calling the function non-interactively.  One can
>  achieve more or less the same effect with setting values of local variables outside
>  the interactive expression.  In this scenario, running the function non-interactively would
> still force interactive input from the minibuffer.
> 
> I am not sure if in practice that is ever desired.

(interactive &optional ARG-DESCRIPTOR &rest MODES) -- this makes the
function a command that may be tied to a key, and it helps in
specifying the arguments to the function. 

In this context function may be run as command, or by pressing a
key. However, it does not really mean it need to interact with user,
not at all. It does not need to ask nothing of the user. In fact, it
can just interactively, during Emacs session be called by user with
M-x or by using a key. Beyond that, function may remain quite silent
without interactivity.

The above is one specific context where word "interactive" is used as
in function (interactive).

It does not exclude the other context that any function without
(interactive) may do interactive activities, like ask user
interactively for input.

Remember, there are 2 different contexts. One does not exclude the other.

-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

* Re: Making a function than can only be used interactively
  2022-07-06  0:07                         ` Jean Louis
@ 2022-07-06 20:00                           ` Christopher Dimech
  2022-07-06 20:29                             ` Jean Louis
  0 siblings, 1 reply; 58+ messages in thread
From: Christopher Dimech @ 2022-07-06 20:00 UTC (permalink / raw)
  To: Jean Louis; +Cc: carlmarcos, Stefan Monnier, Tassilo Horn, help-gnu-emacs


> Sent: Wednesday, July 06, 2022 at 12:07 PM
> From: "Jean Louis" <bugs@gnu.support>
> To: carlmarcos@tutanota.com
> Cc: "Stefan Monnier" <monnier@iro.umontreal.ca>, "Tassilo Horn" <tsdh@gnu.org>, help-gnu-emacs@gnu.org
> Subject: Re: Making a function than can only be used interactively
>
> * carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-07-04 22:52]:
> > Technically, you can use `completing-read` and `read-from-minibuffer` if you'd also
> >  like to set values interactively, while calling the function non-interactively.  One can
> >  achieve more or less the same effect with setting values of local variables outside
> >  the interactive expression.  In this scenario, running the function non-interactively would
> > still force interactive input from the minibuffer.
> > 
> > I am not sure if in practice that is ever desired.
> 
> (interactive &optional ARG-DESCRIPTOR &rest MODES) -- this makes the
> function a command that may be tied to a key, and it helps in
> specifying the arguments to the function. 
> 
> In this context function may be run as command, or by pressing a
> key. However, it does not really mean it need to interact with user,
> not at all. It does not need to ask nothing of the user. In fact, it
> can just interactively, during Emacs session be called by user with
> M-x or by using a key. Beyond that, function may remain quite silent
> without interactivity.
> 
> The above is one specific context where word "interactive" is used as
> in function (interactive).
> 
> It does not exclude the other context that any function without
> (interactive) may do interactive activities, like ask user
> interactively for input.

If one does not mind interactive activities with the minibuffer for
a function without the interactive clause.
 
> Remember, there are 2 different contexts. One does not exclude the other.
> 
> -- 
> Jean
> 
> Take action in Free Software Foundation campaigns:
> https://www.fsf.org/campaigns
> 
> In support of Richard M. Stallman
> https://stallmansupport.org/
> 
>



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

* Re: Making a function than can only be used interactively
  2022-07-06 20:00                           ` Christopher Dimech
@ 2022-07-06 20:29                             ` Jean Louis
  2022-07-07 11:03                               ` Christopher Dimech
  2022-07-07 21:06                               ` carlmarcos--- via Users list for the GNU Emacs text editor
  0 siblings, 2 replies; 58+ messages in thread
From: Jean Louis @ 2022-07-06 20:29 UTC (permalink / raw)
  To: Christopher Dimech
  Cc: carlmarcos, Stefan Monnier, Tassilo Horn, help-gnu-emacs

* Christopher Dimech <dimech@gmx.com> [2022-07-06 23:00]:
> 
> > Sent: Wednesday, July 06, 2022 at 12:07 PM
> > From: "Jean Louis" <bugs@gnu.support>
> > To: carlmarcos@tutanota.com
> > Cc: "Stefan Monnier" <monnier@iro.umontreal.ca>, "Tassilo Horn" <tsdh@gnu.org>, help-gnu-emacs@gnu.org
> > Subject: Re: Making a function than can only be used interactively
> >
> > * carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-07-04 22:52]:
> > > Technically, you can use `completing-read` and `read-from-minibuffer` if you'd also
> > >  like to set values interactively, while calling the function non-interactively.  One can
> > >  achieve more or less the same effect with setting values of local variables outside
> > >  the interactive expression.  In this scenario, running the function non-interactively would
> > > still force interactive input from the minibuffer.
> > > 
> > > I am not sure if in practice that is ever desired.
> > 
> > (interactive &optional ARG-DESCRIPTOR &rest MODES) -- this makes the
> > function a command that may be tied to a key, and it helps in
> > specifying the arguments to the function. 
> > 
> > In this context function may be run as command, or by pressing a
> > key. However, it does not really mean it need to interact with user,
> > not at all. It does not need to ask nothing of the user. In fact, it
> > can just interactively, during Emacs session be called by user with
> > M-x or by using a key. Beyond that, function may remain quite silent
> > without interactivity.
> > 
> > The above is one specific context where word "interactive" is used as
> > in function (interactive).
> > 
> > It does not exclude the other context that any function without
> > (interactive) may do interactive activities, like ask user
> > interactively for input.
> 
> If one does not mind interactive activities with the minibuffer for
> a function without the interactive clause.

1) That means for me, you did not understand what is interactive
function. Just read docstring. 

2) Nowhere it says that function without (interactive) cannot
interact with user. 

Numbers above (1) and (2) are different contexts. A word such as
"interactive" has different meanings. 

-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

In support of Richard M. Stallman
https://stallmansupport.org/



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

* Re: Making a function than can only be used interactively
  2022-07-06 20:29                             ` Jean Louis
@ 2022-07-07 11:03                               ` Christopher Dimech
  2022-07-07 21:06                               ` carlmarcos--- via Users list for the GNU Emacs text editor
  1 sibling, 0 replies; 58+ messages in thread
From: Christopher Dimech @ 2022-07-07 11:03 UTC (permalink / raw)
  To: Jean Louis; +Cc: carlmarcos, Stefan Monnier, Tassilo Horn, help-gnu-emacs



> Sent: Thursday, July 07, 2022 at 8:29 AM
> From: "Jean Louis" <bugs@gnu.support>
> To: "Christopher Dimech" <dimech@gmx.com>
> Cc: carlmarcos@tutanota.com, "Stefan Monnier" <monnier@iro.umontreal.ca>, "Tassilo Horn" <tsdh@gnu.org>, help-gnu-emacs@gnu.org
> Subject: Re: Making a function than can only be used interactively
>
> * Christopher Dimech <dimech@gmx.com> [2022-07-06 23:00]:
> > 
> > > Sent: Wednesday, July 06, 2022 at 12:07 PM
> > > From: "Jean Louis" <bugs@gnu.support>
> > > To: carlmarcos@tutanota.com
> > > Cc: "Stefan Monnier" <monnier@iro.umontreal.ca>, "Tassilo Horn" <tsdh@gnu.org>, help-gnu-emacs@gnu.org
> > > Subject: Re: Making a function than can only be used interactively
> > >
> > > * carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-07-04 22:52]:
> > > > Technically, you can use `completing-read` and `read-from-minibuffer` if you'd also
> > > >  like to set values interactively, while calling the function non-interactively.  One can
> > > >  achieve more or less the same effect with setting values of local variables outside
> > > >  the interactive expression.  In this scenario, running the function non-interactively would
> > > > still force interactive input from the minibuffer.
> > > > 
> > > > I am not sure if in practice that is ever desired.
> > > 
> > > (interactive &optional ARG-DESCRIPTOR &rest MODES) -- this makes the
> > > function a command that may be tied to a key, and it helps in
> > > specifying the arguments to the function. 
> > > 
> > > In this context function may be run as command, or by pressing a
> > > key. However, it does not really mean it need to interact with user,
> > > not at all. It does not need to ask nothing of the user. In fact, it
> > > can just interactively, during Emacs session be called by user with
> > > M-x or by using a key. Beyond that, function may remain quite silent
> > > without interactivity.
> > > 
> > > The above is one specific context where word "interactive" is used as
> > > in function (interactive).
> > > 
> > > It does not exclude the other context that any function without
> > > (interactive) may do interactive activities, like ask user
> > > interactively for input.
> > 
> > If one does not mind interactive activities with the minibuffer for
> > a function without the interactive clause.
> 
> 1) That means for me, you did not understand what is interactive
> function. Just read docstring. 
> 
> 2) Nowhere it says that function without (interactive) cannot
> interact with user. 

It is a way to pass arguments with user prompt.
 
> Numbers above (1) and (2) are different contexts. A word such as
> "interactive" has different meanings. 

What different meanings?  
 
> -- 
> Jean
> 
> Take action in Free Software Foundation campaigns:
> https://www.fsf.org/campaigns
> 
> In support of Richard M. Stallman
> https://stallmansupport.org/
>



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

* Re: Making a function than can only be used interactively
  2022-07-06 20:29                             ` Jean Louis
  2022-07-07 11:03                               ` Christopher Dimech
@ 2022-07-07 21:06                               ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-07 21:28                                 ` Emanuel Berg
  1 sibling, 1 reply; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-07 21:06 UTC (permalink / raw)
  To: Jean Louis
  Cc: Christopher Dimech, Stefan Monnier, Tassilo Horn, help-gnu-emacs


Jul 6, 2022, 20:29 by bugs@gnu.support:

> * Christopher Dimech <dimech@gmx.com> [2022-07-06 23:00]:
>
>>
>> > Sent: Wednesday, July 06, 2022 at 12:07 PM
>> > From: "Jean Louis" <bugs@gnu.support>
>> > To: carlmarcos@tutanota.com
>> > Cc: "Stefan Monnier" <monnier@iro.umontreal.ca>, "Tassilo Horn" <tsdh@gnu.org>, help-gnu-emacs@gnu.org
>> > Subject: Re: Making a function than can only be used interactively
>> >
>> > * carlmarcos--- via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2022-07-04 22:52]:
>> > > Technically, you can use `completing-read` and `read-from-minibuffer` if you'd also
>> > >  like to set values interactively, while calling the function non-interactively.  One can
>> > >  achieve more or less the same effect with setting values of local variables outside
>> > >  the interactive expression.  In this scenario, running the function non-interactively would
>> > > still force interactive input from the minibuffer.
>> > > 
>> > > I am not sure if in practice that is ever desired.
>> > 
>> > (interactive &optional ARG-DESCRIPTOR &rest MODES) -- this makes the
>> > function a command that may be tied to a key, and it helps in
>> > specifying the arguments to the function. 
>> > 
>> > In this context function may be run as command, or by pressing a
>> > key. However, it does not really mean it need to interact with user,
>> > not at all. It does not need to ask nothing of the user. In fact, it
>> > can just interactively, during Emacs session be called by user with
>> > M-x or by using a key. Beyond that, function may remain quite silent
>> > without interactivity.
>> > 
>> > The above is one specific context where word "interactive" is used as
>> > in function (interactive).
>> > 
>> > It does not exclude the other context that any function without
>> > (interactive) may do interactive activities, like ask user
>> > interactively for input.
>>
>> If one does not mind interactive activities with the minibuffer for
>> a function without the interactive clause.
>>
>
> 1) That means for me, you did not understand what is interactive
> function. Just read docstring. 
>
> 2) Nowhere it says that function without (interactive) cannot
> interact with user. 
>
It is a way to pass arguments with user prompt.


> Numbers above (1) and (2) are different contexts. A word such as
> "interactive" has different meanings. 
>
What different meanings?  

-- 

> Jean
>
> Take action in Free Software Foundation campaigns:
> https://www.fsf.org/campaigns
>
> In support of Richard M. Stallman
> https://stallmansupport.org/
>



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

* Re: Making a function than can only be used interactively
  2022-07-07 21:06                               ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-07 21:28                                 ` Emanuel Berg
  2022-07-07 22:14                                   ` carlmarcos--- via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 58+ messages in thread
From: Emanuel Berg @ 2022-07-07 21:28 UTC (permalink / raw)
  To: help-gnu-emacs

carlmarcos--- via Users list for the GNU Emacs text editor wrote:

>> A word such as "interactive" has different meanings.
>
> What different meanings?

So interactive/non-interactive 101 ...

M-x - that's interactive

Keystroke - interactive!

"interactive" means (interactive "nX: \n") is used to assign
the argument values to the formal parameters.

Compare "from Lisp" or non-interactive use which looks like
this:

(from-lisp x) - non-interactive, i.e. (interactive "...")
isn't used, but you see that x is provided so no worries.

A function that is interactive is also called a command!

That's all I know ... what more do you want?

  You gotta give me more and more
  Cuz you're the girl that I adore
  --Zodiac Evermore, Netherlands 1996
  https://dataswamp.org/~incal/vidz/evermore-kate.mp4

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




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

* Re: Making a function than can only be used interactively
  2022-07-07 21:28                                 ` Emanuel Berg
@ 2022-07-07 22:14                                   ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-08  3:40                                     ` Emanuel Berg
  2022-07-08  6:08                                     ` Yuri Khan
  0 siblings, 2 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-07 22:14 UTC (permalink / raw)
  To: Emanuel Berg; +Cc: help-gnu-emacs



-- 
 Sent with Tutanota, enjoy secure & ad-free emails. 



Jul 7, 2022, 21:28 by incal@dataswamp.org:

> carlmarcos--- via Users list for the GNU Emacs text editor wrote:
>
>>> A word such as "interactive" has different meanings.
>>>
>>
>> What different meanings?
>>
>
> So interactive/non-interactive 101 ...
>
> M-x - that's interactive
>
> Keystroke - interactive!
>
> "interactive" means (interactive "nX: \n") is used to assign
> the argument values to the formal parameters.
>
> Compare "from Lisp" or non-interactive use which looks like
> this:
>
> (from-lisp x) - non-interactive, i.e. (interactive "...")
> isn't used, but you see that x is provided so no worries.
>
> A function that is interactive is also called a command!
>
> That's all I know ... what more do you want?
>

I want to know a few specific things.  If I want to use the prefix argument, I should include
a variable in the argument list, right?  Let us call the variable "prefix".  Now, should the prefix
 be  mandatory or optional?  Should it always be the first argument?  

(defun funname (prefix arg-a arg-b)
  "docstring"
  (interactive "P\ns Name:\n s City")
  (message "executed funname"))


>  You gotta give me more and more
>  Cuz you're the girl that I adore
>  --Zodiac Evermore, Netherlands 1996
>  https://dataswamp.org/~incal/vidz/evermore-kate.mp4
>
> -- 
> underground experts united
> https://dataswamp.org/~incal
>



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

* Re: Making a function than can only be used interactively
  2022-07-07 22:14                                   ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-08  3:40                                     ` Emanuel Berg
  2022-07-08  6:08                                     ` Yuri Khan
  1 sibling, 0 replies; 58+ messages in thread
From: Emanuel Berg @ 2022-07-08  3:40 UTC (permalink / raw)
  To: help-gnu-emacs

Here is an example of a more complicated interactive spec,

  (interactive
   `(,(read-string "search: [repeat] ")
     ,(or (equal current-prefix-arg '( 4))
          (equal current-prefix-arg '(64)) )
     ,(or (equal current-prefix-arg '(16))
          (equal current-prefix-arg '(64)) )
     ,@(if (use-region-p)
           (list (region-beginning) (region-end))
         (list (point-min) (point-max)) )))

Again, eval the `interactive'!

The signature is

  (defun wrap-search (str &optional case rev beg end)

Especially because 'case' and 'rev' both depends on the
`prefix-arg' I wonder if it's impossible to do with just the
interactive string, even ...

Other than that it isn't so difficult, a string is "s",
a number is "n" and the region is "r".

Note the use of the backtick just to be able to
do ,@ ... that's pretty common.

Another situation is this

  (let*((case-fold-search (not case))
        (pos (point))
        (data (if rev (list #'search-backward end beg)
                (list #'search-forward beg end) ))
        (search-f (car data))
        (search-beg (cadr data))
        (search-end (caddr data)) ) ...)

Here we see that instead of doing (if rev ... ) three times we
stash the configuration (here 3 vars) based on 'rev', then use
`car' and the "forbidden" `cadr' and `caddr' to get from that.
(Forbidden as you should it has been said only use vanilla `car'
and `cdr', with 2 or more elements instead of `car' one should
do `nth.'.

But I think the argument-free cars are interesting I
guess ....

Full source:
  https://dataswamp.org/~incal/emacs-init/wrap-search.el

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




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

* Re: Making a function than can only be used interactively
  2022-07-07 22:14                                   ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-08  3:40                                     ` Emanuel Berg
@ 2022-07-08  6:08                                     ` Yuri Khan
  2022-07-08  6:30                                       ` Emanuel Berg
  1 sibling, 1 reply; 58+ messages in thread
From: Yuri Khan @ 2022-07-08  6:08 UTC (permalink / raw)
  To: carlmarcos; +Cc: Emanuel Berg, help-gnu-emacs

On Fri, 8 Jul 2022 at 05:14, carlmarcos--- via Users list for the GNU
Emacs text editor <help-gnu-emacs@gnu.org> wrote:

> I want to know a few specific things.  If I want to use the prefix argument, I should include
> a variable in the argument list, right?  Let us call the variable "prefix".  Now, should the prefix
>  be  mandatory or optional?  Should it always be the first argument?
>
> (defun funname (prefix arg-a arg-b)
>   "docstring"
>   (interactive "P\ns Name:\n s City")
>   (message "executed funname"))

It does not matter for interactive use. Your (interactive) spec, if it
were written correctly[see below], would describe three arguments, and
Emacs would therefore pass three arguments to your function.

‘&optional’ comes into play if you use this function
non-interactively, from Lisp:

    (defun funname (prefix arg-a arg-b)
       nil)
    (funname 0 1 2)
    ⇒ nil
    (funname)
    ⇒ (wrong-number-of-arguments (lambda (prefix arg-a arg-b) nil) 0)

    (defun funname (&optional prefix arg-a arg-b)
       nil)
    (funname 0 1 2)
    ⇒ nil
    (funname)
    ⇒ nil

Now about (interactive) spec syntax: you have three spaces there. The
one immediately after the ‘\n’ breaks things — the first character of
an argument specification specifies the way it is produced, and space
is not a valid code letter. The other two spaces (after ‘s’) become
part of the prompt so the prompt is displayed not at the window edge
but one character to the right. Your spec should be:

    (interactive "P\nsName:\nsCity")



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

* Re: Making a function than can only be used interactively
  2022-07-08  6:08                                     ` Yuri Khan
@ 2022-07-08  6:30                                       ` Emanuel Berg
  2022-07-08  6:55                                         ` Yuri Khan
  0 siblings, 1 reply; 58+ messages in thread
From: Emanuel Berg @ 2022-07-08  6:30 UTC (permalink / raw)
  To: help-gnu-emacs

Yuri Khan wrote:

> It does not matter for interactive use. [...] ‘&optional’
> comes into play if you use this function non-interactively,
> from Lisp

No, it matters. One example how it matters is that optional
arguments defaults to nil.

Check out this file and in particular example 4 which doesn't
make sense to me?

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

;; DWIM example 1, from Lisp ignore region if set

(defun test-dwim (&optional beg end)
  (interactive (when (use-region-p)
                 (list (region-beginning) (region-end)) ))
  (or beg (setq beg (point-min))) ; or (point)
  (or end (setq end (point-max)))
  ;; insert code here
  ;; now let's just make a list to do something
  (list beg end) )

;; example 2, use the region if available from Lisp as well

(defun test-dwim-2 (&optional beg end)
  (interactive (when (use-region-p)
                 (list (region-beginning) (region-end)) ))
  (or beg (setq beg (if (use-region-p) (region-beginning) (point-min))))
  (or end (setq end (if (use-region-p) (region-end)       (point-max))))
  (list beg end) )

;; example 3, one call to `use-region-p' is enough

(defun test-dwim-3 (re &optional beg end)
  (interactive `(,(read-regexp "re: ")
                 ,@(when (use-region-p)
                     (list (region-beginning) (region-end)) )))
  (or beg (setq beg (point-min)))
  (or end (setq end (point-max)))
  (message "%s" (list re beg end)) )

;; example 4, let's do that with the `interactive' spec
;; string. but without `use-region-p' it doesn't reset after
;; I clear the region, or that's what I thought happened
;; anyway :) so this doesn't work as intended, which
;; `test-dwim-3' does, supposedly the worse one.

(defun test-dwim-4 (re &optional beg end)
  (interactive "sre: \nr")
  (or beg (setq beg (point-min)))
  (or end (setq end (point-max)))
  (message "%s" (list re beg end)) )

;; test the interface

(when nil
  (save-excursion
    (set-mark   10)
    (goto-char 500)
    (call-interactively #'test-dwim) ) ; (10  500)
  (call-interactively #'test-dwim)     ; ( 1 2867)
  (test-dwim 30 90)                    ; (30   90)
  (test-dwim)                          ; ( 1 2867)
)

;; example function

(defun count-chars (&optional beg end)
  (interactive (when (use-region-p)
                 (list (region-beginning) (region-end)) ))
  (let*((bg (or beg (point-min)))
        (ed (or end (point-max)))
        (df (- ed bg)) )
    (prog1
        df
      (message "%d" df) )))

;; Test the example function:
;;
:;   [try these with and without a region]
;;
;;   (call-interactively #'count-chars)
;;   (count-chars)
;;
;;   [this will always be the same tho]
;;
;;   (count-chars 10 40)
;;
;; Note:
;;   A common mistake in Elisp is that optional formal
;;   parameters aren't sent as arguments when called from
;;   Lisp, they are then nil but are used as for example an
;;   integer, as in:
;;
;;     (when (and (<= 0 width) (<= width 648)) ... ) ; DNC
;;
;; The test method is to call the function every way possible:
;;   1. interactively with a region
;;   2. ditto w/o
;;   3. From Lisp with arguments
;;   4. ditto w/o
;;   .. ..

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




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

* Re: Making a function than can only be used interactively
  2022-07-08  6:30                                       ` Emanuel Berg
@ 2022-07-08  6:55                                         ` Yuri Khan
  2022-07-08 11:44                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
                                                             ` (4 more replies)
  0 siblings, 5 replies; 58+ messages in thread
From: Yuri Khan @ 2022-07-08  6:55 UTC (permalink / raw)
  To: help-gnu-emacs

On Fri, 8 Jul 2022 at 13:31, Emanuel Berg <incal@dataswamp.org> wrote:

> > It does not matter for interactive use. [...] ‘&optional’
> > comes into play if you use this function non-interactively,
> > from Lisp
>
> No, it matters. One example how it matters is that optional
> arguments defaults to nil.

You’re right, with an interactive specification that evaluates to a
list it matters, because the list you return may or may not have as
many arguments as the function takes.

My point was that in the specific case of a three-argument function
and a three-item string-valued interactive specification, &optional
does not matter for interactive use.


> Check out this file and in particular example 4 which doesn't
> make sense to me?
>
> ;; DWIM example 1, from Lisp ignore region if set
> ;; example 2, use the region if available from Lisp as well
>
> (defun test-dwim (&optional beg end)
>   (interactive (when (use-region-p)
>                  (list (region-beginning) (region-end)) ))

Here you have two cases. If the region is active, you produce a
two-element list, otherwise, a 0-element list. The function signature
allows 0..2 arguments, so it works in either case.

> ;; example 3, one call to `use-region-p' is enough
>
> (defun test-dwim-3 (re &optional beg end)
>   (interactive `(,(read-regexp "re: ")
>                  ,@(when (use-region-p)
>                      (list (region-beginning) (region-end)) )))

Mostly same, except you build a list of 3 or 1 elements, and the
function accepts 1..3 arguments.

> ;; example 4, let's do that with the `interactive' spec
> ;; string. but without `use-region-p' it doesn't reset after
> ;; I clear the region, or that's what I thought happened
> ;; anyway :) so this doesn't work as intended, which
> ;; `test-dwim-3' does, supposedly the worse one.
>
> (defun test-dwim-4 (re &optional beg end)
>   (interactive "sre: \nr")

Here you use a string interactive spec which always produces 3
elements. In non-interactive use, it will work if called as
(test-dwim-4 "^foo$"), (test-dwim-4 "^foo$" 42), or (test-dwim-4
"^foo$" 42 69).

As to your “clearing” the region, Emacs always maintains the point and
mark positions, and the ‘r’ interactive spec code ignores the region
activation flag and always passes the point and mark. (This could be
considered a bug, but I see no good alternative behavior, except maybe
passing two nils if the region is not active.)



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

* Re: Making a function than can only be used interactively
  2022-07-08  6:55                                         ` Yuri Khan
@ 2022-07-08 11:44                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-09  2:05                                             ` Emanuel Berg
  2022-07-10  4:33                                             ` Emanuel Berg
  2022-07-08 12:06                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
                                                             ` (3 subsequent siblings)
  4 siblings, 2 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-08 11:44 UTC (permalink / raw)
  To: Yuri Khan; +Cc: help-gnu-emacs



Jul 8, 2022, 06:55 by yuri.v.khan@gmail.com:

> On Fri, 8 Jul 2022 at 13:31, Emanuel Berg <incal@dataswamp.org> wrote:
>
>> > It does not matter for interactive use. [...] ‘&optional’
>> > comes into play if you use this function non-interactively,
>> > from Lisp
>>
>> No, it matters. One example how it matters is that optional
>> arguments defaults to nil.
>>
>
> You’re right, with an interactive specification that evaluates to a
> list it matters, because the list you return may or may not have as
> many arguments as the function takes.
>

Using a list in the most general way to use interactive.  I need specific rules 
for using a list, how to decide whether the arguments should be mandatory
or optional.


> My point was that in the specific case of a three-argument function
> and a three-item string-valued interactive specification, &optional
> does not matter for interactive use.
>
>
>> Check out this file and in particular example 4 which doesn't
>> make sense to me?
>>
>> ;; DWIM example 1, from Lisp ignore region if set
>> ;; example 2, use the region if available from Lisp as well
>>
>> (defun test-dwim (&optional beg end)
>>  (interactive (when (use-region-p)
>>  (list (region-beginning) (region-end)) ))
>>
>
> Here you have two cases. If the region is active, you produce a
> two-element list, otherwise, a 0-element list. The function signature
> allows 0..2 arguments, so it works in either case.
>
>> ;; example 3, one call to `use-region-p' is enough
>>
>> (defun test-dwim-3 (re &optional beg end)
>>  (interactive `(,(read-regexp "re: ")
>>  ,@(when (use-region-p)
>>  (list (region-beginning) (region-end)) )))
>>
>
> Mostly same, except you build a list of 3 or 1 elements, and the
> function accepts 1..3 arguments.
>
>> ;; example 4, let's do that with the `interactive' spec
>> ;; string. but without `use-region-p' it doesn't reset after
>> ;; I clear the region, or that's what I thought happened
>> ;; anyway :) so this doesn't work as intended, which
>> ;; `test-dwim-3' does, supposedly the worse one.
>>
>> (defun test-dwim-4 (re &optional beg end)
>>  (interactive "sre: \nr")
>>
>
> Here you use a string interactive spec which always produces 3
> elements. In non-interactive use, it will work if called as
> (test-dwim-4 "^foo$"), (test-dwim-4 "^foo$" 42), or (test-dwim-4
> "^foo$" 42 69).
>
> As to your “clearing” the region, Emacs always maintains the point and
> mark positions, and the ‘r’ interactive spec code ignores the region
> activation flag and always passes the point and mark. (This could be
> considered a bug, but I see no good alternative behavior, except maybe
> passing two nils if the region is not active.)
>



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

* Re: Making a function than can only be used interactively
  2022-07-08  6:55                                         ` Yuri Khan
  2022-07-08 11:44                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-08 12:06                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-08 12:11                                           ` Christopher Dimech
                                                             ` (2 subsequent siblings)
  4 siblings, 0 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-08 12:06 UTC (permalink / raw)
  To: Yuri Khan; +Cc: help-gnu-emacs

Jul 8, 2022, 06:55 by yuri.v.khan@gmail.com:

> On Fri, 8 Jul 2022 at 13:31, Emanuel Berg <incal@dataswamp.org> wrote:
>
>> > It does not matter for interactive use. [...] ‘&optional’
>> > comes into play if you use this function non-interactively,
>> > from Lisp
>>
>> No, it matters. One example how it matters is that optional
>> arguments defaults to nil.
>>
>
> You’re right, with an interactive specification that evaluates to a
> list it matters, because the list you return may or may not have as
> many arguments as the function takes.
>
> My point was that in the specific case of a three-argument function
> and a three-item string-valued interactive specification, &optional
> does not matter for interactive use.
>
>
>> Check out this file and in particular example 4 which doesn't
>> make sense to me?
>>
>> ;; DWIM example 1, from Lisp ignore region if set
>> ;; example 2, use the region if available from Lisp as well
>>
>> (defun test-dwim (&optional beg end)
>>  (interactive (when (use-region-p)
>>  (list (region-beginning) (region-end)) ))
>>
>
> Here you have two cases. If the region is active, you produce a
> two-element list, otherwise, a 0-element list. The function signature
> allows 0..2 arguments, so it works in either case.
>
>> ;; example 3, one call to `use-region-p' is enough
>>
>> (defun test-dwim-3 (re &optional beg end)
>>  (interactive `(,(read-regexp "re: ")
>>  ,@(when (use-region-p)
>>  (list (region-beginning) (region-end)) )))
>>
>
> Mostly same, except you build a list of 3 or 1 elements, and the
> function accepts 1..3 arguments.
>
>> ;; example 4, let's do that with the `interactive' spec
>> ;; string. but without `use-region-p' it doesn't reset after
>> ;; I clear the region, or that's what I thought happened
>> ;; anyway :) so this doesn't work as intended, which
>> ;; `test-dwim-3' does, supposedly the worse one.
>>
>> (defun test-dwim-4 (re &optional beg end)
>>  (interactive "sre: \nr")
>>
>
> Here you use a string interactive spec which always produces 3
> elements. In non-interactive use, it will work if called as
> (test-dwim-4 "^foo$"), (test-dwim-4 "^foo$" 42), or (test-dwim-4
> "^foo$" 42 69).
>
> As to your “clearing” the region, Emacs always maintains the point and
> mark positions, and the ‘r’ interactive spec code ignores the region
> activation flag and always passes the point and mark. (This could be
> considered a bug, but I see no good alternative behavior, except maybe
> passing two nils if the region is not active.)
>
There seems to exist total confusion on how to use the interactive clause and how 
when to use mandatory or optional arguments, and how to handle them.  


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

* Re: Making a function than can only be used interactively
  2022-07-08  6:55                                         ` Yuri Khan
  2022-07-08 11:44                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-08 12:06                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-08 12:11                                           ` Christopher Dimech
       [not found]                                           ` <N6Sh4jm--3-2@tutanota.com-N6ShCt5----2>
  2022-07-08 16:14                                           ` Christopher Dimech
  4 siblings, 0 replies; 58+ messages in thread
From: Christopher Dimech @ 2022-07-08 12:11 UTC (permalink / raw)
  To: Yuri Khan; +Cc: help-gnu-emacs




> Sent: Friday, July 08, 2022 at 6:55 PM
> From: "Yuri Khan" <yuri.v.khan@gmail.com>
> To: "help-gnu-emacs" <help-gnu-emacs@gnu.org>
> Subject: Re: Making a function than can only be used interactively
>
> On Fri, 8 Jul 2022 at 13:31, Emanuel Berg <incal@dataswamp.org> wrote:
> 
> > > It does not matter for interactive use. [...] ‘&optional’
> > > comes into play if you use this function non-interactively,
> > > from Lisp
> >
> > No, it matters. One example how it matters is that optional
> > arguments defaults to nil.
> 
> You’re right, with an interactive specification that evaluates to a
> list it matters, because the list you return may or may not have as
> many arguments as the function takes.
> 
> My point was that in the specific case of a three-argument function
> and a three-item string-valued interactive specification, &optional
> does not matter for interactive use.
> 
> 
> > Check out this file and in particular example 4 which doesn't
> > make sense to me?
> >
> > ;; DWIM example 1, from Lisp ignore region if set
> > ;; example 2, use the region if available from Lisp as well
> >
> > (defun test-dwim (&optional beg end)
> >   (interactive (when (use-region-p)
> >                  (list (region-beginning) (region-end)) ))
> 
> Here you have two cases. If the region is active, you produce a
> two-element list, otherwise, a 0-element list. The function signature
> allows 0..2 arguments, so it works in either case.
> 
> > ;; example 3, one call to `use-region-p' is enough
> >
> > (defun test-dwim-3 (re &optional beg end)
> >   (interactive `(,(read-regexp "re: ")
> >                  ,@(when (use-region-p)
> >                      (list (region-beginning) (region-end)) )))
> 
> Mostly same, except you build a list of 3 or 1 elements, and the
> function accepts 1..3 arguments.
> 
> > ;; example 4, let's do that with the `interactive' spec
> > ;; string. but without `use-region-p' it doesn't reset after
> > ;; I clear the region, or that's what I thought happened
> > ;; anyway :) so this doesn't work as intended, which
> > ;; `test-dwim-3' does, supposedly the worse one.
> >
> > (defun test-dwim-4 (re &optional beg end)
> >   (interactive "sre: \nr")
> 
> Here you use a string interactive spec which always produces 3
> elements. In non-interactive use, it will work if called as
> (test-dwim-4 "^foo$"), (test-dwim-4 "^foo$" 42), or (test-dwim-4
> "^foo$" 42 69).
> 
> As to your “clearing” the region, Emacs always maintains the point and
> mark positions, and the ‘r’ interactive spec code ignores the region
> activation flag and always passes the point and mark. (This could be
> considered a bug, but I see no good alternative behavior, except maybe
> passing two nils if the region is not active.)
> 

When using the prefix argument, what makes sense?  A mandatory or an optional 
declaration for the prefix argument?



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

* Re: Making a function than can only be used interactively
       [not found]                                           ` <N6Sh4jm--3-2@tutanota.com-N6ShCt5----2>
@ 2022-07-08 12:18                                             ` carlmarcos--- via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 58+ messages in thread
From: carlmarcos--- via Users list for the GNU Emacs text editor @ 2022-07-08 12:18 UTC (permalink / raw)
  To: carlmarcos; +Cc: Yuri Khan, help-gnu-emacs


Jul 8, 2022, 12:06 by help-gnu-emacs@gnu.org:

> Jul 8, 2022, 06:55 by yuri.v.khan@gmail.com:
>
>> On Fri, 8 Jul 2022 at 13:31, Emanuel Berg <incal@dataswamp.org> wrote:
>>
>>> > It does not matter for interactive use. [...] ‘&optional’
>>> > comes into play if you use this function non-interactively,
>>> > from Lisp
>>>
>>> No, it matters. One example how it matters is that optional
>>> arguments defaults to nil.
>>>
>>
>> You’re right, with an interactive specification that evaluates to a
>> list it matters, because the list you return may or may not have as
>> many arguments as the function takes.
>>
>> My point was that in the specific case of a three-argument function
>> and a three-item string-valued interactive specification, &optional
>> does not matter for interactive use.
>>
What should one be concerned with most when deciding when and what arguments
are defined as optional.  When in non-interactive mode, or in interactive mode?



>>> Check out this file and in particular example 4 which doesn't
>>> make sense to me?
>>>
>>> ;; DWIM example 1, from Lisp ignore region if set
>>> ;; example 2, use the region if available from Lisp as well
>>>
>>> (defun test-dwim (&optional beg end)
>>>  (interactive (when (use-region-p)
>>>  (list (region-beginning) (region-end)) ))
>>>
>>
>> Here you have two cases. If the region is active, you produce a
>> two-element list, otherwise, a 0-element list. The function signature
>> allows 0..2 arguments, so it works in either case.
>>
>>> ;; example 3, one call to `use-region-p' is enough
>>>
>>> (defun test-dwim-3 (re &optional beg end)
>>>  (interactive `(,(read-regexp "re: ")
>>>  ,@(when (use-region-p)
>>>  (list (region-beginning) (region-end)) )))
>>>
>>
>> Mostly same, except you build a list of 3 or 1 elements, and the
>> function accepts 1..3 arguments.
>>
>>> ;; example 4, let's do that with the `interactive' spec
>>> ;; string. but without `use-region-p' it doesn't reset after
>>> ;; I clear the region, or that's what I thought happened
>>> ;; anyway :) so this doesn't work as intended, which
>>> ;; `test-dwim-3' does, supposedly the worse one.
>>>
>>> (defun test-dwim-4 (re &optional beg end)
>>>  (interactive "sre: \nr")
>>>
>>
>> Here you use a string interactive spec which always produces 3
>> elements. In non-interactive use, it will work if called as
>> (test-dwim-4 "^foo$"), (test-dwim-4 "^foo$" 42), or (test-dwim-4
>> "^foo$" 42 69).
>>
>> As to your “clearing” the region, Emacs always maintains the point and
>> mark positions, and the ‘r’ interactive spec code ignores the region
>> activation flag and always passes the point and mark. (This could be
>> considered a bug, but I see no good alternative behavior, except maybe
>> passing two nils if the region is not active.)
>>
> There seems to exist total confusion on how to use the interactive clause and how 
> when to use mandatory or optional arguments, and how to handle them. 
>



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

* Re: Making a function than can only be used interactively
  2022-07-08  6:55                                         ` Yuri Khan
                                                             ` (3 preceding siblings ...)
       [not found]                                           ` <N6Sh4jm--3-2@tutanota.com-N6ShCt5----2>
@ 2022-07-08 16:14                                           ` Christopher Dimech
  4 siblings, 0 replies; 58+ messages in thread
From: Christopher Dimech @ 2022-07-08 16:14 UTC (permalink / raw)
  To: Yuri Khan; +Cc: help-gnu-emacs


> Sent: Friday, July 08, 2022 at 6:55 PM
> From: "Yuri Khan" <yuri.v.khan@gmail.com>
> To: "help-gnu-emacs" <help-gnu-emacs@gnu.org>
> Subject: Re: Making a function than can only be used interactively
>
> On Fri, 8 Jul 2022 at 13:31, Emanuel Berg <incal@dataswamp.org> wrote:
> 
> > > It does not matter for interactive use. [...] ‘&optional’
> > > comes into play if you use this function non-interactively,
> > > from Lisp
> >
> > No, it matters. One example how it matters is that optional
> > arguments defaults to nil.
> 
> You’re right, with an interactive specification that evaluates to a
> list it matters, because the list you return may or may not have as
> many arguments as the function takes.
> 
> My point was that in the specific case of a three-argument function
> and a three-item string-valued interactive specification, &optional
> does not matter for interactive use.


It looks as if the easiest understanding of mandatory versus optional
function arguments occurs when using a function interactively.

For the interactive case, it is quite complicated, depending on whether
the function uses code characters or a list.

My proposition would be to include the corresponding explanation on using
in either the "Emacs Lisp Reference Manual" or the "Introduction to Programming
in Emacs Lisp".



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

* Re: Making a function than can only be used interactively
  2022-07-08 11:44                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
@ 2022-07-09  2:05                                             ` Emanuel Berg
  2022-07-10  4:33                                             ` Emanuel Berg
  1 sibling, 0 replies; 58+ messages in thread
From: Emanuel Berg @ 2022-07-09  2:05 UTC (permalink / raw)
  To: help-gnu-emacs

carlmarcos--- via Users list for the GNU Emacs text editor wrote:

>> You’re right, with an interactive specification that
>> evaluates to a list it matters, because the list you return
>> may or may not have as many arguments as the
>> function takes.
>
> Using a list in the most general way to use interactive. 
> I need specific rules for using a list, how to decide
> whether the arguments should be mandatory or optional.

Rule for using a list: When it gets too complicated to use the
interactive spec string. Try that first.

Rule for mandatory: When the operation to be carried out don't
make sense without that information, then it's mandatory.
Blow up a bomb. WHEN, WHERE and what BOMB, those are
mandatory. Optional WHY. If provided, there will be
a communique (in lowercase-only letters) to the press (not
Springer media) and that will be the WHY argument. So if you
write something there that hasn't anything to do with the
attentat that will be published just as well! So be careful
and think before you act.

Optional arguments can also be fancy features and the default
is, not enabled. You may have heard of para-arithmetic
transcendence, instigated by the de facto information
conglomerate known to us only as the Dark Druids. That's the
kin of thing you realize, it's not gonna happen just
by itself ever again.

Those days are over :(

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




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

* Re: Making a function than can only be used interactively
  2022-07-08 11:44                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
  2022-07-09  2:05                                             ` Emanuel Berg
@ 2022-07-10  4:33                                             ` Emanuel Berg
  1 sibling, 0 replies; 58+ messages in thread
From: Emanuel Berg @ 2022-07-10  4:33 UTC (permalink / raw)
  To: help-gnu-emacs

carlmarcos--- via Users list for the GNU Emacs text editor wrote:

> Using a list in the most general way to use interactive.
> I need specific rules for using a list, how to decide
> whether the arguments should be mandatory or optional.

Use your mind and instinct to solve the specific situation.
When the next situation arrives, do the same. I don't think
you have to do that that many times before you don't need
rules anyway for that. Especially since it isn't really
difficult, right?

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




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

end of thread, other threads:[~2022-07-10  4:33 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-04 23:42 Making a function than can only be used interactively Christopher Dimech
  -- strict thread matches above, loose matches on Subject: below --
2022-07-04 21:07 Christopher Dimech
2022-07-04 21:45 ` Stefan Monnier
2022-07-04 22:05   ` Christopher Dimech
2022-07-04 22:35     ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-07-04 23:33     ` Christopher Dimech
2022-07-04 20:10 Christopher Dimech
2022-07-04 20:35 ` Stefan Monnier
2022-07-04 20:46   ` Christopher Dimech
2022-07-04 21:18     ` Stefan Monnier
2022-07-04 21:59       ` Christopher Dimech
2022-07-05 22:34       ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-04 19:32 Christopher Dimech
2022-07-03 19:16 carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-03 19:28 ` Bruno Barbier
     [not found] ` <N64WnlX--3-2@missing-mail-id>
2022-07-03 19:36   ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-03 19:53     ` Tassilo Horn
2022-07-03 20:17       ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-04  4:51         ` Tassilo Horn
2022-07-05 23:13       ` Emanuel Berg
2022-07-03 20:14     ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-07-03 20:27       ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-03 20:51       ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-03 21:18         ` Stefan Monnier
2022-07-03 21:29       ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-03 22:01         ` Stefan Monnier via Users list for the GNU Emacs text editor
2022-07-03 22:45           ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-04  1:13             ` Stefan Monnier
     [not found]             ` <jwvczelllyq.fsf-monnier+emacs@gnu.org-N65lQ2m----2>
2022-07-04 10:36               ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-04 10:55                 ` Tassilo Horn
2022-07-04 11:43                   ` Christopher Dimech
2022-07-04 13:21                     ` Stefan Monnier
2022-07-04 14:08                       ` Robert Pluim
2022-07-04 21:40                       ` Christopher Dimech
2022-07-05 17:35                         ` Jean Louis
2022-07-04 19:17                   ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-04 19:40                     ` Stefan Monnier
2022-07-04 19:50                       ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-04 20:45                         ` Stefan Monnier
2022-07-06  0:07                         ` Jean Louis
2022-07-06 20:00                           ` Christopher Dimech
2022-07-06 20:29                             ` Jean Louis
2022-07-07 11:03                               ` Christopher Dimech
2022-07-07 21:06                               ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-07 21:28                                 ` Emanuel Berg
2022-07-07 22:14                                   ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-08  3:40                                     ` Emanuel Berg
2022-07-08  6:08                                     ` Yuri Khan
2022-07-08  6:30                                       ` Emanuel Berg
2022-07-08  6:55                                         ` Yuri Khan
2022-07-08 11:44                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-09  2:05                                             ` Emanuel Berg
2022-07-10  4:33                                             ` Emanuel Berg
2022-07-08 12:06                                           ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-08 12:11                                           ` Christopher Dimech
     [not found]                                           ` <N6Sh4jm--3-2@tutanota.com-N6ShCt5----2>
2022-07-08 12:18                                             ` carlmarcos--- via Users list for the GNU Emacs text editor
2022-07-08 16:14                                           ` Christopher Dimech
2022-07-04  1:06     ` Po Lu

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