all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* emacs lisp - unable to write a function maker
@ 2011-09-16  8:46 C K Kashyap
  2011-09-16  8:58 ` Thien-Thi Nguyen
  0 siblings, 1 reply; 10+ messages in thread
From: C K Kashyap @ 2011-09-16  8:46 UTC (permalink / raw)
  To: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 417 bytes --]

Hi,
I was trying to write a function that would help in creating various
abbreviation functions.


(defun makeAbrevFun (name val)
  (eval
   (defun name () (insert val))))

The intention is that the below code would create a function called "aa"
(makeAbrevFun 'aa "aaaaaaaaaaaaaa")
That can be invoked by doing (aa)C-X C-e
This does not work. Could someone please let me know how I can achieve this?
Regards,
Kashyap

[-- Attachment #2: Type: text/html, Size: 617 bytes --]

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

* Re: emacs lisp - unable to write a function maker
  2011-09-16  8:46 emacs lisp - unable to write a function maker C K Kashyap
@ 2011-09-16  8:58 ` Thien-Thi Nguyen
  2011-09-16  9:26   ` C K Kashyap
  0 siblings, 1 reply; 10+ messages in thread
From: Thien-Thi Nguyen @ 2011-09-16  8:58 UTC (permalink / raw)
  To: C K Kashyap; +Cc: help-gnu-emacs

() C K Kashyap <ckkashyap@gmail.com>
() Fri, 16 Sep 2011 14:16:04 +0530

   Could someone please let me know how I can achieve this?

Don't be so hasty; pass ‘eval’ something that is not yet ‘eval’ed.



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

* Re: emacs lisp - unable to write a function maker
  2011-09-16  8:58 ` Thien-Thi Nguyen
@ 2011-09-16  9:26   ` C K Kashyap
  2011-09-16  9:40     ` Thien-Thi Nguyen
  2011-09-16  9:57     ` Eric Abrahamsen
  0 siblings, 2 replies; 10+ messages in thread
From: C K Kashyap @ 2011-09-16  9:26 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 418 bytes --]

On Fri, Sep 16, 2011 at 2:28 PM, Thien-Thi Nguyen <ttn@gnuvola.org> wrote:

> () C K Kashyap <ckkashyap@gmail.com>
> () Fri, 16 Sep 2011 14:16:04 +0530
>
>   Could someone please let me know how I can achieve this?
>
> Don't be so hasty; pass ‘eval’ something that is not yet ‘eval’ed.
>

Actually, I used eval because I noticed that if I did not, the formal
parameter "name" becomes the defined function.

[-- Attachment #2: Type: text/html, Size: 748 bytes --]

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

* Re: emacs lisp - unable to write a function maker
  2011-09-16  9:26   ` C K Kashyap
@ 2011-09-16  9:40     ` Thien-Thi Nguyen
  2011-09-16  9:57     ` Eric Abrahamsen
  1 sibling, 0 replies; 10+ messages in thread
From: Thien-Thi Nguyen @ 2011-09-16  9:40 UTC (permalink / raw)
  To: C K Kashyap; +Cc: help-gnu-emacs

() C K Kashyap <ckkashyap@gmail.com>
() Fri, 16 Sep 2011 14:56:38 +0530

   Actually, I used eval because I noticed that if I did not,
   the formal parameter "name" becomes the defined function.

Does this reasoning hold across reboot (Emacs exit + restart)?



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

* Re: emacs lisp - unable to write a function maker
  2011-09-16  9:26   ` C K Kashyap
  2011-09-16  9:40     ` Thien-Thi Nguyen
@ 2011-09-16  9:57     ` Eric Abrahamsen
  2011-09-16 10:17       ` C K Kashyap
  2011-09-16 14:06       ` Drew Adams
  1 sibling, 2 replies; 10+ messages in thread
From: Eric Abrahamsen @ 2011-09-16  9:57 UTC (permalink / raw)
  To: help-gnu-emacs

On Fri, Sep 16 2011, C K Kashyap wrote:

> On Fri, Sep 16, 2011 at 2:28 PM, Thien-Thi Nguyen <ttn@gnuvola.org>
> wrote:
>
>     () C K Kashyap <ckkashyap@gmail.com>
>     () Fri, 16 Sep 2011 14:16:04 +0530
>    
>       Could someone please let me know how I can achieve this?
>    
>     Don't be so hasty; pass ‘eval’ something that is not yet
>     ‘eval’ed.
>
>
> Actually, I used eval because I noticed that if I did not, the formal
> parameter "name" becomes the defined function.

Perhaps I'm ruining some didactic exercise here, but if you're using
eval on something you don't want eval'd until the function is run, you
should backquote it. This works for me:


(defun functionmaker (name form)
  (eval
   `(defun ,name ()
      ,form)))

