unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* giving `setq-local' the same signature as `setq'
@ 2015-03-18 15:26 Jordon Biondo
  2015-03-18 16:24 ` Stefan Monnier
  0 siblings, 1 reply; 9+ messages in thread
From: Jordon Biondo @ 2015-03-18 15:26 UTC (permalink / raw)
  To: emacs-devel

I’ve often run into an issue when assuming `setq-local’ behave like `setq’ by accepting multiple [SYM VAL] pairs and returning the value assigned to the last symbol rather than only accepting one symbol and one value.

This is my patch that modifies `setq-local’ to behave this way. Please advise on why this can or shouldn’t be applied.

Note that I have not filled out the copyright assignment paperwork, so if it is to be applied, please send send in the right direction to get the paperwork taken care of.

Thank You

- Jordon Biondo



diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index d61a0a6..8154d60 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,8 @@
+2015-03-18  Jordon Biondo  <jordonbiondo@gmail.com>
+
+	* lisp/subr.el (setq-local): Can now set multiple local variables
+	like `setq'.
+
 2015-03-18  Dima Kogan  <dima@secretsauce.net>
 
 	Have gud-display-line not display source buffer in gud window.
diff --git a/lisp/subr.el b/lisp/subr.el
index deadca6..41340f0 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -116,10 +116,21 @@ BODY should be a list of Lisp expressions.
   ;; depend on backquote.el.
   (list 'function (cons 'lambda cdr)))
 
-(defmacro setq-local (var val)
-  "Set variable VAR to value VAL in current buffer."
+(defmacro setq-local (&rest args)
+  "Set each SYM to the value of its VAL in the current buffer.
+
+\(fn [SYM VAL]...)"
   ;; Can't use backquote here, it's too early in the bootstrap.
-  (list 'set (list 'make-local-variable (list 'quote var)) val))
+  (let ((expr))
+    (while args
+      (setq expr
+            (cons
+             (list 'set
+                   (list 'make-local-variable (list 'quote (car args)))
+                   (car (cdr args)))
+             expr))
+      (setq args (cdr (cdr args))))
+    (cons 'progn (nreverse expr))))
 
 (defmacro defvar-local (var val &optional docstring)
   "Define VAR as a buffer-local variable with default value VAL.




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

* Re: giving `setq-local' the same signature as `setq'
  2015-03-18 15:26 giving `setq-local' the same signature as `setq' Jordon Biondo
@ 2015-03-18 16:24 ` Stefan Monnier
  2015-03-19 14:08   ` Richard Stallman
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2015-03-18 16:24 UTC (permalink / raw)
  To: Jordon Biondo; +Cc: emacs-devel

> I’ve often run into an issue when assuming `setq-local’ behave like
> `setq’ by accepting multiple [SYM VAL] pairs and returning the value
> assigned to the last symbol rather than only accepting one symbol and
> one value.

I find this behavior of `setq' to be a misfeature, which is why
I haven't adopted it for setq-local.


        Stefan



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

* Re: giving `setq-local' the same signature as `setq'
  2015-03-18 16:24 ` Stefan Monnier
@ 2015-03-19 14:08   ` Richard Stallman
  2015-03-19 14:48     ` Jordon Biondo
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Stallman @ 2015-03-19 14:08 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: jordonbiondo, 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. ]]]

It is most natural for setq-local to have the same calling convention
as setq.

-- 
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org  www.gnu.org
Skype: No way! See stallman.org/skype.html.




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

* Re: giving `setq-local' the same signature as `setq'
  2015-03-19 14:08   ` Richard Stallman
@ 2015-03-19 14:48     ` Jordon Biondo
  2015-03-19 15:11       ` Drew Adams
  0 siblings, 1 reply; 9+ messages in thread
From: Jordon Biondo @ 2015-03-19 14:48 UTC (permalink / raw)
  To: rms; +Cc: Stefan Monnier, emacs-devel


> On Mar 19, 2015, at 10:08 AM, Richard Stallman <rms@gnu.org> wrote:
> 
> It is most natural for setq-local to have the same calling convention
> as setq.


> On Mar 18, 2015, at 12:24 PM, Stefan Monnier <monnier@IRO.UMontreal.CA> wrote:
> 
> I find this behavior of `setq' to be a misfeature, which is why
> I haven't adopted it for setq-local.


