* Quoted function in `define-key' @ 2017-02-04 10:20 Narendra Joshi 2017-02-04 11:11 ` Narendra Joshi ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Narendra Joshi @ 2017-02-04 10:20 UTC (permalink / raw) To: help-gnu-emacs The following piece of code is confusing me. It is from `rinari-minor-mode'. (dolist (el (append (mapcar (lambda (el) (cons (concat "f" (second el)) (read (format "'rinari-find-%S" (first el))))) rinari-jump-schema) rinari-minor-mode-keybindings)) (eval `(define-key rinari-prefix-map ,(car el) ,(cdr el)))) If I replace the last expression with: (define-key rinari-prefix-map (car el) (cdr el)) why does it fail? (cdr el) is (quote function-name) which is exactly the same as 'function-name. -- Narendra Joshi ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-04 10:20 Quoted function in `define-key' Narendra Joshi @ 2017-02-04 11:11 ` Narendra Joshi 2017-02-04 12:05 ` Michael Heerdegen 2017-02-04 18:10 ` Stefan Monnier 2 siblings, 0 replies; 10+ messages in thread From: Narendra Joshi @ 2017-02-04 11:11 UTC (permalink / raw) To: Narendra Joshi; +Cc: help-gnu-emacs Narendra Joshi <narendraj9@gmail.com> writes: > The following piece of code is confusing me. It is from `rinari-minor-mode'. > > (dolist (el (append (mapcar > (lambda (el) > (cons (concat "f" (second el)) > (read (format "'rinari-find-%S" > (first el))))) > rinari-jump-schema) > rinari-minor-mode-keybindings)) > (eval `(define-key rinari-prefix-map ,(car el) ,(cdr el)))) I have also tried changing this ^ to (let ((key (car el)) (func (cdr el))) (define-key rinari-prefix-map key func)) I thought maybe `define-key` is a macro and hence the calls to `car` and `cdr` might not be evaluated. But that doesn't seem to be the case. This still fails. The key is bound to a value that is equal to (quote some-function-name). -- Narendra Joshi ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-04 10:20 Quoted function in `define-key' Narendra Joshi 2017-02-04 11:11 ` Narendra Joshi @ 2017-02-04 12:05 ` Michael Heerdegen 2017-02-04 15:03 ` Narendra Joshi 2017-02-04 18:10 ` Stefan Monnier 2 siblings, 1 reply; 10+ messages in thread From: Michael Heerdegen @ 2017-02-04 12:05 UTC (permalink / raw) To: Narendra Joshi; +Cc: help-gnu-emacs Narendra Joshi <narendraj9@gmail.com> writes: > The following piece of code is confusing me. It is from `rinari-minor-mode'. > > (dolist (el (append (mapcar > (lambda (el) > (cons (concat "f" (second el)) > (read (format "'rinari-find-%S" > (first el))))) > rinari-jump-schema) > rinari-minor-mode-keybindings)) > (eval `(define-key rinari-prefix-map ,(car el) ,(cdr el)))) > > > If I replace the last expression with: > > (define-key rinari-prefix-map (car el) (cdr el)) > > why does it fail? > > (cdr el) is (quote function-name) which is exactly the same as > 'function-name. Sure, but this is then not evaluated again, and you want the DEF argument of `define-key' to be function-name, not (quote function-name). And yes, using `eval' in this context is indeed overkill (as well as `read' which could be replaced with `intern'). Michael. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-04 12:05 ` Michael Heerdegen @ 2017-02-04 15:03 ` Narendra Joshi 2017-02-04 17:25 ` Michael Heerdegen 0 siblings, 1 reply; 10+ messages in thread From: Narendra Joshi @ 2017-02-04 15:03 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Narendra Joshi, help-gnu-emacs Michael Heerdegen <michael_heerdegen@web.de> writes: > Sure, but this is then not evaluated again, and you want the DEF > argument of `define-key' to be function-name, not (quote function-name). Okay. Let me re-state this whole thing so that I can assure myself that I have understood. (quote my-function) is exactly the same as 'my-function, i.e. (eq (quote my-function) 'my-function) evaluates to t. But here we are talking about the result of evaluating (quote my-function) which isn't a cons but a symbol. But if we have `(quote my-function) that isn't the same as 'my-function. Side note: If anybody knows how to type inline code in gnus message, it would be greatly appreciated. -- Narendra Joshi ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-04 15:03 ` Narendra Joshi @ 2017-02-04 17:25 ` Michael Heerdegen 2017-02-05 10:10 ` Narendra Joshi 0 siblings, 1 reply; 10+ messages in thread From: Michael Heerdegen @ 2017-02-04 17:25 UTC (permalink / raw) To: Narendra Joshi; +Cc: help-gnu-emacs Narendra Joshi <narendraj9@gmail.com> writes: > (quote my-function) is exactly the same as 'my-function, i.e. Yes, the second is an alternative read syntax for the first expression. > (eq (quote my-function) 'my-function) evaluates to t. > > But here we are talking about the result of evaluating > > (quote my-function) which isn't a cons but a symbol. No, it's a list (and a cons), but the result of evaluation is a symbol. > But if we have `(quote my-function) that isn't the same as > 'my-function. `(quote my-function) and '(quote my-function) eval to the list (quote my-function). ''my-function is an alternative read syntax for '(quote my-function). But that all doesn't appear in the example. It's so: you want to specify a symbol as third argument to `define-key'. `define-key' is a function, so the argument positions are evaluated. Thus you want to specify an expression that evaluates to the symbol you want. (quote my-function) or 'my-function evaluate to the symbol you want. In (define-key rinari-prefix-map (car el) (cdr el)) the expression at that position is (cdr el), so that expression should eval to a symbol, not to a list like (quote symbol) - even when this list would give you what you want when it would be evaluated. Evaluation happens only once. With other words: when you write something like (define-key my-map keys 'my-function) you use the quote to prevent my-function from being evaluated, because you want to specify that symbol (unlike its binding as a variable), but _not_ because define-key would expect something quoted. BTW, most people prefer (define-key my-map keys #'my-function) however. #'my-function is a read syntax for (function my-function), where function is like quote but tells the byte compiler that the quoted thing is a function expression. > Side note: If anybody knows how to type inline code in gnus message, > it would be greatly appreciated. I use `message-mark-inserted-region' for multiline code, but I don't know of any rule for smaller snippets. Most of the time I don't care too much (like here). It's good style to quote a `symbol' like this, but I sometimes avoid it when code snippets already involve lots of quoting. HTH, Michael. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-04 17:25 ` Michael Heerdegen @ 2017-02-05 10:10 ` Narendra Joshi 2017-02-05 13:50 ` Michael Heerdegen 0 siblings, 1 reply; 10+ messages in thread From: Narendra Joshi @ 2017-02-05 10:10 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Narendra Joshi, help-gnu-emacs Michael Heerdegen <michael_heerdegen@web.de> writes: > Narendra Joshi <narendraj9@gmail.com> writes: > >> (quote my-function) is exactly the same as 'my-function, i.e. > > Yes, the second is an alternative read syntax for the first expression. > >> (eq (quote my-function) 'my-function) evaluates to t. >> >> But here we are talking about the result of evaluating >> >> (quote my-function) which isn't a cons but a symbol. > > No, it's a list (and a cons), but the result of evaluation is a symbol. > >> But if we have `(quote my-function) that isn't the same as >> 'my-function. > > `(quote my-function) and '(quote my-function) eval to the list > (quote my-function). ''my-function is an alternative read syntax for > '(quote my-function). But that all doesn't appear in the example. > > It's so: you want to specify a symbol as third argument to `define-key'. > `define-key' is a function, so the argument positions are evaluated. > Thus you want to specify an expression that evaluates to the symbol you > want. (quote my-function) or 'my-function evaluate to > the symbol you want. In > > (define-key rinari-prefix-map (car el) (cdr el)) > > the expression at that position is (cdr el), so that expression should > eval to a symbol, not to a list like (quote symbol) - even when this > list would give you what you want when it would be evaluated. > Evaluation happens only once. > > With other words: when you write something like > > (define-key my-map keys 'my-function) This was really helpful. Thanks! :) > > you use the quote to prevent my-function from being evaluated, because > you want to specify that symbol (unlike its binding as a variable), but > _not_ because define-key would expect something quoted. > > BTW, most people prefer > > (define-key my-map keys #'my-function) > however. #'my-function is a read syntax for (function my-function), > where function is like quote but tells the byte compiler that the quoted > thing is a function expression. So, the symbol `my-function' can have the function definition in its value slot? What does the byte compiler do with this information? I am just curious about this. If this is recommended, I would also start quoting my functions as #'my-function. >> Side note: If anybody knows how to type inline code in gnus message, >> it would be greatly appreciated. > > I use `message-mark-inserted-region' for multiline code, but I don't > know of any rule for smaller snippets. Most of the time I don't care > too much (like here). It's good style to quote a `symbol' like this, > but I sometimes avoid it when code snippets already involve lots of > quoting. Thanks! `message-mark-inserted-region' is good but I would probably change the boundary that it inserts. :) -- Narendra Joshi ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-05 10:10 ` Narendra Joshi @ 2017-02-05 13:50 ` Michael Heerdegen 2017-02-05 19:09 ` Narendra Joshi 0 siblings, 1 reply; 10+ messages in thread From: Michael Heerdegen @ 2017-02-05 13:50 UTC (permalink / raw) To: Narendra Joshi; +Cc: help-gnu-emacs Narendra Joshi <narendraj9@gmail.com> writes: > So, the symbol `my-function' can have the function definition in its > value slot? There's a separate slot for function bindings. You can refer to it directly with passing the symbol to `symbol-function'. So any symbol can have two separate "bindings" - a binding as a variable, and one as a function (unlike scheme, for example). That's why Elisp is a Lisp-2. Actually, there is one more cell for symbol property lists ("plists"). See (info "(elisp) Symbol Components") for more details. > What does the byte compiler do with this information? I am just > curious about this. When you sharp quote a lambda expression, the compiler knows that this lambda list is supposed to be called as a function, and will byte compile it. The evaluator might turn it into a closure when lexical binding is used. In elisp, the `lambda' macro comes with implicit function quoting (see its definition), so you can just omit it. But OTOH, it's an error to `quote' lambdas like '(lambda () body...) because it will prevent byte compilation or closure creation and make Stefan angry. Obviously for `function' quoted symbols there is not much to do, but the byte compiler can determine whether that function is defined/ will be defined at run time, so it can warn you about typos as an extra service. For example, you get a compiler warning when compiling (define-key my-map [key] #'make-frame-cmomand) but not for (define-key my-map [key] 'make-frame-cmomand) > If this is recommended, I would also start quoting my functions as > #'my-function. Yes, it's a good idea. Michael. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-05 13:50 ` Michael Heerdegen @ 2017-02-05 19:09 ` Narendra Joshi 2017-02-05 19:45 ` Michael Heerdegen 0 siblings, 1 reply; 10+ messages in thread From: Narendra Joshi @ 2017-02-05 19:09 UTC (permalink / raw) To: Michael Heerdegen; +Cc: Narendra Joshi, help-gnu-emacs Michael Heerdegen <michael_heerdegen@web.de> writes: > (info "(elisp) Symbol Components") How did you insert this link to info? > > >> What does the byte compiler do with this information? I am just >> curious about this. > > When you sharp quote a lambda expression, the compiler knows that this > lambda list is supposed to be called as a function, and will byte > compile it. The evaluator might turn it into a closure when lexical > binding is used. > > In elisp, the `lambda' macro comes with implicit function quoting (see > its definition), so you can just omit it. > > But OTOH, it's an error to `quote' lambdas like > > '(lambda () body...) > > because it will prevent byte compilation or closure creation and make > Stefan angry. :) > Obviously for `function' quoted symbols there is not much to do, but the > byte compiler can determine whether that function is defined/ will be > defined at run time, so it can warn you about typos as an extra service. > > For example, you get a compiler warning when compiling > > (define-key my-map [key] #'make-frame-cmomand) > > but not for > > (define-key my-map [key] 'make-frame-cmomand) > >> If this is recommended, I would also start quoting my functions as >> #'my-function. > > Yes, it's a good idea. Thanks! This is very informative. -- Narendra Joshi ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-05 19:09 ` Narendra Joshi @ 2017-02-05 19:45 ` Michael Heerdegen 0 siblings, 0 replies; 10+ messages in thread From: Michael Heerdegen @ 2017-02-05 19:45 UTC (permalink / raw) To: Narendra Joshi; +Cc: help-gnu-emacs Narendra Joshi <narendraj9@gmail.com> writes: > > (info "(elisp) Symbol Components") > How did you insert this link to info? Simply M-0 w from *info* (i.e. just w with a zero prefix arg) and you have a call to visit the current info page in the kill ring. Michael. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Quoted function in `define-key' 2017-02-04 10:20 Quoted function in `define-key' Narendra Joshi 2017-02-04 11:11 ` Narendra Joshi 2017-02-04 12:05 ` Michael Heerdegen @ 2017-02-04 18:10 ` Stefan Monnier 2 siblings, 0 replies; 10+ messages in thread From: Stefan Monnier @ 2017-02-04 18:10 UTC (permalink / raw) To: help-gnu-emacs >>>>> "Narendra" == Narendra Joshi <narendraj9@gmail.com> writes: > The following piece of code is confusing me. It is from `rinari-minor-mode'. > (dolist (el (append (mapcar > (lambda (el) > (cons (concat "f" (second el)) > (read (format "'rinari-find-%S" > (first el))))) > rinari-jump-schema) > rinari-minor-mode-keybindings)) > (eval `(define-key rinari-prefix-map ,(car el) ,(cdr el)))) > If I replace the last expression with: > (define-key rinari-prefix-map (car el) (cdr el)) > why does it fail? > (cdr el) is (quote function-name) which is exactly the same as > 'function-name. "Exactly the same"? Well, clearly not, since it behaves differently: (eval (cdr el)) => (quote function-name) (eval 'function-name) => function-name A good first rule is that if you're using `eval` it means you're not really doing it right: (dolist (el (append (mapcar (lambda (el) (cons (vconcat [?\f] (nth 1 el)) (intern "rinari-find-%s" (nth 0 el)))) rinari-jump-schema) rinari-minor-mode-keybindings)) (define-key rinari-prefix-map (car el) (cdr el))) -- Stefan ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2017-02-05 19:45 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-02-04 10:20 Quoted function in `define-key' Narendra Joshi 2017-02-04 11:11 ` Narendra Joshi 2017-02-04 12:05 ` Michael Heerdegen 2017-02-04 15:03 ` Narendra Joshi 2017-02-04 17:25 ` Michael Heerdegen 2017-02-05 10:10 ` Narendra Joshi 2017-02-05 13:50 ` Michael Heerdegen 2017-02-05 19:09 ` Narendra Joshi 2017-02-05 19:45 ` Michael Heerdegen 2017-02-04 18:10 ` Stefan Monnier
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).