* Proposal: make prog2 a macro @ 2016-10-07 4:16 Wilfred Hughes 2016-10-07 5:04 ` Tino Calancha ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Wilfred Hughes @ 2016-10-07 4:16 UTC (permalink / raw) To: emacs-devel I was looking at a list of Emacs' special forms, and noticed that prog2 is implemented in C. Is there any interest in moving this to a simple macro? I think this makes the implementation easier to understand for users who are less familiar with the C parts of Emacs. I've brought up an Emacs instance with the patch, and 'make check' passes. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From 569a8b3b9c3aee677fef9a574d99727a68f86fa5 Mon Sep 17 00:00:00 2001 From: Wilfred Hughes <me@wilfred.me.uk> Date: Thu, 6 Oct 2016 23:58:36 -0400 Subject: [PATCH] Make prog2 a macro rather than a special form * src/eval.c (Sprog2): Remove. * lisp/subr.el (prog2): Define a prog2 macro. * doc/lispref/control.texi (Sequencing): prog2 is now a macro. * doc/lispref/functions.texi (Function Safety): prog2 is no longer a special form. --- doc/lispref/control.texi | 2 +- doc/lispref/functions.texi | 2 +- lisp/subr.el | 11 +++++++++++ src/eval.c | 12 ------------ 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 0cdb035..bdcbd19 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -125,7 +125,7 @@ Sequencing @end defspec @defspec prog2 form1 form2 forms@dots{} -This special form evaluates @var{form1}, @var{form2}, and all of the +This macro evaluates @var{form1}, @var{form2}, and all of the following @var{forms}, in textual order, returning the result of @var{form2}. diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index fff4ac0..37f3a18 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -2294,7 +2294,7 @@ Function Safety safe expressions. @item One of the special forms @code{and}, @code{catch}, @code{cond}, -@code{if}, @code{or}, @code{prog1}, @code{prog2}, @code{progn}, +@code{if}, @code{or}, @code{prog1}, @code{progn}, @code{while}, and @code{unwind-protect}], if all its arguments are safe. @item diff --git a/lisp/subr.el b/lisp/subr.el index b143812..f1aecf3 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -174,6 +174,17 @@ pop (macroexp-let2 macroexp-copyable-p x getter `(prog1 ,x ,(funcall setter `(cdr ,x)))))))) +(defmacro prog2 (form1 form2 &rest body) + "Eval FORM1, FORM2 and BODY sequentially; return value from FORM2. +The value of FORM2 is saved during the evaluation of the +remaining args, whose values are discarded. + +\(fn FORM1 FORM2 BODY...)" + (declare (indent 2) (debug t)) + `(prog1 + (progn ,form1 ,form2) + ,@body)) + (defmacro when (cond &rest body) "If COND yields non-nil, do BODY, else return nil. When COND yields non-nil, eval BODY forms sequentially and return diff --git a/src/eval.c b/src/eval.c index 2fedbf3..c823530 100644 --- a/src/eval.c +++ b/src/eval.c @@ -465,17 +465,6 @@ usage: (prog1 FIRST BODY...) */) return val; } -DEFUN ("prog2", Fprog2, Sprog2, 2, UNEVALLED, 0, - doc: /* Eval FORM1, FORM2 and BODY sequentially; return value from FORM2. -The value of FORM2 is saved during the evaluation of the -remaining args, whose values are discarded. -usage: (prog2 FORM1 FORM2 BODY...) */) - (Lisp_Object args) -{ - eval_sub (XCAR (args)); - return Fprog1 (XCDR (args)); -} - DEFUN ("setq", Fsetq, Ssetq, 0, UNEVALLED, 0, doc: /* Set each SYM to the value of its VAL. The symbols SYM are variables; they are literal (not evaluated). @@ -3917,7 +3906,6 @@ alist of active lexical bindings. */); defsubr (&Scond); defsubr (&Sprogn); defsubr (&Sprog1); - defsubr (&Sprog2); defsubr (&Ssetq); defsubr (&Squote); defsubr (&Sfunction); -- 2.10.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: Proposal: make prog2 a macro 2016-10-07 4:16 Proposal: make prog2 a macro Wilfred Hughes @ 2016-10-07 5:04 ` Tino Calancha 2016-10-07 7:46 ` John Wiegley 2016-10-07 8:08 ` Tino Calancha 2 siblings, 0 replies; 9+ messages in thread From: Tino Calancha @ 2016-10-07 5:04 UTC (permalink / raw) To: Wilfred Hughes; +Cc: emacs-devel On Fri, 7 Oct 2016, Wilfred Hughes wrote: > I was looking at a list of Emacs' special forms, and noticed that > prog2 is implemented in C. Is there any interest in moving this to a > simple macro? I don't have opinion about if this is worth or not, but i think is safer to avoid the use of backquote: prog2 could be used in an early stage of the bootstrap. Instead of: > + `(prog1 > + (progn ,form1 ,form2) > + ,@body)) Better use: (cons 'prog1 (cons (list 'progn form1 form2) body))) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Proposal: make prog2 a macro 2016-10-07 4:16 Proposal: make prog2 a macro Wilfred Hughes 2016-10-07 5:04 ` Tino Calancha @ 2016-10-07 7:46 ` John Wiegley 2016-10-07 20:34 ` Richard Stallman 2016-10-07 8:08 ` Tino Calancha 2 siblings, 1 reply; 9+ messages in thread From: John Wiegley @ 2016-10-07 7:46 UTC (permalink / raw) To: Wilfred Hughes; +Cc: emacs-devel >>>>> "WH" == Wilfred Hughes <me@wilfred.me.uk> writes: WH> I was looking at a list of Emacs' special forms, and noticed that prog2 is WH> implemented in C. Is there any interest in moving this to a simple macro? It seems it has always been in C, since the beginning of version history for that file. I can't think of a reason it shouldn't be changed to a Lisp macro. My desire is to move as much functionality into Emacs Lisp as is feasible. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Proposal: make prog2 a macro 2016-10-07 7:46 ` John Wiegley @ 2016-10-07 20:34 ` Richard Stallman 0 siblings, 0 replies; 9+ messages in thread From: Richard Stallman @ 2016-10-07 20:34 UTC (permalink / raw) To: John Wiegley; +Cc: me, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] I initially defined prog2 and NOT prog1, because prog2 subsumes prog1 nicely as in (prog2 nil ...). Back then, I was trying in every way to keep Emacs small. This change will cause increased inconvenience in the Lisp debugger for interpreted code. That is the only effect that the change will have on users, and it is negative. I suggest not changing it. It works fine. It compiles into good code. Changing it could break something. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Proposal: make prog2 a macro 2016-10-07 4:16 Proposal: make prog2 a macro Wilfred Hughes 2016-10-07 5:04 ` Tino Calancha 2016-10-07 7:46 ` John Wiegley @ 2016-10-07 8:08 ` Tino Calancha 2016-10-08 2:12 ` Wilfred Hughes 2 siblings, 1 reply; 9+ messages in thread From: Tino Calancha @ 2016-10-07 8:08 UTC (permalink / raw) To: Wilfred Hughes; +Cc: emacs-devel On Fri, 7 Oct 2016, Wilfred Hughes wrote: > I think this makes the implementation easier to understand for users > I've brought up an Emacs instance with the patch, > and 'make check' passes. You might want to update other files doing the special form treatment, for instance, without trying to be exhaustive, bytecomp.el, byte-opt.el, cl-macs.el. Maybe you could also replace any mention of prog2 as a special form, again without being exhaustive, for instance, unsafep.el. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Proposal: make prog2 a macro 2016-10-07 8:08 ` Tino Calancha @ 2016-10-08 2:12 ` Wilfred Hughes 2016-10-08 2:35 ` Noam Postavsky 2016-10-08 3:40 ` Tino Calancha 0 siblings, 2 replies; 9+ messages in thread From: Wilfred Hughes @ 2016-10-08 2:12 UTC (permalink / raw) To: Tino Calancha; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 680 bytes --] On 7 October 2016 at 04:08, Tino Calancha <tino.calancha@gmail.com> wrote: > > Maybe you could also replace any mention of prog2 as a special form, > again without being exhaustive, for instance, > unsafep.el. OK, here's an updated patch. I've removed the usage of backquote as suggested, and updated unsafep.el, bytecomp.el and cl-macs.el. I've grepped through Emacs for other references to prog2, I think I've covered everything. > This change will cause increased inconvenience in the Lisp debugger > for interpreted code. I don't see how: I've added a debug declaration so you can step through with edebug as normal. It's no different from `when' in this respect. Wilfred [-- Attachment #2: 0001-Make-prog2-a-macro-rather-than-a-special-form.patch --] [-- Type: text/x-patch, Size: 7183 bytes --] From 5e9d390c3a5c4ac2b3ddabeab77bd6e2e9319c7b Mon Sep 17 00:00:00 2001 From: Wilfred Hughes <me@wilfred.me.uk> Date: Thu, 6 Oct 2016 23:58:36 -0400 Subject: [PATCH] Make prog2 a macro rather than a special form * src/eval.c (Sprog2): Remove. * lisp/subr.el (prog2): Define a prog2 macro. * lisp/emacs-lisp/generator.el (cps--transform-1): prog2 no longer exists after macro expansion, so we don't need to transform it * lisp/emacs-lisp/bytecomp.el: Remove special treatment of prog2 in byte-compilation, as it's macro-expanded away. * lisp/emacs-lisp/unsafep.el: Update comments to reflect that prog2 is now a macro. * lisp/emacs-lisp/cl-macs.el (cl--simple-funcs): prog2 is no longer special form and does not need special treatment * doc/lispref/control.texi (Sequencing): prog2 is now a macro. * doc/lispref/functions.texi (Function Safety): prog2 is no longer a special form. --- doc/lispref/control.texi | 2 +- doc/lispref/functions.texi | 2 +- lisp/emacs-lisp/bytecomp.el | 1 - lisp/emacs-lisp/cl-macs.el | 2 +- lisp/emacs-lisp/generator.el | 7 ------- lisp/emacs-lisp/unsafep.el | 9 +++++---- lisp/subr.el | 11 +++++++++++ src/eval.c | 12 ------------ 8 files changed, 19 insertions(+), 27 deletions(-) diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 0cdb035..bdcbd19 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -125,7 +125,7 @@ Sequencing @end defspec @defspec prog2 form1 form2 forms@dots{} -This special form evaluates @var{form1}, @var{form2}, and all of the +This macro evaluates @var{form1}, @var{form2}, and all of the following @var{forms}, in textual order, returning the result of @var{form2}. diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index fff4ac0..37f3a18 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -2294,7 +2294,7 @@ Function Safety safe expressions. @item One of the special forms @code{and}, @code{catch}, @code{cond}, -@code{if}, @code{or}, @code{prog1}, @code{prog2}, @code{progn}, +@code{if}, @code{or}, @code{prog1}, @code{progn}, @code{while}, and @code{unwind-protect}], if all its arguments are safe. @item diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index c34ec5c..8d90aa7 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2406,7 +2406,6 @@ byte-compile-file-form-require (put 'progn 'byte-hunk-handler 'byte-compile-file-form-progn) (put 'prog1 'byte-hunk-handler 'byte-compile-file-form-progn) -(put 'prog2 'byte-hunk-handler 'byte-compile-file-form-progn) (defun byte-compile-file-form-progn (form) (mapc 'byte-compile-file-form (cdr form)) ;; Return nil so the forms are not output twice. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index f5b7b82..33a9f65 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -82,7 +82,7 @@ 'cl--compiler-macro-cXXr ;; macro expanders to optimize the results in certain common cases. (defconst cl--simple-funcs '(car cdr nth aref elt if and or + - 1+ 1- min max - car-safe cdr-safe progn prog1 prog2)) + car-safe cdr-safe progn prog1)) (defconst cl--safe-funcs '(* / % length memq list vector vectorp < > <= >= = error)) diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el index 49af240..f326b8e 100644 --- a/lisp/emacs-lisp/generator.el +++ b/lisp/emacs-lisp/generator.el @@ -379,13 +379,6 @@ cps--transform-1 `(setf ,cps--value-symbol ,temp-var-symbol ,cps--state-symbol ,next-state)))))))) - ;; Process `prog2'. - - (`(prog2 ,form1 ,form2 . ,body) - (cps--transform-1 - `(progn ,form1 (prog1 ,form2 ,@body)) - next-state)) - ;; Process `unwind-protect': If we're inside an unwind-protect, we ;; have a block of code UNWINDFORMS which we would like to run ;; whenever control flows away from the main piece of code, diff --git a/lisp/emacs-lisp/unsafep.el b/lisp/emacs-lisp/unsafep.el index 584684f..bfdd58d 100644 --- a/lisp/emacs-lisp/unsafep.el +++ b/lisp/emacs-lisp/unsafep.el @@ -33,8 +33,9 @@ ;; 1. It's an atom. ;; 2. It's a function call to a safe function and all arguments are safe ;; formulas. -;; 3. It's a special form whose arguments are like a function's (and, -;; catch, if, or, prog1, prog2, progn, while, unwind-protect). +;; 3. It's a special form or macro whose arguments are like a +;; function's (and, catch, if, or, prog1, prog2, progn, while, +;; unwind-protect). ;; 4. It's a special form or macro that creates safe temporary bindings ;; (condition-case, dolist, dotimes, lambda, let, let*). ;; 4. It's one of (cond, quote) that have special parsing. @@ -99,13 +100,13 @@ unsafep-vars ;;Other safe functions (dolist (x '(;;Special forms - and catch if or prog1 prog2 progn while unwind-protect + and catch if or prog1 progn while unwind-protect ;;Safe subrs that have some side-effects ding error random signal sleep-for string-match throw ;;Defsubst functions from subr.el caar cadr cdar cddr ;;Macros from subr.el - save-match-data unless when + prog2 save-match-data unless when ;;Functions from subr.el that have side effects split-string replace-regexp-in-string play-sound-file)) (put x 'safe-function t)) diff --git a/lisp/subr.el b/lisp/subr.el index b143812..47e2050 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -174,6 +174,17 @@ pop (macroexp-let2 macroexp-copyable-p x getter `(prog1 ,x ,(funcall setter `(cdr ,x)))))))) +(defmacro prog2 (form1 form2 &rest body) + "Eval FORM1, FORM2 and BODY sequentially; return value from FORM2. +The value of FORM2 is saved during the evaluation of the +remaining args, whose values are discarded. + +\(fn FORM1 FORM2 BODY...)" + (declare (indent 2) (debug t)) + (cons 'prog1 + (cons (list 'progn form1 form2) + body))) + (defmacro when (cond &rest body) "If COND yields non-nil, do BODY, else return nil. When COND yields non-nil, eval BODY forms sequentially and return diff --git a/src/eval.c b/src/eval.c index 2fedbf3..c823530 100644 --- a/src/eval.c +++ b/src/eval.c @@ -465,17 +465,6 @@ usage: (prog1 FIRST BODY...) */) return val; } -DEFUN ("prog2", Fprog2, Sprog2, 2, UNEVALLED, 0, - doc: /* Eval FORM1, FORM2 and BODY sequentially; return value from FORM2. -The value of FORM2 is saved during the evaluation of the -remaining args, whose values are discarded. -usage: (prog2 FORM1 FORM2 BODY...) */) - (Lisp_Object args) -{ - eval_sub (XCAR (args)); - return Fprog1 (XCDR (args)); -} - DEFUN ("setq", Fsetq, Ssetq, 0, UNEVALLED, 0, doc: /* Set each SYM to the value of its VAL. The symbols SYM are variables; they are literal (not evaluated). @@ -3917,7 +3906,6 @@ alist of active lexical bindings. */); defsubr (&Scond); defsubr (&Sprogn); defsubr (&Sprog1); - defsubr (&Sprog2); defsubr (&Ssetq); defsubr (&Squote); defsubr (&Sfunction); -- 2.10.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: Proposal: make prog2 a macro 2016-10-08 2:12 ` Wilfred Hughes @ 2016-10-08 2:35 ` Noam Postavsky 2016-10-08 6:11 ` Eli Zaretskii 2016-10-08 3:40 ` Tino Calancha 1 sibling, 1 reply; 9+ messages in thread From: Noam Postavsky @ 2016-10-08 2:35 UTC (permalink / raw) To: Wilfred Hughes; +Cc: emacs-devel, Tino Calancha On Fri, Oct 7, 2016 at 10:12 PM, Wilfred Hughes <me@wilfred.me.uk> wrote: > >> This change will cause increased inconvenience in the Lisp debugger >> for interpreted code. > > I don't see how: I've added a debug declaration so you can step > through with edebug as normal. It's no different from `when' in this > respect. The "Lisp debugger" may be referring to `debug', not `edebug'. See bug #3466 - "have `d' in debugger treat macro expansion like `c' does". That said, I think prog2 is rare enough (a quick M-x rgrep over Emacs' lisp code found only 66 matches vs 874 for prog1 and 8585 for progn) that it wouldn't really matter that much. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Proposal: make prog2 a macro 2016-10-08 2:35 ` Noam Postavsky @ 2016-10-08 6:11 ` Eli Zaretskii 0 siblings, 0 replies; 9+ messages in thread From: Eli Zaretskii @ 2016-10-08 6:11 UTC (permalink / raw) To: Noam Postavsky; +Cc: me, tino.calancha, emacs-devel > From: Noam Postavsky <npostavs@users.sourceforge.net> > Date: Fri, 7 Oct 2016 22:35:04 -0400 > Cc: emacs-devel <emacs-devel@gnu.org>, Tino Calancha <tino.calancha@gmail.com> > > The "Lisp debugger" may be referring to `debug', not `edebug'. See bug > #3466 - "have `d' in debugger treat macro expansion like `c' does". > That said, I think prog2 is rare enough (a quick M-x rgrep over Emacs' > lisp code found only 66 matches vs 874 for prog1 and 8585 for progn) > that it wouldn't really matter that much. Sorry, but I don't find that small number to be negligible. Debugging Emacs Lisp code in core is already too hard; e.g., too frequently I need to resort to "printf debugging". I object to any further difficulties in this area, so if we want to make this a macro, that bug needs to be fixed first. In any case, this issue is no more than a nice-to-have, whereas debugging difficulties are much more important to solve, for a project which long ago entered the maintenance phase of its life cycle. Thanks. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Proposal: make prog2 a macro 2016-10-08 2:12 ` Wilfred Hughes 2016-10-08 2:35 ` Noam Postavsky @ 2016-10-08 3:40 ` Tino Calancha 1 sibling, 0 replies; 9+ messages in thread From: Tino Calancha @ 2016-10-08 3:40 UTC (permalink / raw) To: Wilfred Hughes; +Cc: emacs-devel, Tino Calancha On Fri, 7 Oct 2016, Wilfred Hughes wrote: > On 7 October 2016 at 04:08, Tino Calancha <tino.calancha@gmail.com> wrote: >> >> Maybe you could also replace any mention of prog2 as a special form, >> again without being exhaustive, for instance, >> unsafep.el. > > OK, here's an updated patch. I've removed the usage of backquote as > suggested, and updated unsafep.el, bytecomp.el and cl-macs.el. I've > grepped through Emacs for other references to prog2, I think I've > covered everything. Thank you very much. I have one question regarding following file: * lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Do we still need to byte optimize the `prog2' forms arguments after you changed it to a macro? ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-10-08 6:11 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-10-07 4:16 Proposal: make prog2 a macro Wilfred Hughes 2016-10-07 5:04 ` Tino Calancha 2016-10-07 7:46 ` John Wiegley 2016-10-07 20:34 ` Richard Stallman 2016-10-07 8:08 ` Tino Calancha 2016-10-08 2:12 ` Wilfred Hughes 2016-10-08 2:35 ` Noam Postavsky 2016-10-08 6:11 ` Eli Zaretskii 2016-10-08 3:40 ` Tino Calancha
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.