I used to associate backquoting exclusively with macros, but I think
that was wrong thinking.

Hope someone will correct me if I've done something dumb here…

Eric

-- 
GNU Emacs 23.2.1 (i686-pc-linux-gnu, GTK+ Version 2.24.4)
 of 2011-04-04 on rothera, modified by Debian




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

* Re: emacs lisp - unable to write a function maker
  2011-09-16  9:57     ` Eric Abrahamsen
@ 2011-09-16 10:17       ` C K Kashyap
  2011-09-16 11:19         ` Eric Abrahamsen
  2011-09-16 14:06       ` Drew Adams
  1 sibling, 1 reply; 10+ messages in thread
From: C K Kashyap @ 2011-09-16 10:17 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 654 bytes --]

>
> Perhaps I'm ruining some didactic exercise here, but if you're using
> eval on something you don't want eval'd until the function is run, you
> should backquote it. This works for me:
>
>
> (defun functionmaker (name form)
>  (eval
>   `(defun ,name ()
>      ,form)))
>
> I used to associate backquoting exclusively with macros, but I think
> that was wrong thinking.
>
> Hope someone will correct me if I've done something dumb here…
>


Wow .. .This worked as I was wanting ... Could you please point me to some
documentation that would help me with things like, when to use "," in front
of the name etc?

Regards,
Kashyap

[-- Attachment #2: Type: text/html, Size: 927 bytes --]

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

* Re: emacs lisp - unable to write a function maker
  2011-09-16 10:17       ` C K Kashyap
@ 2011-09-16 11:19         ` Eric Abrahamsen
  0 siblings, 0 replies; 10+ messages in thread
From: Eric Abrahamsen @ 2011-09-16 11:19 UTC (permalink / raw)
  To: help-gnu-emacs

On Fri, Sep 16 2011, C K Kashyap wrote:

>     Perhaps I'm ruining some didactic exercise here, but if you're
>     using
>     eval on something you don't want eval'd until the function is
>     run, you
>     should backquote it. This works for me:
>    
>    
>     (defun functionmaker (name form)
>      (eval
>       `(defun ,name ()
>          ,form)))
>    
>     I used to associate backquoting exclusively with macros, but I
>     think
>     that was wrong thinking.
>    
>     Hope someone will correct me if I've done something dumb here…
>
>
>
> Wow .. .This worked as I was wanting ... Could you please point me to
> some documentation that would help me with things like, when to use
> "," in front of the name etc?
>
> Regards,
> Kashyap 

I'm the wrong one to ask about this -- my elisp only works because of
liberal sprinklings of pixie dust -- but if you read the elisp manual on
macros, and keep in mind that backquoting works in contexts other than
that of macros, you'll be most of the way there. What I used in this
tiny example (plus the ,@ form for splicing lists) is pretty much all
there is to it, though the ramifications do get complicated…

Good luck!

E

-- 
GNU Emacs 23.2.1 (i686-pc-linux-gnu, GTK+ Version 2.24.4)
 of 2011-04-04 on rothera, modified by Debian




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

* RE: emacs lisp - unable to write a function maker
  2011-09-16  9:57     ` Eric Abrahamsen
  2011-09-16 10:17       ` C K Kashyap
@ 2011-09-16 14:06       ` Drew Adams
  2011-09-23 15:31         ` Tim Landscheidt
  1 sibling, 1 reply; 10+ messages in thread
From: Drew Adams @ 2011-09-16 14:06 UTC (permalink / raw)
  To: 'Eric Abrahamsen', help-gnu-emacs

