* humble proposal: New special form progn-1
@ 2016-07-27 12:16 Tino Calancha
2016-07-27 12:22 ` Stefan Monnier
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Tino Calancha @ 2016-07-27 12:16 UTC (permalink / raw)
To: emacs-devel
Dear all,
i got this idea few days ago (see the patch at the end).
Even though I envision that no one here will like this proposal,
for me it's instructive to learn from your answers why this is
not a good idea.
So, why is this a bad idea?
Thanks in advance for your answer,
Tino
My (weak) motivation for introduce this is:
* Compact (and familiar) syntaxis.
* Same reasons to exists as prog2 has (excluding historical reasons).
* Other way to acomplish one usual task.
* Allow lower indentation level (see below):
(progn-1
(form1)
(form2)
(form3)
.
.
.
(formN-1)
(formN))
(prog1
(progn
(form1)
(form2)
(form3)
.
.
.
(formN-1))
(formN))
(prog2
(progn
(form1)
(form2)
(form3)
.
.
.
(formN-2))
(prog1
(formN-1)
(formN)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
From c9b38c42b253ca004c3aef4dd9dde274aa717d91 Mon Sep 17 00:00:00 2001
From: Tino Calancha <tino.calancha@gmail.com>
Date: Wed, 27 Jul 2016 20:40:25 +0900
Subject: [PATCH] New special form progn-1
* src/eval.c (progn-1): Eval sequentially N forms and
return the value of the form N-1.
---
src/eval.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/eval.c b/src/eval.c
index 33b82f7..5eb0cfd 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -431,6 +431,23 @@ usage: (progn BODY...) */)
return val;
}
+DEFUN ("progn-1", Fprogn_1, Sprogn_1, 2, UNEVALLED, 0,
+ doc: /* Eval N forms sequentially; return value from form N-1.
+usage: (progn-1 FORM_1 FORM_2...FORM_N-1 FORM_N) */)
+ (Lisp_Object body)
+{
+ Lisp_Object val = Qnil;
+
+ while (CONSP (XCDR (body)))
+ {
+ val = eval_sub (XCAR (body));
+ body = XCDR (body);
+ }
+ eval_sub (XCAR (body));
+
+ return val;
+}
+
/* Evaluate BODY sequentially, discarding its value. Suitable for
record_unwind_protect. */
@@ -3906,6 +3923,7 @@ alist of active lexical bindings. */);
defsubr (&Sif);
defsubr (&Scond);
defsubr (&Sprogn);
+ defsubr (&Sprogn_1);
defsubr (&Sprog1);
defsubr (&Sprog2);
defsubr (&Ssetq);
--
2.8.1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
In GNU Emacs 25.1.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.20.6)
of 2016-07-27 built
Repository revision: e0d425976e3a83585db9a586687897fe1ac6455f
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 12:16 humble proposal: New special form progn-1 Tino Calancha
@ 2016-07-27 12:22 ` Stefan Monnier
2016-07-27 12:53 ` Andreas Schwab
2016-07-27 14:08 ` Clément Pit--Claudel
2 siblings, 0 replies; 12+ messages in thread
From: Stefan Monnier @ 2016-07-27 12:22 UTC (permalink / raw)
To: emacs-devel
> (progn-1
> (form1)
> .
> .
> (formN-1)
> (formN))
Shouldn't that be
> (progn-1
> (form1)
> .
> .
> (formN-1)
> (formN))
to follow the usual convention of prog1, prog2, ... ?
If so, we also need a patch for the indentation code.
> +DEFUN ("progn-1", Fprogn_1, Sprogn_1, 2, UNEVALLED, 0,
All special forms need support in the compiler as well.
Stefan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 12:16 humble proposal: New special form progn-1 Tino Calancha
2016-07-27 12:22 ` Stefan Monnier
@ 2016-07-27 12:53 ` Andreas Schwab
2016-07-27 13:58 ` Tino Calancha
2016-07-27 14:08 ` Clément Pit--Claudel
2 siblings, 1 reply; 12+ messages in thread
From: Andreas Schwab @ 2016-07-27 12:53 UTC (permalink / raw)
To: Tino Calancha; +Cc: emacs-devel
On Mi, Jul 27 2016, Tino Calancha <tino.calancha@gmail.com> wrote:
> * Other way to acomplish one usual task.
How usual is that task?
> * Allow lower indentation level (see below):
>
> (progn-1
> (form1)
> (form2)
> (form3)
> .
> .
> .
> (formN-1)
> (formN))
(progn
(form1)
...
(prog1
(formN-1)
(formN)))
Andreas.
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 12:53 ` Andreas Schwab
@ 2016-07-27 13:58 ` Tino Calancha
2016-07-27 16:04 ` Andreas Schwab
0 siblings, 1 reply; 12+ messages in thread
From: Tino Calancha @ 2016-07-27 13:58 UTC (permalink / raw)
To: Andreas Schwab; +Cc: emacs-devel, Tino Calancha
On Wed, 27 Jul 2016, Andreas Schwab wrote:
> On Mi, Jul 27 2016, Tino Calancha <tino.calancha@gmail.com> wrote:
>
>> * Other way to acomplish one usual task.
>
> How usual is that task?
I will estimate it:
Running following command on lisp dir:
find lisp -type f -exec grep --color -InH -e regexp \{\} +
1) regexp = '(prog1 '
matches: 462
2) regexp = '(prog2 '
matches: 20
3) regexp = '(progn '
matches: 2262
I would say similar order of magnitude as 1), i.e., ~ 20% of 3)
>> * Allow lower indentation level (see below):
>>
>> (progn-1
>> (form1)
>> (form2)
>> (form3)
>> .
>> .
>> .
>> (formN-1)
>> (formN))
>
> (progn
> (form1)
> ...
> (prog1
> (formN-1)
> (formN)))
>
Its also nice; maybe slightly more readable the first one.
You know, it's matter of taste: 2 forms VS 1 form, like:
(let ((i 1)
(j 2))
(form))
compared with:
(let ((i 1))
(let ((j 2))
(form)))
Tino
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 12:16 humble proposal: New special form progn-1 Tino Calancha
2016-07-27 12:22 ` Stefan Monnier
2016-07-27 12:53 ` Andreas Schwab
@ 2016-07-27 14:08 ` Clément Pit--Claudel
2016-07-27 14:30 ` Phil Sainty
2016-07-27 14:38 ` Tino Calancha
2 siblings, 2 replies; 12+ messages in thread
From: Clément Pit--Claudel @ 2016-07-27 14:08 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 2590 bytes --]
On 2016-07-27 08:16, Tino Calancha wrote:
> Dear all,
>
> i got this idea few days ago (see the patch at the end).
>
> Even though I envision that no one here will like this proposal,
> for me it's instructive to learn from your answers why this is
> not a good idea.
:) I don't have anything strongly against it myself. Any reason to not make it a lisp macro though?
> My (weak) motivation for introduce this is:
>
> * Compact (and familiar) syntaxis.
> * Same reasons to exists as prog2 has (excluding historical reasons).
> * Other way to acomplish one usual task.
> * Allow lower indentation level (see below):
Sounds good. One worry that I have with the name is that I read it as (progn)-(1), not prog(n-1).
But in any case, maybe it would be best to make it a lisp macro first?
> ...
> (prog2
> (progn
> (form1)
> (form2)
> (form3)
> .
> .
> .
> (formN-2))
> (prog1
> (formN-1)
> (formN)))
Wouldn't
(progn
(form1)
...
(formN-2)
(prog1
(formN-1)
(formN)))
work?
Cheers,
Clément.
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> From c9b38c42b253ca004c3aef4dd9dde274aa717d91 Mon Sep 17 00:00:00 2001
> From: Tino Calancha <tino.calancha@gmail.com>
> Date: Wed, 27 Jul 2016 20:40:25 +0900
> Subject: [PATCH] New special form progn-1
>
> * src/eval.c (progn-1): Eval sequentially N forms and
> return the value of the form N-1.
> ---
> src/eval.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/src/eval.c b/src/eval.c
> index 33b82f7..5eb0cfd 100644
> --- a/src/eval.c
> +++ b/src/eval.c
> @@ -431,6 +431,23 @@ usage: (progn BODY...) */)
> return val;
> }
>
> +DEFUN ("progn-1", Fprogn_1, Sprogn_1, 2, UNEVALLED, 0,
> + doc: /* Eval N forms sequentially; return value from form N-1.
> +usage: (progn-1 FORM_1 FORM_2...FORM_N-1 FORM_N) */)
> + (Lisp_Object body)
> +{
> + Lisp_Object val = Qnil;
> +
> + while (CONSP (XCDR (body)))
> + {
> + val = eval_sub (XCAR (body));
> + body = XCDR (body);
> + }
> + eval_sub (XCAR (body));
> +
> + return val;
> +}
> +
> /* Evaluate BODY sequentially, discarding its value. Suitable for
> record_unwind_protect. */
>
> @@ -3906,6 +3923,7 @@ alist of active lexical bindings. */);
> defsubr (&Sif);
> defsubr (&Scond);
> defsubr (&Sprogn);
> + defsubr (&Sprogn_1);
> defsubr (&Sprog1);
> defsubr (&Sprog2);
> defsubr (&Ssetq);
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 14:08 ` Clément Pit--Claudel
@ 2016-07-27 14:30 ` Phil Sainty
2016-07-27 15:15 ` Drew Adams
2016-07-27 14:38 ` Tino Calancha
1 sibling, 1 reply; 12+ messages in thread
From: Phil Sainty @ 2016-07-27 14:30 UTC (permalink / raw)
To: emacs-devel
Or the idea could be generalised to:
(progn- offset &rest body)
(prog0+ offset &rest body)
I think code readability potentially suffers with any of
these ideas, mind.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 14:08 ` Clément Pit--Claudel
2016-07-27 14:30 ` Phil Sainty
@ 2016-07-27 14:38 ` Tino Calancha
2016-07-27 19:07 ` Clément Pit--Claudel
1 sibling, 1 reply; 12+ messages in thread
From: Tino Calancha @ 2016-07-27 14:38 UTC (permalink / raw)
To: Clément Pit--Claudel; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1133 bytes --]
On Wed, 27 Jul 2016, Clément Pit--Claudel wrote:
> On 2016-07-27 08:16, Tino Calancha wrote:
>> Dear all,
>>
>> i got this idea few days ago (see the patch at the end).
>>
>> Even though I envision that no one here will like this proposal,
>> for me it's instructive to learn from your answers why this is
>> not a good idea.
>
> :) I don't have anything strongly against it myself. Any reason to not make it a lisp macro though?
>
>> My (weak) motivation for introduce this is:
>>
>> * Compact (and familiar) syntaxis.
>> * Same reasons to exists as prog2 has (excluding historical reasons).
>> * Other way to acomplish one usual task.
>> * Allow lower indentation level (see below):
>
> Sounds good. One worry that I have with the name is that I read it as (progn)-(1), not prog(n-1).
You mean that could confuse some people that is like:
(1- (progn (form)))
I still like progn-1 more because naturally fit in the sequence:
prog1, prog2, ..., progn
> Wouldn't
> (progn
> (form1)
> ...
> (formN-2)
> (prog1
> (formN-1)
> (formN)))
> work?
Of course does. I didn't claim i exhausted the casuistic :-)
Thank you!
Tino
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: humble proposal: New special form progn-1
2016-07-27 14:30 ` Phil Sainty
@ 2016-07-27 15:15 ` Drew Adams
2016-07-28 11:35 ` Tino Calancha
0 siblings, 1 reply; 12+ messages in thread
From: Drew Adams @ 2016-07-27 15:15 UTC (permalink / raw)
To: Phil Sainty, emacs-devel
FWIW -
I would have no use for that, and I would find code that uses it
harder to read than what I would normally write.
In fact, I rarely use `prog1', `prog2', or `progn' - less than 0.1%
of code lines for `prog1', .02% for `prog2', and 0.5% for `progn'.
And all of the `prog2' lines, and some of the others, are only for
code that mirrors some code distributed by Emacs (e.g., so that
subsequent updates/diffs are easier). IOW, it's really someone
else's ugly code. ;-)
I use `prog1' for the swapping idiom (which might be clearer as a
`swap-values' macro, but which is ingrained in me and easy to see):
(setq start (prog1 end (setq end start)))
and sometimes for a return-value computation that is followed by
some side effect such as showing a message.
But for most cases where someone else might use `prog1' I'm already
let-binding a variable that I use for the value that might otherwise
be returned by the `prog1' (or by a `prog2').
(let (... result) ... (setq result ...) ... result)
And I rarely use `progn' with `if', preferring `when', `unless',
`and', `or', or `cond' for most such use cases.
Just one opinion.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 13:58 ` Tino Calancha
@ 2016-07-27 16:04 ` Andreas Schwab
0 siblings, 0 replies; 12+ messages in thread
From: Andreas Schwab @ 2016-07-27 16:04 UTC (permalink / raw)
To: Tino Calancha; +Cc: emacs-devel
On Mi, Jul 27 2016, Tino Calancha <tino.calancha@gmail.com> wrote:
> On Wed, 27 Jul 2016, Andreas Schwab wrote:
>
>> On Mi, Jul 27 2016, Tino Calancha <tino.calancha@gmail.com> wrote:
>>
>>> * Other way to acomplish one usual task.
>>
>> How usual is that task?
> I will estimate it:
> Running following command on lisp dir:
I was asking about progn-1. I don't see much use case for it.
Andreas.
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 14:38 ` Tino Calancha
@ 2016-07-27 19:07 ` Clément Pit--Claudel
2016-07-27 21:51 ` Nicolas Petton
0 siblings, 1 reply; 12+ messages in thread
From: Clément Pit--Claudel @ 2016-07-27 19:07 UTC (permalink / raw)
To: Tino Calancha; +Cc: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 588 bytes --]
On 2016-07-27 10:38, Tino Calancha wrote:
> You mean that could confuse some people that is like:
> (1- (progn (form)))
> I still like progn-1 more because naturally fit in the sequence:
> prog1, prog2, ..., progn
No, that's not what I meant. I meant that in Lisp when I want to write (n - 1) I actually write (- n 1); thus, when I see progn-1, I don't read it as "prog (n minus 1)", but instead as "progn dash 1". Given the convention that foo-1 usually means "internal function used in the implementation of foo", I read it as "internal function used to implement progn".
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: humble proposal: New special form progn-1
2016-07-27 19:07 ` Clément Pit--Claudel
@ 2016-07-27 21:51 ` Nicolas Petton
0 siblings, 0 replies; 12+ messages in thread
From: Nicolas Petton @ 2016-07-27 21:51 UTC (permalink / raw)
To: Clément Pit--Claudel, Tino Calancha; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 279 bytes --]
Clément Pit--Claudel <clement.pit@gmail.com> writes:
Hi Clément,
> Given the convention that foo-1 usually means "internal function used
> in the implementation of foo", I read it as "internal function used to
> implement progn".
I agree with you.
Cheers,
Nico
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: humble proposal: New special form progn-1
2016-07-27 15:15 ` Drew Adams
@ 2016-07-28 11:35 ` Tino Calancha
0 siblings, 0 replies; 12+ messages in thread
From: Tino Calancha @ 2016-07-28 11:35 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1107 bytes --]
On Wed, 27 Jul 2016, Drew Adams wrote:
> and sometimes for a return-value computation that is followed by
> some side effect such as showing a message.
>
> But for most cases where someone else might use `prog1' I'm already
> let-binding a variable that I use for the value that might otherwise
> be returned by the `prog1' (or by a `prog2').
>
> (let (... result) ... (setq result ...) ... result)
Yeah, i also like binding one 'result' variable: this way
all defun's in the code sistematically return
the last evaluated form. Its easier to read.
On Wed, 27 Jul 2016, Clément Pit--Claudel wrote:
>No, that's not what I meant. I meant that in Lisp when I want to write
>(n - 1) I actually write (- n 1); thus, when I see progn-1,
>I don't read it as "prog (n minus 1)", but instead as "progn dash 1".
>Given the convention that foo-1 usually means
>"internal function used in the implementation of foo",
>I read it as "internal function used to implement progn".
This is another point against my proposal: the notation could be
misleading.
So, i give up with my proposal.
Thank you very much.
Tino
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-07-28 11:35 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-27 12:16 humble proposal: New special form progn-1 Tino Calancha
2016-07-27 12:22 ` Stefan Monnier
2016-07-27 12:53 ` Andreas Schwab
2016-07-27 13:58 ` Tino Calancha
2016-07-27 16:04 ` Andreas Schwab
2016-07-27 14:08 ` Clément Pit--Claudel
2016-07-27 14:30 ` Phil Sainty
2016-07-27 15:15 ` Drew Adams
2016-07-28 11:35 ` Tino Calancha
2016-07-27 14:38 ` Tino Calancha
2016-07-27 19:07 ` Clément Pit--Claudel
2016-07-27 21:51 ` Nicolas Petton
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
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).