I understand the notion of setq's signature being a misfeature, but seeing as that will never change, I would tend to think that `setq-local’ should reflect it’s name and act the same as `setq’ but change values locally. 

Regardless of the solution decided upon, thank you both for the input,

- Jordon Biondo


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

* RE: giving `setq-local' the same signature as `setq'
  2015-03-19 14:48     ` Jordon Biondo
@ 2015-03-19 15:11       ` Drew Adams
  2015-03-19 15:17         ` Oleh Krehel
  0 siblings, 1 reply; 9+ messages in thread
From: Drew Adams @ 2015-03-19 15:11 UTC (permalink / raw)
  To: Jordon Biondo, rms; +Cc: Stefan Monnier, emacs-devel

> > > I find this behavior of `setq' to be a misfeature, which is
> > > why I haven't adopted it for setq-local.
> 
> > It is most natural for setq-local to have the same calling
> > convention as setq.
> 
> I understand the notion of setq's signature being a misfeature,

You do?  Pray tell, in what way is it a misfeature?  Nothing has
been said to elucidate this, so far - it has only been asserted.

IMHO, it is a feature, giving users the choice.  Just like implicit
`progn' gives you the choice of adding `progn' or not.

I often prefer to see sequential assignments grouped in the same
`setq'.  It means a lot less noise, for one thing.

Especially when it means not needing to group multiple `setq's
using `progn'.

> but seeing as that will never change, I would tend to think that
> `setq-local’ should reflect it’s name and act the same as `setq’

Yes.  Not to mention the same as Common Lisp `setf' and `psetf'...
(Other Lisps too.)

> but change values locally.

Yes, I think so too, FWIW.



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

* Re: giving `setq-local' the same signature as `setq'
  2015-03-19 15:11       ` Drew Adams
@ 2015-03-19 15:17         ` Oleh Krehel
  2015-03-19 15:39           ` Drew Adams
  0 siblings, 1 reply; 9+ messages in thread
From: Oleh Krehel @ 2015-03-19 15:17 UTC (permalink / raw)
  To: Drew Adams; +Cc: Jordon Biondo, emacs-devel, rms, Stefan Monnier

Drew Adams <drew.adams@oracle.com> writes:

> You do?  Pray tell, in what way is it a misfeature?  Nothing has
> been said to elucidate this, so far - it has only been asserted.
>
> IMHO, it is a feature, giving users the choice.

Choice leads to inconsistency.  I very much prefer the
only-one-variable-per-setq style. It shows much more clearly where the
variable is. It also gives an anchor to quickly navigate to the variable
to get its value.

In a setq list of 10 items, by item 5 it is already unclear which is the
variable and which is the value.  In my opinion, it's not worth
complicating the code maintenance just to save a few chars.

Oleh



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

* RE: giving `setq-local' the same signature as `setq'
  2015-03-19 15:17         ` Oleh Krehel
@ 2015-03-19 15:39           ` Drew Adams
  2015-03-19 15:55             ` Oleh Krehel
  0 siblings, 1 reply; 9+ messages in thread
From: Drew Adams @ 2015-03-19 15:39 UTC (permalink / raw)
  To: Oleh Krehel; +Cc: Jordon Biondo, emacs-devel, rms, Stefan Monnier

> > You do?  Pray tell, in what way is it a misfeature?  Nothing has
> > been said to elucidate this, so far - it has only been asserted.
> >
> > IMHO, it is a feature, giving users the choice.
> 
> Choice leads to inconsistency.

Bof.

http://en.wikipedia.org/wiki/Self-Reliance and search for "hobgoblin".

> I very much prefer the only-one-variable-per-setq style.

You're in luck then.  You have the choice. ;-)

You can do the same for `let*', if you like:

