From: Kelly Dean <kelly@prtime.org>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: emacs-devel@gnu.org
Subject: Re: [PATCH] (Updated) Run hook when variable is set
Date: Sat, 21 Feb 2015 14:18:02 +0000 [thread overview]
Message-ID: <HGBvdMciIbdx8At48cuBzdhnw7ZhtFedJlH41DHA4PG@local> (raw)
In-Reply-To: <jwva908ofzm.fsf-monnier+emacs@gnu.org>
Stefan Monnier wrote:
> I think either behavior is equally correct and wrong (sometimes you'd
> rather want one and sometimes you'd rather want the other), so I'd
> rather choose based on which of the two is more efficient/easy to
> implement (and if it's not on the critical path (i.e. the path used when
> the variable is not hooked), then efficiency doesn't matter).
It's not on the critical path, and they're equally efficient and easy to implement. Returning the override value results in a few less lines of code (thus smaller patch), since in some places I don't have to put return statements on separate lines from the calls to run_varhook, and in some places that lets me eliminate a pair of curly brackets too.
> In either case, `setq' should never return Qunbound.
Right. It doesn't.
> Regarding one of the bikesheds,
[snip]
> We can change the name later to something actually better, but for now,
> let's just stick to "constant".
Ok, I'll change it back.
>> +#define SYM_CONST 1
>> +#define SYM_HOOKED 2
> constant and hooked at the same time is nonsensical, so these aren't two
> independent bits, instead `vetted' is a 3-valued field. An `enum'
> sounds right.
The compiler will encode the enum into Lisp_Symbol's bitfield, so that will produce no change in the compiled code. And SYM_CONST and SYM_HOOKED are better than sprinkling the code with 1 and 2 as magic numbers, for the same reason that «false» and «true» are better than 0 and 1 for booleans.
But I'll put those constants into an enum.
Note that those constant definitions have been there ever since I originally combined the constant and hooked fields in the patch I submitted on Feb 9th.
>> -static void grow_specpdl (void);
>> +static inline void grow_specpdl (void);
>
> What happens if we don't inline grow_specpdl?
That's just an optimization since it's in the critical path of specbind, as I noted in my message when I made this change on Feb 9th. The result is a small but measurable performance improvement, at the cost of increasing the executable's size by a few kB (i.e. less than a tenth of a percent, since Emacs is nearly 20MB already).
If that's an undesirable tradeoff, I'll remove the inline.
>> + case SYMBOL_VARALIAS:
>> + sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start;
>
> Why did you have to move this?
[snip]
> Hmm... same kind of change here. I must be missing something.
I didn't have to. It's just a minor optimization to avoid an extra conditional branch before the common case (SYMBOL_PLAINVAL) on the critical path, in case the compiler implements the switch statement as a series of «if», «else if», «else if» statements. I decided it was worth bothering to make this change because your original reason for wanting to combine the constant and hooked fields was just to avoid an extra conditional branch on this same critical path in set_internal.
Same thing for the other two places (specbind and find_symbol_value) where I made this same change.
These have been here since Feb 9th, and on Feb 7th I explained why.
>> + set_internal (symbol, old_value, where, true, Dyn_Unbind);
>
> If using "unbind" when referring to "undoing a let-binding" bothers you,
That doesn't bother me. ‟Unbind” is the right term for that. What bothers me is saying that a variable is ‟unbound” when it's actually bound to void and the binding shadows a non-void binding.
> Personally I have no problem with using "unbind"
> sometimes for "makunbound" and sometimes for "undo a let".
Neither would I, if void could never shadow non-void.
> I'd give it a more verbose name, to make sure it doesn't clash with
> someone else's var. After all, it's not like this is going to be used
> very often, so the length doesn't matter. `symbol-setter-void-value'
> sounds fine.
Ok, I'll change it.
>> + XSYMBOL (Vvoid_sentinel)->declared_special = true;
>> + XSYMBOL (Vvoid_sentinel)->vetted = SYM_CONST;
>
> This value is just a symbol, not a variable, so there's no point marking
> it as special and/or constant.
If the user does something stupid such as (set void-sentinel 'foo), it might as well barf. Especially since the print name looks like a keyword. Thus marked constant.
I don't see why mark it special, but t and nil are marked special, so I decided to do this for the sake of consistency, in case there was some reason constants should be marked special.
>> +buf-local: The setter's buffer-local environment.
>> +dyn-local: The innermost dynamic environment in which SYMBOL is bound.
>> +dyn-bind: A new dynamic environment, such as creatable using `let'.
>
> I think this needs clarification, because when I read it, I don't know
> for sure which one I'd get in which case.
Ok, I'll elaborate.
>> +If OLDVAL
>> +is the value of void-sentinel but NEWVAL is not, you can override the new
>> +value, but you can't prevent the variable from being set to a non-void value.
>
> Why not?
Because if you could, then as I explained in my previous message, you could convert a setq into a makunbound, and since I changed setq to return the override value, that means setq could return Qunbound, which is something it should never do.
>> +To hook all variables of a symbol, use `symbol-hook'.
>
> "all variables of a symbol" sounds really odd.
Ok, I'll change it.
> Whether there are
> several variables for a single symbol is really a philosophical
> question,
Until you add multithreading to Emacs. ;-)
> I'd much prefer to keep all the new functions/vars of this feature under
> a common (and new) prefix. I'll let you choose whether it should be
> `symbol-setter-', `symbol-watcher-`, `symbol-hook-', or whatnot.
Ok, I'll change it.
> Why disallow Qunbound for all but makunbound?
> I understand that it might be strange to return Qunbound in the `setq'
> case, but I'm not sure it's worth the trouble trying to disallow it.
Because I changed setq to return the override value. And as I noted, it also has the fortunate side effect of making (setq x void-sentinel) behave the same regardless of whether x is hooked. IOW, technically, allowing Qunbound for setq would be a bug (even if setq returned its argument, instead of the override value), because hooking a symbol must not change the behavior of Emacs.
> And it seems positively wrong in the case of unwinding the topmost let
> binding of a variable, so even if we do want to disallow it, the test
> shouldn't be "rawenv == Dyn_Makvoid" but "orig_newval == Qunbound".
> So, I think we don't need Dyn_Makvoid (hence we don't need to touch
> Fmakunbound).
Yup, that's a bug. Oops.
> Since writing the above, I think I'm beginning to like the idea of
> (setq <var> <val>) always returning <val> even if <var> ends up set to
> something else.
It would be annoying in the case of (if (setq x y) ...), if you override the setting of x but the «if» doesn't respect your choice.
> Try M-: (list (setq auto-hscroll-mode 2) auto-hscroll-mode) RET
Whether or not hooked, you get (2 t). If hooked, and you override to 3, you get (3 t), not (t t), because the return value of setq is the override value; setq doesn't set the variable and then read it back.
>> - if (sym->constant)
>> + if (SYM_CONST_P (sym))
>> error ("Symbol %s may not be frame-local", SDATA (SYMBOL_NAME (variable)));
>
> I think we can keep sym->constant here.
That would be a bug, since it would signal an error if the symbol is hooked. Hooking a symbol must not change the behavior of Emacs.
> we want to inflict pain on
> the few rare remaining users of frame-local.
Just deleting all the code for frame-local would accomplish that more effectively.
next prev parent reply other threads:[~2015-02-21 14:18 UTC|newest]
Thread overview: 110+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-20 2:54 Proposal to change cursor appearance to indicate region activation Kelly Dean
2013-04-20 7:23 ` Drew Adams
2015-01-22 5:38 ` [PATCH] " Kelly Dean
2015-01-22 14:25 ` Stefan Monnier
2015-01-23 3:08 ` [PATCH] " Kelly Dean
2015-01-23 4:55 ` Stefan Monnier
2015-01-23 11:07 ` Kelly Dean
2015-01-23 17:49 ` Drew Adams
2015-01-24 3:06 ` Kelly Dean
2015-01-24 4:52 ` Stefan Monnier
2015-01-24 9:22 ` Kelly Dean
2015-01-25 14:29 ` Stefan Monnier
2015-01-28 9:15 ` [PATCH] Run hook when variable is set Kelly Dean
2015-01-28 9:23 ` [PATCH] Proposal to change cursor appearance to indicate region activation Kelly Dean
2015-01-28 11:24 ` David Kastrup
2015-01-28 12:13 ` David Kastrup
2015-01-29 10:46 ` Kelly Dean
2015-01-29 11:16 ` David Kastrup
2015-01-30 7:20 ` Kelly Dean
2015-01-30 9:19 ` David Kastrup
2015-01-30 10:05 ` Kelly Dean
2015-01-30 10:12 ` David Kastrup
2015-01-30 9:43 ` Kelly Dean
2015-01-28 19:25 ` [PATCH] Run hook when variable is set Stefan Monnier
2015-01-29 8:20 ` Kelly Dean
2015-01-29 8:28 ` Lars Ingebrigtsen
2015-01-29 14:58 ` Stefan Monnier
2015-01-30 7:34 ` Kelly Dean
2015-01-30 15:55 ` Stefan Monnier
2015-01-31 9:18 ` Kelly Dean
2015-01-31 20:48 ` Stefan Monnier
2015-02-02 5:40 ` Kelly Dean
2015-02-02 15:57 ` Stefan Monnier
2015-02-03 19:56 ` Kelly Dean
2015-02-03 22:49 ` Stefan Monnier
2015-02-05 3:10 ` [PATCH] (Updated) " Kelly Dean
2015-02-05 13:57 ` Stefan Monnier
2015-02-06 5:34 ` Kelly Dean
2015-02-06 14:42 ` Stefan Monnier
2015-02-07 12:27 ` Kelly Dean
2015-02-07 15:09 ` Stefan Monnier
2015-02-09 3:24 ` Kelly Dean
2015-02-12 19:58 ` Stefan Monnier
2015-02-13 23:08 ` Kelly Dean
2015-02-14 0:55 ` Stefan Monnier
2015-02-14 22:19 ` Kelly Dean
2015-02-15 20:25 ` Stefan Monnier
2015-02-17 2:22 ` Kelly Dean
2015-02-17 23:07 ` Richard Stallman
2015-02-18 3:19 ` The purpose of makunbound (Was: Run hook when variable is set) Kelly Dean
2015-02-18 5:48 ` The purpose of makunbound Stefan Monnier
2015-02-18 8:51 ` Kelly Dean
2015-02-18 14:34 ` Stefan Monnier
2015-02-18 18:53 ` Kelly Dean
2015-02-18 22:42 ` Stefan Monnier
2015-02-19 10:36 ` Kelly Dean
2015-02-22 0:18 ` Kelly Dean
2015-02-19 10:45 ` Kelly Dean
2015-02-19 13:33 ` Stefan Monnier
2015-02-19 23:51 ` Kelly Dean
2015-02-20 1:59 ` Stefan Monnier
2015-02-20 9:35 ` Kelly Dean
2015-02-20 16:55 ` Stefan Monnier
2015-02-20 2:58 ` Stephen J. Turnbull
2015-02-20 0:56 ` Richard Stallman
2015-02-20 9:02 ` Kelly Dean
2015-02-20 15:41 ` Richard Stallman
2015-02-21 5:45 ` Stephen J. Turnbull
2015-02-22 0:32 ` Kelly Dean
2015-02-22 8:45 ` Andreas Schwab
2015-02-18 5:15 ` [PATCH] (Updated) Run hook when variable is set Kelly Dean
2015-02-18 22:37 ` Stefan Monnier
2015-02-18 22:37 ` Stefan Monnier
2015-02-19 10:35 ` Kelly Dean
2015-02-19 13:30 ` Stefan Monnier
2015-02-20 6:48 ` Kelly Dean
2015-02-20 19:29 ` Stefan Monnier
2015-02-21 14:18 ` Kelly Dean [this message]
2015-02-21 20:51 ` Stefan Monnier
2015-02-22 0:32 ` Kelly Dean
2015-02-22 10:40 ` Stephen J. Turnbull
2015-02-22 21:35 ` Stefan Monnier
2015-02-23 3:09 ` Kelly Dean
2015-02-23 4:19 ` Stefan Monnier
2015-02-20 20:27 ` Proposal for debugging/testing option Kelly Dean
2015-02-24 16:28 ` Stefan Monnier
2015-02-14 20:37 ` [PATCH] (Updated) Run hook when variable is set Johan Bockgård
2015-02-15 19:36 ` Stefan Monnier
2015-02-15 19:53 ` Patches: inline vs. attachment, compressed vs. uncompressed. [was: Run hook when variable is set] Alan Mackenzie
2015-02-06 9:55 ` [PATCH] (Updated) Run hook when variable is set Kelly Dean
2015-01-30 23:29 ` [PATCH] " Richard Stallman
2015-01-31 9:23 ` Kelly Dean
2015-01-31 23:16 ` Richard Stallman
2015-02-02 5:41 ` Kelly Dean
2015-02-01 2:04 ` Alexis
2015-02-01 4:05 ` Stefan Monnier
2015-02-01 8:58 ` David Kastrup
2015-01-29 16:06 ` Eli Zaretskii
2015-01-30 7:14 ` Kelly Dean
2015-01-30 9:08 ` Eli Zaretskii
2015-01-23 20:34 ` [PATCH] Proposal to change cursor appearance to indicate region activation Stefan Monnier
2015-01-24 0:25 ` Kelly Dean
2015-01-23 10:01 ` Tassilo Horn
2015-01-23 17:49 ` Drew Adams
2015-01-23 10:06 ` Eli Zaretskii
2015-01-23 11:40 ` Kelly Dean
2015-01-23 11:56 ` Eli Zaretskii
2015-01-22 5:41 ` Kelly Dean
2013-11-23 13:34 ` Stefan Monnier
2013-11-23 20:25 ` Drew Adams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=HGBvdMciIbdx8At48cuBzdhnw7ZhtFedJlH41DHA4PG@local \
--to=kelly@prtime.org \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.