From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: lee Newsgroups: gmane.emacs.help Subject: Re: replacing a function with another one Date: Wed, 12 Mar 2014 15:48:46 +0100 Organization: my virtual residence Message-ID: <87vbvjmq0h.fsf@yun.yagibdah.de> References: <87vbvofsi6.fsf@yun.yagibdah.de> <87bnxgs4r9.fsf@web.de> <87lhwj1cfz.fsf@yun.yagibdah.de> <87zjkz6vd5.fsf@web.de> <8738ir161u.fsf@yun.yagibdah.de> <87eh2b6nfm.fsf@web.de> <87r46anab5.fsf@yun.yagibdah.de> <87wqg2u77k.fsf@web.de> <87pplugjh6.fsf@yun.yagibdah.de> <8738ipd2kh.fsf@web.de> <87y50gj1uf.fsf@yun.yagibdah.de> <874n34ticd.fsf@web.de> <87bnxcrloa.fsf@web.de> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1394646193 15192 80.91.229.3 (12 Mar 2014 17:43:13 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 12 Mar 2014 17:43:13 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Wed Mar 12 18:43:22 2014 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1WNnBV-0002MI-6O for geh-help-gnu-emacs@m.gmane.org; Wed, 12 Mar 2014 18:43:17 +0100 Original-Received: from localhost ([::1]:33828 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WNnBU-0005sz-Nr for geh-help-gnu-emacs@m.gmane.org; Wed, 12 Mar 2014 13:43:16 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:41497) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WNnB5-0005oJ-Q0 for help-gnu-emacs@gnu.org; Wed, 12 Mar 2014 13:42:57 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WNnAz-0004ez-LN for help-gnu-emacs@gnu.org; Wed, 12 Mar 2014 13:42:51 -0400 Original-Received: from client-194-42-186-216.muenet.net ([194.42.186.216]:52974 helo=yun.yagibdah.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WNnAz-0004dz-5J for help-gnu-emacs@gnu.org; Wed, 12 Mar 2014 13:42:45 -0400 Original-Received: from lee by yun.yagibdah.de with local (Exim 4.80.1) (envelope-from ) id 1WNnAs-00060B-LQ for help-gnu-emacs@gnu.org; Wed, 12 Mar 2014 18:42:38 +0100 In-Reply-To: <87bnxcrloa.fsf@web.de> (Michael Heerdegen's message of "Wed, 12 Mar 2014 07:11:17 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux) Mail-Followup-To: help-gnu-emacs@gnu.org X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 194.42.186.216 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:96465 Archived-At: Michael Heerdegen writes: > Michael Heerdegen writes: > >> Because it's trivial. > > I have the feeling that this might sound strange - but it's true! So, > here is some pseudo code that shows, in a simplified manner, what > defining an around advice with `advice-add' does: > > (defun my-add-around-advice (fun-to-advice advice) > (lexical-let ((oldfun (symbol-function fun-to-advice)) > (function advice)) > (fset fun-to-advice > (lambda (&rest r) (apply function oldfun r))))) >=20=20=20=20=20=20=20=20=20=20=20 > FUN-TO-ADVICE is the function to advice, ADVICE is the piece of advice > you want to add. Do you recognize the line I cite all the time? It's > what you get as resulting combined function. > > Actually, it's not pseudo code but fully functional. > > An example. Let's define the faculty (a non-recursive version): > > (defun my-fac (n) (reduce '* (number-sequence 1 n))) > > Suppose we want to make it return the faculty of -n for negative > integers n by adding an around advice (currently it returns 1 for negative > arguments). With the above simple implementation, you would do it > like that: > > (my-add-around-advice > 'my-fac > (lambda (orig-fun n) (funcall orig-fun (abs n)))) > > Then, e.g. > > (my-fac -5) > > =3D=3D> 120 That sounds like a cryptic way to do the `callinstead' I just suggested in my previous post :) > Of course, you can't remove the advice with my simplified version, etc. And advice-add is lacking what defadvice has with the ability to enable and to disable the advice. (callinstead orig-fn new-fn (orig-arg0..orig-argN) :named "removable-callin= stead") (callinstead-remove "removable-callinstead") (callinstead-add "removable-callinstead") > With `advice-add' you would do > > (advice-add 'my-fac :around > (lambda (orig-fun n) (funcall orig-fun (abs n)))) > > Let's add another around advice that makes `my-fac' print the result in > the echo area. This time using a named function as advice: > > (defun my-fac--print-result-around-advice (orig-fun n) > "Print result in the echo area." > (let ((result (funcall orig-fun n))) > (message "The faculty of %d is %d" n result) > (sit-for 3) > result)) > > (my-add-around-advice 'my-fac #'my-fac--print-result-around-advice) > > These are not very useful examples, but hopefully they show a bit how it > works, and one can play with them. You also see how to deal with > arguments and the return value of the original function. > > The other advice types can be implemented similarly. I still don=C2=B4t understand how it works. Here=C2=B4s another example: lexical-let is a Lisp macro in `cl.el'. (lexical-let BINDINGS BODY) Like `let', but lexically scoped. The main visible difference is that lambdas inside BODY will create lexical closures as in Common Lisp. So what is that supposed to mean? `let' keeps driving me insane already because it requires so many brackets. Then finally, I do something like (let ((end-marker (concat "^" comment-start lsl-hi-lock-patterns-end-ma= rker)) ((marker-pos (re-search-forward end-marker (point-max) t)))) (do-stuff)) and it doesn=C2=B4t work because end-marker is undefined despite I just defined it :( So I have (let ((end-marker (concat "^" comment-start lsl-hi-lock-patterns-end-ma= rker))) (let ((marker-pos (re-search-forward end-marker (point-max) t))) (do-something))) instead ... And in the end, I=C2=B4m left with the unanswerable question of how to intentionally returning something in particular from a function: (defun lsl-get-patterns-from-file (file) "Read hi-lock-mode highlighting-patterns from a file and return the patterns read." (with-current-buffer (find-file-noselect file) (goto-char (point-min)) (let ((end-marker (concat "^" comment-start lsl-hi-lock-patterns-end-ma= rker))) (let ((marker-pos (re-search-forward end-marker (point-max) t))) (when marker-pos (goto-char marker-pos) (previous-line) (end-of-line) (setq marker-pos (point)) (goto-char (point-min)) (message "reading hi-lock patterns from %s (%d..%d)" (buffer-name) (point-min) marker-pos) (let ((patterns nil)) (while (< (point) marker-pos) (setq patterns (append (read (current-buffer)) patterns))) (setq patterns patterns))))))) I need this function to return `patterns'. Without the last line, it seems to return nil because the setq is enclosed in the while. This is what I made from the example implementation you made. That really got me somewhere, and I don=C2=B4t need to use advices anymore. Then I found I want to be able to edit the patterns. Editing them is easier when there is one pattern per line, so I made it write one per line and then found that they are suddenly much more difficult to read. Finally I got it to read them, just to find out that the function doesn=C2=B4t return them. --=20 Knowledge is volatile and fluid. Software is power.