(let ((foo  fooval))
  (let ((phlop  phlopval))
    (let ((toto  totoval))
      ...)))

> It shows much more clearly where the variable is.

Where the variable is?  How so?  (Where is it?  Where's Waldo?)

> It also gives an anchor to quickly navigate to the variable
> to get its value.

How so?  Please elaborate.

> In a setq list of 10 items, by item 5 it is already unclear which is the
> variable and which is the value.  In my opinion, it's not worth
> complicating the code maintenance just to save a few chars.

This is why it is good that you have the choice.

I find it clearer to let `setq' do the grouping, instead of implicit or
explicit `progn'.  But I put each var & value pair on a separate line:

(setq foo    fooval
      phlop  phlopval  ; Maybe this one needs a comment.
      toto   totoval)

I don't do this to save characters (e.g. for typing).  I do it to make
the code clearer and maintenance less error prone and easier.  For me,
at least.



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

* Re: giving `setq-local' the same signature as `setq'
  2015-03-19 15:39           ` Drew Adams
@ 2015-03-19 15:55             ` Oleh Krehel
  2015-03-19 17:25               ` Drew Adams
  0 siblings, 1 reply; 9+ messages in thread
From: Oleh Krehel @ 2015-03-19 15:55 UTC (permalink / raw)
  To: Drew Adams; +Cc: Jordon Biondo, rms, Stefan Monnier, emacs-devel

Drew Adams <drew.adams@oracle.com> writes:

>> I very much prefer the only-one-variable-per-setq style.
>
> You're in luck then.  You have the choice. ;-)

What I meant to say that I very much prefer the
only-one-variable-per-setq style when interacting with other people's
code. Obviously, I don't use this notation in my own code.

>
> You can do the same for `let*', if you like:
>
> (let ((foo  fooval))
>   (let ((phlop  phlopval))
>     (let ((toto  totoval))
>       ...)))
>

Now you've just lead yourself into a trap. This is similar to
one-var-per-setq:

(let* ((foo fooval)
       (phlop phlopval)
       (toto totoval))
  ...)

This is similar to multi-var-per-setq:

(let* (foo fooval
       phlop phlopval
       toto totoval)
  ...)

It already looks bad for single symbol statements. Imagine how bad it
would be if they were more complex.

>> It shows much more clearly where the variable is.
>
> Where the variable is?  How so?  (Where is it?  Where's Waldo?)

Obviously, the variable is by the big fat left paren.

>> It also gives an anchor to quickly navigate to the variable
>> to get its value.
>
> How so?  Please elaborate.

With C-M-n and C-M-p you can navigate to the big fat paren by which the
variable resides (after setq).

>> In a setq list of 10 items, by item 5 it is already unclear which is the
>> variable and which is the value.  In my opinion, it's not worth
>> complicating the code maintenance just to save a few chars.
>
> This is why it is good that you have the choice.

You're wrong here. I don't have the choice. Just yesterday I was debugging my
AUCTEX config. It wasn't pleasant to navigate 5-variable setq
statements, some of which took the whole page.

> I find it clearer to let `setq' do the grouping, instead of implicit or
> explicit `progn'.  But I put each var & value pair on a separate line:
>
> (setq foo    fooval
>       phlop  phlopval  ; Maybe this one needs a comment.
>       toto   totoval)
>
> I don't do this to save characters (e.g. for typing).  I do it to make
> the code clearer and maintenance less error prone and easier.  For me,
> at least.

Imagine that you want to comment out `phlop phlopval', which is a
multi-line statement. If it was bounded by parens, you could do it in an
easy and error-free way. Otherwise, you have to manually select the region.

Oleh



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

* RE: giving `setq-local' the same signature as `setq'
  2015-03-19 15:55             ` Oleh Krehel
@ 2015-03-19 17:25               ` Drew Adams
  0 siblings, 0 replies; 9+ messages in thread
From: Drew Adams @ 2015-03-19 17:25 UTC (permalink / raw)
  To: Oleh Krehel; +Cc: Jordon Biondo, rms, Stefan Monnier, emacs-devel

> > You can do the same for `let*', if you like:
> > (let ((foo  fooval))
> >   (let ((phlop  phlopval))
> >     (let ((toto  totoval))
> >       ...)))
> 
> Now you've just lead yourself into a trap. This is similar to
> one-var-per-setq:
> (let* ((foo fooval)
>        (phlop phlopval)
>        (toto totoval))
>   ...)

No, one var per `let' would be as I showed it - 3 `let's for 3 bindings.

Using `let*' with multiple vars is analogous to using `setq' with multiple
vars.  `setq' assigns and `let*' binds, but they both let you give values
to multiple variables.  Or to only one variable at a time - your choice.

> This is similar to multi-var-per-setq:
> (let* (foo fooval
>        phlop phlopval
>        toto totoval)
>   ...)

No, that is simply malformed code.

> >> It also gives an anchor to quickly navigate to the variable
> >> to get its value.
> >
> > How so?  Please elaborate.
> 
> With C-M-n and C-M-p you can navigate to the big fat paren by which the
> variable resides (after setq).

OK.

> >> In a setq list of 10 items, by item 5 it is already unclear which is the
> >> variable and which is the value.  In my opinion, it's not worth
> >> complicating the code maintenance just to save a few chars.
> >
> > This is why it is good that you have the choice.
> 
> You're wrong here. I don't have the choice. Just yesterday I was debugging
> my AUCTEX config. It wasn't pleasant to navigate 5-variable setq
> statements, some of which took the whole page.

That problem is independent of this discussion, unless you are referring
to the convenience of your using `C-M-p' to move to individual assignments.

One can write bad code, with 473 `setq's in a row or with a single `setq'
that has 473 assignments.  Being able to group assignments in a single
`setq' does not require anyone to use many assignments in a row.

> > I find it clearer to let `setq' do the grouping, instead of implicit or
> > explicit `progn'.  But I put each var & value pair on a separate line:
> >
> > (setq foo    fooval
> >       phlop  phlopval  ; Maybe this one needs a comment.
> >       toto   totoval)
> >
> > I don't do this to save characters (e.g. for typing).  I do it to make
> > the code clearer and maintenance less error prone and easier.  For me,
> > at least.
> 
> Imagine that you want to comment out `phlop phlopval', which is a
> multi-line statement. If it was bounded by parens, you could do it in an
> easy and error-free way. Otherwise, you have to manually select the region.

Actually, `phlop phlopval' is a single line, and can be commented out simply.

But I take your point.  Yes, the style I prefer can mean extra typing.
To me it's worth it, for the sake of clearer code (IMO).  But you don't
need to write code the way I prefer.  And you don't need to maintain my
code.

If you work with a team to create and maintain code, then it can help to
decide what the team prefers, in terms of coding style.  That's not
limited to this discussion about `setq'.

What is germain to this discussion is that different teams can choose
what they want, wrt using separate `setq's for multiple assignments.

What you propose is that for the sake of "consistency" there must be,
in effect, only one team: the choice should be made for Emacs Lisp as
a whole, instead of letting those who use it decide.

I prefer that Emacs Lisp be consistent with, well, LISP in this regard.

Multiple assignments for `setq' have been around since the 60s in Lisp
(but no, they were not in Lisp 1.5).  At least two of us like it that way.



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

end of thread, other threads:[~2015-03-19 17:25 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-18 15:26 giving `setq-local' the same signature as `setq' Jordon Biondo
2015-03-18 16:24 ` Stefan Monnier
2015-03-19 14:08   ` Richard Stallman
2015-03-19 14:48     ` Jordon Biondo
2015-03-19 15:11       ` Drew Adams
2015-03-19 15:17         ` Oleh Krehel
2015-03-19 15:39           ` Drew Adams
2015-03-19 15:55             ` Oleh Krehel
2015-03-19 17:25               ` Drew Adams

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).