> if you're using eval on something you don't want eval'd
> until the function is run, you should backquote it.
> 
> (defun functionmaker (name form)
>   (eval `(defun ,name () ,form)))
> 
> I used to associate backquoting exclusively with macros, but I think
> that was wrong thinking.

Right.

But if you're evaluating the entire constructed form once at the top level like
that, then you likely do want to use a macro. That's just what a Lisp macro is:
a function that returns code that then gets evaluated.

(defmacro functionmaker (name form)
 `(defun ,name () ,form))

Or, for the original question:

(defmacro makeAbrevFun (name val)
 `(defun ,name () (insert ,val)))

(makeAbrevFun aa "aaaaaaaaaaaaaa")

Well, not quite - the OP quoted the function symbol, indicating that s?he would
pass something that needs to be eval'd. If that's rally part of the requirement,
then:

(defmacro makeAbrevFun (name val)
 `(defun ,(eval name) () (insert ,val)))

(makeAbrevFun 'aa "aaaaaaaaaaaaaa")

In both cases: (symbol-function 'aa) gives:
(lambda () (insert "aaaaaaaaaaaaaa"))




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

* Re: emacs lisp - unable to write a function maker
  2011-09-16 14:06       ` Drew Adams
@ 2011-09-23 15:31         ` Tim Landscheidt
  2011-09-23 16:43           ` Drew Adams
  0 siblings, 1 reply; 10+ messages in thread
From: Tim Landscheidt @ 2011-09-23 15:31 UTC (permalink / raw)
  To: help-gnu-emacs

"Drew Adams" <drew.adams@oracle.com> wrote:

> [...]
> Well, not quite - the OP quoted the function symbol, indicating that s?he would
> pass something that needs to be eval'd. If that's rally part of the requirement,
> then:

> (defmacro makeAbrevFun (name val)
>  `(defun ,(eval name) () (insert ,val)))

> (makeAbrevFun 'aa "aaaaaaaaaaaaaa")

> In both cases: (symbol-function 'aa) gives:
> (lambda () (insert "aaaaaaaaaaaaaa"))

On a related note - how do I proceed if I do not want to
create a macro that creates a function, but create multiple
functions directly? For example, after some trial and error
my ~/.emacs ended up with (paraphrased):

| (dolist (i '(("once"   . 1)
|              ("twice"  . 2)
|              ("thrice" . 3)))
|   (fset (intern (concat "tl-say-" (downcase (car i))))
|         `(lambda (s)
|            ,(concat "Say S only " (car i) ".")
|            (interactive "sWhat to message: ")
|            (dotimes (j ,(cdr i))
|              (message "I say it only %s: %s." ,(car i) s)))))

I didn't manage to use defun as I got stuck in quoting and
non-quoting "magic".

Tim




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

* RE: emacs lisp - unable to write a function maker
  2011-09-23 15:31         ` Tim Landscheidt
@ 2011-09-23 16:43           ` Drew Adams
  0 siblings, 0 replies; 10+ messages in thread
From: Drew Adams @ 2011-09-23 16:43 UTC (permalink / raw)
  To: 'Tim Landscheidt', help-gnu-emacs

> how do I proceed if I do not want to
> create a macro that creates a function, but create multiple
> functions directly? For example, after some trial and error
> my ~/.emacs ended up with (paraphrased):
> 
> | (dolist (i '(("once"   . 1)
> |              ("twice"  . 2)
> |              ("thrice" . 3)))
> |   (fset (intern (concat "tl-say-" (downcase (car i))))
> |         `(lambda (s)
> |            ,(concat "Say S only " (car i) ".")
> |            (interactive "sWhat to message: ")
> |            (dotimes (j ,(cdr i))
> |              (message "I say it only %s: %s." ,(car i) s)))))
> 
> I didn't manage to use defun as I got stuck in quoting and
> non-quoting "magic".

Are you asking how you would do that using `defun' instead of `fset', but
without using a macro?  Here's one answer:

(dolist (i '(("once"   . 1)
             ("twice"  . 2)
             ("thrice" . 3)))
  (eval `(defun ,(intern (concat "tl-say-" (downcase (car i)))) 
           (s)
           ,(concat "Say S only " (car i) ".")
           (interactive "sWhat to message: ")
           (dotimes (j ,(cdr i))
             (message "I say it only %s: %s." ,(car i) s)))))

(pp-eval-expression '(symbol-function 'tl-say-twice))

`defun' is a special form (which is similar to a macro).  It does not evaluate
its args. So if you want to construct the function name then you must construct
a `defun' form that uses that constructed name, and then evaluate that form.

There's nothing magic about quoting, but evaluation and quoting do take a little
getting used to.  What can be confusing is that special forms and macros do not,
a priori, evaluate their arguments.  A macro constructs code that then gets
evaluated (normally).

To debug macros you are working on, use `macroexpand': it expands a macro form
without also evaluating the resulting code.




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

end of thread, other threads:[~2011-09-23 16:43 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-16  8:46 emacs lisp - unable to write a function maker C K Kashyap
2011-09-16  8:58 ` Thien-Thi Nguyen
2011-09-16  9:26   ` C K Kashyap
2011-09-16  9:40     ` Thien-Thi Nguyen
2011-09-16  9:57     ` Eric Abrahamsen
2011-09-16 10:17       ` C K Kashyap
2011-09-16 11:19         ` Eric Abrahamsen
2011-09-16 14:06       ` Drew Adams
2011-09-23 15:31         ` Tim Landscheidt
2011-09-23 16:43           ` Drew Adams

Code repositories for project(s) associated with this external index

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

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