LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-30-2013, 12:52 AM   #1
hydraMax
Member
 
Registered: Jul 2010
Location: Skynet
Distribution: Debian + Emacs
Posts: 467
Blog Entries: 60

Rep: Reputation: 51
emacs lisp: naming convention for interactive/non-interactive function pairs


Hi. I am new to Emacs Lisp. Is there convention about how you should name function pairs, where one function is the non-interactive version and one is the interactive version?

For the functions I'm coding it makes sense to have a non-interactive version that performs the core calculation, and another to be an interactive wrapper which messages the result, etc.
 
Old 05-30-2013, 06:49 AM   #2
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
I'm unaware of any such convention but take a look at `called-interactively-p' which you can use to test whether function was called interactively or not and depending on the result message the result. In fact, keeping both kinds of functionalities in the same function may be beneficial as it helps with discovery – one does not need to remember two function names. So you could do:
Code:
(defun foo ()
  (let ((result (… do the calculation …)))
    (when (called-interactively-p)
      (message "%s" result))
    result))
Or if you really want to separate the main logic into another function, I'd use “--”:
Code:
(defun foo--do-calculate ()
  … do the calculation …)

(defun foo ()
  (let ((result (foo--do-calculate)))
    (when (called-interactively-p)
      (message "%s" result))
    result))
 
1 members found this post helpful.
Old 05-30-2013, 09:16 AM   #3
hydraMax
Member
 
Registered: Jul 2010
Location: Skynet
Distribution: Debian + Emacs
Posts: 467

Original Poster
Blog Entries: 60

Rep: Reputation: 51
Thanks! I tried your first suggestion and it seems to work great.
 
Old 05-30-2013, 11:10 PM   #4
hydraMax
Member
 
Registered: Jul 2010
Location: Skynet
Distribution: Debian + Emacs
Posts: 467

Original Poster
Blog Entries: 60

Rep: Reputation: 51
Hi again. I am hoping to get your insight on a small issue that has appeared relating to the solution you gave me. To provide a working example, I have this function:

Code:
(defun cm-sphere-volume (r)
  "Calculate the volume of a sphere from the radius."
  (interactive "nradius: ")
  (let ((result (* (/ 4.0 3.0) pi (expt r 3))))
    (when (called-interactively-p)
      (message "%.15f" result)) result))
This works great. However, when I byte-compile, I get this warning:

Code:
In cm-sphere-volume:
math.el:29:12:Warning: called-interactively-p called with 0 arguments, but
    requires 1
I checked the documentation for the called-interactively-p function. It still isn't quite clear to me, but I expected this to work:

Code:
(defun cm-sphere-volume (r)
  "Calculate the volume of a sphere from the radius."
  (interactive "nradius: ")
  (let ((result (* (/ 4.0 3.0) pi (expt r 3))))
    (when (called-interactively-p (interactive))
      (message "%.15f" result)) result))
But, in this case, I get the error:

Code:
In cm-sphere-volume:
math.el:27:4:Warning: misplaced interactive spec: `(interactive)'
Again - I really like the the approach you suggested here (a single function serving both interactive and non-interactive uses) but I'm inclined never to ignore compiler warning messages without at least understanding what is going on.
 
Old 05-30-2013, 11:13 PM   #5
hydraMax
Member
 
Registered: Jul 2010
Location: Skynet
Distribution: Debian + Emacs
Posts: 467

Original Poster
Blog Entries: 60

Rep: Reputation: 51
Oh, sorry, just figured it out. Apparently it needs to be like so:

Code:
(defun cm-sphere-volume (r)
  "Calculate the volume of a sphere from the radius."
  (interactive "nradius: ")
  (let ((result (* (/ 4.0 3.0) pi (expt r 3))))
    (when (called-interactively-p 'interactive)
      (message "%.15f" result)) result))
The solution always seems to come to me about two seconds after hitting the submit button. :|

Last edited by hydraMax; 05-30-2013 at 11:14 PM.
 
Old 05-30-2013, 11:22 PM   #6
hydraMax
Member
 
Registered: Jul 2010
Location: Skynet
Distribution: Debian + Emacs
Posts: 467

Original Poster
Blog Entries: 60

Rep: Reputation: 51
Hmm, this seems to work as well...

Code:
(defun cm-sphere-volume (r)
  "Calculate the volume of a sphere from the radius."
  (interactive "nradius: ")
  (let ((result (* (/ 4.0 3.0) pi (expt r 3))))
    (when (called-interactively-p 'bla)
      (message "%.15f" result)) result))
So probably there is something I don't understand correctly.
 
Old 05-31-2013, 12:01 AM   #7
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,786

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
Whenever you don't understand a function you can look at it's documentation with <f1> f function-name RET:

Code:
called-interactively-p is a compiled Lisp function in `subr.el'.

(called-interactively-p KIND)

Return t if the containing function was called by `call-interactively'.
If KIND is `interactive', then only return t if the call was made
interactively by the user, i.e. not in `noninteractive' mode nor
when `executing-kbd-macro'.
If KIND is `any', on the other hand, it will return t for any kind of
interactive call, including being called as the binding of a key or
from a keyboard macro, even in `noninteractive' mode.

...
Actually, if you look at the source it's not (currently) checking for 'any explicitly: anything that isn't 'interactive counts as 'any.


The doc also says
Code:
Instead of using this function, it is cleaner and more reliable to give your
function an extra optional argument whose `interactive' spec specifies
non-nil unconditionally ("p" is a good way to do this), or via
(not (or executing-kbd-macro noninteractive)).
Which suggests doing something like:

Code:
(defun cm-sphere-volume (r &optional interactive)
  "Calculate the volume of a sphere from the radius."
  (interactive "nradius: \np")
  (let ((result (* (/ 4.0 3.0) pi (expt r 3))))
    (when interactive
      (message "%.15f" result))
    result))
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
emacs lisp: define function to be used inside emacs stateless Programming 1 03-01-2013 05:04 PM
C - Function naming convention golmschenk Programming 10 02-16-2010 08:14 PM
Emacs LISP - function and keymap? jantman Programming 5 09-28-2006 11:59 AM
interactive and non-interactive shell linuxjamil Programming 3 09-03-2006 08:42 PM
mail server the naming naming convention problem kashan Linux - Newbie 0 07-16-2004 02:08 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:35 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration