* bug#30078: 27.0.50; Use lexical-binding for M-: @ 2018-01-11 16:36 Stefan Monnier 2018-01-11 20:58 ` Michael Heerdegen 0 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-01-11 16:36 UTC (permalink / raw) To: 30078 Package: Emacs Version: 27.0.50 I think we should slowly move towards making lexical-binding the default and we could start by making M-: always use lexical binding. WDYT? Stefan diff --git a/lisp/simple.el b/lisp/simple.el index 4c69e0f6ff..fa31ef9f0f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1608,12 +1608,12 @@ eval-expression (eval-expression-get-print-arguments current-prefix-arg))) (if (null eval-expression-debug-on-error) - (push (eval exp lexical-binding) values) + (push (eval exp t) values) (let ((old-value (make-symbol "t")) new-value) ;; Bind debug-on-error to something unique so that we can ;; detect when evalled code changes it. (let ((debug-on-error old-value)) - (push (eval (macroexpand-all exp) lexical-binding) values) + (push (eval (macroexpand-all exp) t) values) (setq new-value debug-on-error)) ;; If evalled code has changed the value of debug-on-error, ;; propagate that change to the global binding. ^ permalink raw reply related [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-11 16:36 bug#30078: 27.0.50; Use lexical-binding for M-: Stefan Monnier @ 2018-01-11 20:58 ` Michael Heerdegen 2018-01-12 14:58 ` Stefan Monnier 0 siblings, 1 reply; 40+ messages in thread From: Michael Heerdegen @ 2018-01-11 20:58 UTC (permalink / raw) To: Stefan Monnier; +Cc: 30078 Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > I think we should slowly move towards making lexical-binding the default > and we could start by making M-: always use lexical binding. > WDYT? Why not? But maybe we should keep this consistent with C-x C-e in *scratch* to avoid confusion (a la "why do the evaluation results differ?"), i.e. enable lexical-binding in *scratch* at the same time? Michael. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-11 20:58 ` Michael Heerdegen @ 2018-01-12 14:58 ` Stefan Monnier 2018-01-12 16:12 ` Stefan Monnier 0 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-01-12 14:58 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30078 >> I think we should slowly move towards making lexical-binding the default >> and we could start by making M-: always use lexical binding. >> WDYT? > Why not? > But maybe we should keep this consistent with C-x C-e in *scratch* to > avoid confusion (a la "why do the evaluation results differ?"), > i.e. enable lexical-binding in *scratch* at the same time? Good idea. Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 14:58 ` Stefan Monnier @ 2018-01-12 16:12 ` Stefan Monnier 2018-01-12 16:53 ` Glenn Morris ` (3 more replies) 0 siblings, 4 replies; 40+ messages in thread From: Stefan Monnier @ 2018-01-12 16:12 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30078 >>> I think we should slowly move towards making lexical-binding the default >>> and we could start by making M-: always use lexical binding. >>> WDYT? >> Why not? >> But maybe we should keep this consistent with C-x C-e in *scratch* to >> avoid confusion (a la "why do the evaluation results differ?"), >> i.e. enable lexical-binding in *scratch* at the same time? > Good idea. I figured M-x ielm would qualify as well. How 'bout this patch, then? Stefan diff --git a/etc/NEWS b/etc/NEWS index f6f36dfc85..d7e84eca7f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -52,6 +52,10 @@ to reduce differences between developer and production builds. \f * Changes in Emacs 27.1 +** Lexical binding is now used when evaluating interactive Elisp forms +More specifically, lexical-binding is used for M-:, M-x ielm, as well +as in the *scratch* buffer. + --- ** The new option 'tooltip-resize-echo-area' avoids truncating tooltip text on GUI frames when tooltips are displayed in the echo area. Instead, diff --git a/lisp/ielm.el b/lisp/ielm.el index fb285e80f6..cad1bded4f 100644 --- a/lisp/ielm.el +++ b/lisp/ielm.el @@ -408,8 +408,7 @@ ielm-eval-input (setf standard-output new-standard-output)) (kill-buffer (current-buffer)) (set-buffer wbuf) - (setq result - (eval form lexical-binding)) + (setq result (eval form t)) (setq wbuf (current-buffer)) (setq ielm-temp-buffer diff --git a/lisp/server.el b/lisp/server.el index ac0d701851..918197ab44 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1294,7 +1294,7 @@ server-execute ((functionp initial-buffer-choice) (funcall initial-buffer-choice))))) (switch-to-buffer - (if (buffer-live-p buf) buf (get-buffer-create "*scratch*")) + (if (buffer-live-p buf) buf (startup--get-buffer-create-scratch)) 'norecord))) ;; Delete the client if necessary. diff --git a/lisp/simple.el b/lisp/simple.el index 87e0b23377..e2d3cd1505 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1555,12 +1555,12 @@ eval-expression (eval-expression-get-print-arguments current-prefix-arg))) (if (null eval-expression-debug-on-error) - (push (eval exp lexical-binding) values) + (push (eval exp t) values) (let ((old-value (make-symbol "t")) new-value) ;; Bind debug-on-error to something unique so that we can ;; detect when evalled code changes it. (let ((debug-on-error old-value)) - (push (eval (macroexpand-all exp) lexical-binding) values) + (push (eval (macroexpand-all exp) t) values) (setq new-value debug-on-error)) ;; If evalled code has changed the value of debug-on-error, ;; propagate that change to the global binding. diff --git a/lisp/startup.el b/lisp/startup.el index 688ea84b7b..f3c0c7b100 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -2095,7 +2095,7 @@ normal-no-mouse-startup-screen (insert "\t\t") (insert-button "Open *scratch* buffer" 'action (lambda (_button) (switch-to-buffer - (get-buffer-create "*scratch*"))) + (startup--get-buffer-create-scratch))) 'follow-link t) (insert "\n") (insert "\n" (emacs-version) "\n" emacs-copyright "\n") @@ -2221,6 +2221,12 @@ display-about-screen (defalias 'about-emacs 'display-about-screen) (defalias 'display-splash-screen 'display-startup-screen) +(defun startup--get-buffer-create-scratch () + (with-current-buffer (get-buffer-create "*scratch*") + (set-buffer-major-mode (current-buffer)) + (setq-local lexical-binding t) + (current-buffer))) + (defun command-line-1 (args-left) "A subroutine of `command-line'." (display-startup-echo-area-message) @@ -2485,7 +2491,7 @@ command-line-1 (when (eq initial-buffer-choice t) ;; When `initial-buffer-choice' equals t make sure that *scratch* ;; exists. - (get-buffer-create "*scratch*")) + (startup--get-buffer-create-scratch)) ;; If *scratch* exists and is empty, insert initial-scratch-message. ;; Do this before switching to *scratch* below to handle bug#9605. @@ -2504,7 +2510,7 @@ command-line-1 ((functionp initial-buffer-choice) (funcall initial-buffer-choice)) ((eq initial-buffer-choice t) - (get-buffer-create "*scratch*")) + (startup--get-buffer-create-scratch)) (t (error "initial-buffer-choice must be a string, a function, or t."))))) (unless (buffer-live-p buf) diff --git a/lisp/window.el b/lisp/window.el index d7fdceb205..7f89c87af1 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4578,7 +4578,7 @@ last-buffer (or (get-next-valid-buffer (nreverse (buffer-list frame)) buffer visible-ok frame) (get-buffer "*scratch*") - (let ((scratch (get-buffer-create "*scratch*"))) + (let ((scratch (startup--get-buffer-create-scratch))) (set-buffer-major-mode scratch) scratch))) ^ permalink raw reply related [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 16:12 ` Stefan Monnier @ 2018-01-12 16:53 ` Glenn Morris 2018-01-12 17:23 ` Michael Heerdegen ` (2 subsequent siblings) 3 siblings, 0 replies; 40+ messages in thread From: Glenn Morris @ 2018-01-12 16:53 UTC (permalink / raw) To: Stefan Monnier; +Cc: Michael Heerdegen, 30078 Stefan Monnier wrote: > How 'bout this patch, then? You forgot all the documentation updates. :) ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 16:12 ` Stefan Monnier 2018-01-12 16:53 ` Glenn Morris @ 2018-01-12 17:23 ` Michael Heerdegen 2018-01-12 18:47 ` Stefan Monnier 2018-01-12 18:34 ` Eli Zaretskii 2018-03-19 19:32 ` Stefan Monnier 3 siblings, 1 reply; 40+ messages in thread From: Michael Heerdegen @ 2018-01-12 17:23 UTC (permalink / raw) To: Stefan Monnier; +Cc: 30078 Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > (defun command-line-1 (args-left) > "A subroutine of `command-line'." > (display-startup-echo-area-message) > @@ -2485,7 +2491,7 @@ command-line-1 > (when (eq initial-buffer-choice t) > ;; When `initial-buffer-choice' equals t make sure that *scratch* > ;; exists. > - (get-buffer-create "*scratch*")) > + (startup--get-buffer-create-scratch)) > > ;; If *scratch* exists and is empty, insert initial-scratch-message. > ;; Do this before switching to *scratch* below to handle bug#9605. Don't you also want to change this occurrence in `command-line'? #+begin_src emacs-lisp ;; If *scratch* exists and init file didn't change its mode, initialize it. (if (get-buffer "*scratch*") (with-current-buffer "*scratch*" (if (eq major-mode 'fundamental-mode) (funcall initial-major-mode)))) #+end_src So far, lexical-binding in *scratch* is nil with emacs -Q with your patch. Maybe also check that evaluating the expression `lexical-binding' returns a result that is consistent with the evaluation behavior. In particular, evaluating lexical-binding in M-x ielm RET still gives nil - that's confusing. Michael. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 17:23 ` Michael Heerdegen @ 2018-01-12 18:47 ` Stefan Monnier 2018-01-12 19:35 ` Michael Heerdegen 0 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-01-12 18:47 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30078 > Don't you also want to change this occurrence in `command-line'? > > #+begin_src emacs-lisp > ;; If *scratch* exists and init file didn't change its mode, initialize it. > (if (get-buffer "*scratch*") > (with-current-buffer "*scratch*" > (if (eq major-mode 'fundamental-mode) > (funcall initial-major-mode)))) > #+end_src Ah, so that's where it is, thanks. > So far, lexical-binding in *scratch* is nil with emacs -Q with your > patch. That's what I was seeing as well, indeed :-( > Maybe also check that evaluating the expression `lexical-binding' > returns a result that is consistent with the evaluation behavior. I already know that the check will fail. Is it important? In general the value of the variable lexical-binding during evaluation of the code is not directly related to whether the code is evaluated using lexical rules or not. Within macros, Emacs tries to make sure that lexical-binding reflects whether the code returned by the macro will use lexical scoping or not (so that the macro can adjust the code it generates accordingly), but other than that, the two are largely independent (which is why (setq lexical-binding t) is not the right way to enable lexical scoping in a file). > In particular, evaluating lexical-binding in M-x ielm RET still gives > nil - that's confusing. Right (well, it doesn't always give you nil: it depends on the value of lexical-binding in the buffer currently selected to evaluate the IELM expressions). But this discrepancy also shows up in various other contexts. Eg.: ;; -*- lexical-binding:t -*- (defun my-test () (interactive) (message "%S" lexical-binding)) will give you a lexically scoped command which will tell you the value of lexical-binding at the time&place you run the command, which will sometimes be t and sometimes not. I'm not sure we should try to encourage the user to think a piece of code can check the value of `lexical-binding` to know if it's being evaluated using lexical scoping rules. Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 18:47 ` Stefan Monnier @ 2018-01-12 19:35 ` Michael Heerdegen 2018-01-13 17:58 ` Stefan Monnier 0 siblings, 1 reply; 40+ messages in thread From: Michael Heerdegen @ 2018-01-12 19:35 UTC (permalink / raw) To: Stefan Monnier; +Cc: 30078 Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > I'm not sure we should try to encourage the user to think a piece of > code can check the value of `lexical-binding` to know if it's being > evaluated using lexical scoping rules. I'm not sure, too. But aren't *scratch* and *ielm* special? These are the current buffers when code is evaluated, but they are also some kind of source-code buffer at the same time. In source code file buffers, M-x lexical-binding RET gives you the right answer about how the code in this buffers is interpreted. I think we should be careful - maybe new users are trying to learn Elisp with the help of *ielm*. With your patch, you get ELISP> (let ((x 1)) (lambda () x)) (closure ((x . 1) t) nil x) but if you put point after the input expression and hit C-x C-e you suddenly get (lambda nil x) People who are actually learning Elisp will not make any sense out of this, I think. Michael. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 19:35 ` Michael Heerdegen @ 2018-01-13 17:58 ` Stefan Monnier 0 siblings, 0 replies; 40+ messages in thread From: Stefan Monnier @ 2018-01-13 17:58 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30078 >> I'm not sure we should try to encourage the user to think a piece of >> code can check the value of `lexical-binding` to know if it's being >> evaluated using lexical scoping rules. > I'm not sure, too. But aren't *scratch* and *ielm* special? These are > the current buffers when code is evaluated, For *scratch* yes, but for *ielm* that's not the case: the code is evaluated in the `ielm-working-buffer` (whose name normally appears in the mode-line after "IELM"). Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 16:12 ` Stefan Monnier 2018-01-12 16:53 ` Glenn Morris 2018-01-12 17:23 ` Michael Heerdegen @ 2018-01-12 18:34 ` Eli Zaretskii 2018-01-12 18:49 ` Stefan Monnier 2018-03-19 19:32 ` Stefan Monnier 3 siblings, 1 reply; 40+ messages in thread From: Eli Zaretskii @ 2018-01-12 18:34 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Date: Fri, 12 Jan 2018 11:12:23 -0500 > Cc: 30078@debbugs.gnu.org > > +** Lexical binding is now used when evaluating interactive Elisp forms > +More specifically, lexical-binding is used for M-:, M-x ielm, as well > +as in the *scratch* buffer. Please, not in *scratch*. Setting variables and then evaluating forms that use them is very useful there. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 18:34 ` Eli Zaretskii @ 2018-01-12 18:49 ` Stefan Monnier 2018-01-12 18:55 ` Eli Zaretskii 0 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-01-12 18:49 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, 30078 > Please, not in *scratch*. Setting variables and then evaluating forms > that use them is very useful there. I'm not sure how the two sentences are connected: Setting lexical-binding to t in *scratch* won't prevent setting variables and evaluating forms that use them. Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 18:49 ` Stefan Monnier @ 2018-01-12 18:55 ` Eli Zaretskii 2018-01-12 19:06 ` Stefan Monnier 0 siblings, 1 reply; 40+ messages in thread From: Eli Zaretskii @ 2018-01-12 18:55 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: michael_heerdegen@web.de, 30078@debbugs.gnu.org > Date: Fri, 12 Jan 2018 13:49:00 -0500 > > > Please, not in *scratch*. Setting variables and then evaluating forms > > that use them is very useful there. > > I'm not sure how the two sentences are connected: > Setting lexical-binding to t in *scratch* won't prevent setting > variables and evaluating forms that use them. For some value of "prevent", surely? Dynamically-bound variables will no longer work as they did before, right? ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 18:55 ` Eli Zaretskii @ 2018-01-12 19:06 ` Stefan Monnier 2018-01-12 20:03 ` Eli Zaretskii 0 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-01-12 19:06 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, 30078 >> > Please, not in *scratch*. Setting variables and then evaluating forms >> > that use them is very useful there. >> I'm not sure how the two sentences are connected: >> Setting lexical-binding to t in *scratch* won't prevent setting >> variables and evaluating forms that use them. > For some value of "prevent", surely? Dynamically-bound variables will > no longer work as they did before, right? No, they'll work pretty much as before. Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 19:06 ` Stefan Monnier @ 2018-01-12 20:03 ` Eli Zaretskii 2018-01-12 20:33 ` Noam Postavsky ` (2 more replies) 0 siblings, 3 replies; 40+ messages in thread From: Eli Zaretskii @ 2018-01-12 20:03 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: michael_heerdegen@web.de, 30078@debbugs.gnu.org > Date: Fri, 12 Jan 2018 14:06:41 -0500 > > >> > Please, not in *scratch*. Setting variables and then evaluating forms > >> > that use them is very useful there. > >> I'm not sure how the two sentences are connected: > >> Setting lexical-binding to t in *scratch* won't prevent setting > >> variables and evaluating forms that use them. > > For some value of "prevent", surely? Dynamically-bound variables will > > no longer work as they did before, right? > > No, they'll work pretty much as before. Then you are saying that turning on lexical-binding in *scratch* will change nothing at all? I very much doubt that, and my witness are all those packages that broke due to lexical-binding and needed minor fixes. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 20:03 ` Eli Zaretskii @ 2018-01-12 20:33 ` Noam Postavsky 2018-01-12 20:55 ` Michael Heerdegen 2018-01-13 18:05 ` Stefan Monnier 2 siblings, 0 replies; 40+ messages in thread From: Noam Postavsky @ 2018-01-12 20:33 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, Stefan Monnier, 30078 On Fri, Jan 12, 2018 at 3:03 PM, Eli Zaretskii <eliz@gnu.org> wrote: >> From: Stefan Monnier <monnier@IRO.UMontreal.CA> >> Cc: michael_heerdegen@web.de, 30078@debbugs.gnu.org >> Date: Fri, 12 Jan 2018 14:06:41 -0500 >> >> >> > Please, not in *scratch*. Setting variables and then evaluating forms >> >> > that use them is very useful there. >> >> I'm not sure how the two sentences are connected: >> >> Setting lexical-binding to t in *scratch* won't prevent setting >> >> variables and evaluating forms that use them. >> > For some value of "prevent", surely? Dynamically-bound variables will >> > no longer work as they did before, right? >> >> No, they'll work pretty much as before. > > Then you are saying that turning on lexical-binding in *scratch* will > change nothing at all? I very much doubt that, and my witness are all > those packages that broke due to lexical-binding and needed minor > fixes. Top-level `setq's would be unaffected (because the lexical environment at the top level is empty). Lexical binding only changes what `let' does, for undeclared variables. (okay, not *just* `let', it also affects `lambda') ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 20:03 ` Eli Zaretskii 2018-01-12 20:33 ` Noam Postavsky @ 2018-01-12 20:55 ` Michael Heerdegen 2018-01-12 21:04 ` Eli Zaretskii 2018-01-13 18:05 ` Stefan Monnier 2 siblings, 1 reply; 40+ messages in thread From: Michael Heerdegen @ 2018-01-12 20:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, 30078 Eli Zaretskii <eliz@gnu.org> writes: > Then you are saying that turning on lexical-binding in *scratch* will > change nothing at all? I very much doubt that, and my witness are > all those packages that broke due to lexical-binding and needed minor > fixes. I do what has been proposed for months. I liked it. What are we doing with scratch? (1) Setting global variables, defining small functions and such simple stuff. lexical-binding doesn't make a big difference here. (2) Re-evaluate parts of the source code, often with small modifications, for testing and debugging. Since more and more packages make active use of lexical-binding, this is actually broken currently! Re-evaluating parts of source code in scratch can currently break Emacs. (3) I often posted some code examples in emacs-help which made use of lexical-binding. People pasted it into scratch and it didn't work. It's currently even not trivial to evaluate such examples with lexical-binding on. OTOH, there is not too much code that really relies on dynamical binding mode. And very often, such code is just written in a bad style (missing `defvar's etc.). In summary, I think the advantages clearly prevail. Michael. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 20:55 ` Michael Heerdegen @ 2018-01-12 21:04 ` Eli Zaretskii 2018-01-12 21:11 ` Michael Heerdegen 2018-01-13 18:19 ` Stefan Monnier 0 siblings, 2 replies; 40+ messages in thread From: Eli Zaretskii @ 2018-01-12 21:04 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, 30078 > From: Michael Heerdegen <michael_heerdegen@web.de> > Cc: Stefan Monnier <monnier@IRO.UMontreal.CA>, 30078@debbugs.gnu.org > Date: Fri, 12 Jan 2018 21:55:25 +0100 > > What are we doing with scratch? > > (1) Setting global variables, defining small functions and such simple > stuff. lexical-binding doesn't make a big difference here. We need to discuss the differences whether they are big or not. > (2) Re-evaluate parts of the source code, often with small > modifications, for testing and debugging. Since more and more packages > make active use of lexical-binding, this is actually broken currently! > Re-evaluating parts of source code in scratch can currently break Emacs. You are describing a mistake. People make mistakes all the time, and will continue making mistakes whatever we do. That shouldn't be a basis for our decisions. > (3) I often posted some code examples in emacs-help which made use of > lexical-binding. People pasted it into scratch and it didn't work. > It's currently even not trivial to evaluate such examples with > lexical-binding on. Another mistake. I don't see why this should be of any importance for the decision at hand. > OTOH, there is not too much code that really relies on dynamical binding > mode. And very often, such code is just written in a bad style (missing > `defvar's etc.). That's your opinion. I happen not to share it. > In summary, I think the advantages clearly prevail. I actually didn't yet see any advantages mentioned, and the above aren't, IMO. Lexical-binding is just a feature, albeit an important one. It doesn't have to be introduced into every possible corner of Emacs, not without a good reason. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 21:04 ` Eli Zaretskii @ 2018-01-12 21:11 ` Michael Heerdegen 2018-01-13 17:50 ` Luis Gerhorst 2018-01-13 18:19 ` Stefan Monnier 1 sibling, 1 reply; 40+ messages in thread From: Michael Heerdegen @ 2018-01-12 21:11 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 30078 Eli Zaretskii <eliz@gnu.org> writes: > I actually didn't yet see any advantages mentioned, and the above > aren't, IMO. Lexical-binding is just a feature, albeit an important > one. It doesn't have to be introduced into every possible corner of > Emacs, not without a good reason. Ah, so you doubt that lexical-binding once should just be the default. Then I think we should discuss about this goal. Michael. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 21:11 ` Michael Heerdegen @ 2018-01-13 17:50 ` Luis Gerhorst 2018-01-13 19:48 ` Eli Zaretskii 0 siblings, 1 reply; 40+ messages in thread From: Luis Gerhorst @ 2018-01-13 17:50 UTC (permalink / raw) To: Michael Heerdegen; +Cc: monnier, 30078 > On 12. Jan 2018, at 22:11, Michael Heerdegen <michael_heerdegen@web.de> wrote: > > Ah, so you doubt that lexical-binding once should just be the default. > Then I think we should discuss about this goal. Here are a few possible pros of lexical binding: 1) Make Elisp more approachable to newcomers. Lexical binding is the default in most programming languages and thus more people are familiar with it. This makes it easier for people to understand existing code since they don‘t have to get used to implicit dynamic binding first, which the code may take advantage of. 2) Make existing code more maintainable. I was involved in porting the package emacs-eclim to lexical binding. The process shed light on some very dark parts of the codebase nobody had touched in a while since they were written in very bad style and thus hard to understand. Using lexical binding forced us to simplify those parts. 3) This is a minor one: I‘ve heard that lexical binding allows for more optimizations. I don‘t know to which extend this actually happens and whether it is noticeable to the user. I believe 1) and 2) will significantly help improving the general quality of Elisp code and thus of Emacs in general. Here‘s the big con: If lexical binding should become the default one day, you would have to give everyone a reasonable amount of time (multiple years?) to adapt for it and port their code or set lexical binding to nil in their files. One idea would be to make elisp-mode somehow encourage users to enable lexical binding in the files they are editing. Any ideas how this can be done without annoying users? Ideas: - Prompting every time elisp-mode is enabled in a file that does not have a lexical binding header. - I know that certain functions insert a apropriate copyright notice into el-files, do / can those also set lexical binding to t? Best regards, Luis ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-13 17:50 ` Luis Gerhorst @ 2018-01-13 19:48 ` Eli Zaretskii 2018-01-13 20:19 ` Luis Gerhorst 2018-01-14 5:58 ` Robert Cochran 0 siblings, 2 replies; 40+ messages in thread From: Eli Zaretskii @ 2018-01-13 19:48 UTC (permalink / raw) To: Luis Gerhorst; +Cc: michael_heerdegen, monnier, 30078 > From: Luis Gerhorst <privat@luisgerhorst.de> > Date: Sat, 13 Jan 2018 18:50:36 +0100 > Cc: Eli Zaretskii <eliz@gnu.org>, monnier@IRO.UMontreal.CA, > 30078@debbugs.gnu.org > > 1) Make Elisp more approachable to newcomers. Lexical binding is the default in most programming languages and thus more people are familiar with it. This makes it easier for people to understand existing code since they don‘t have to get used to implicit dynamic binding first, which the code may take advantage of. Do we know for a fact that most users who extend Emacs by writing their own Lisp have background in Lisps and other similar languages where lexical binding is the default? If not, dynamic binding might be easier to grasp for the newcomers. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-13 19:48 ` Eli Zaretskii @ 2018-01-13 20:19 ` Luis Gerhorst 2018-01-14 5:58 ` Robert Cochran 1 sibling, 0 replies; 40+ messages in thread From: Luis Gerhorst @ 2018-01-13 20:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, monnier, 30078 Eli Zaretskii writes: > Do we know for a fact that most users who extend Emacs by writing > their own Lisp have background in Lisps and other similar languages > where lexical binding is the default? If not, dynamic binding might > be easier to grasp for the newcomers. I wouldn't say we know it for a fact, but I would say we can be pretty sure about it. I think nobody would deny that imperative languages, which mostly use lexical binding, are much more popular (e.g. google the 10 most popular programming languages). You may argue that Emacs users have another background but if you go to https://github.com/topics/emacs and look at the contributors of an arbitrary project you can be almost certain they have at least one imperative language in ther portfolio (most I've looked at only have imperative languages and Emacs Lisp projects). ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-13 19:48 ` Eli Zaretskii 2018-01-13 20:19 ` Luis Gerhorst @ 2018-01-14 5:58 ` Robert Cochran 1 sibling, 0 replies; 40+ messages in thread From: Robert Cochran @ 2018-01-14 5:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, monnier, Luis Gerhorst, 30078 Eli Zaretskii <eliz@gnu.org> writes: >> From: Luis Gerhorst <privat@luisgerhorst.de> >> Date: Sat, 13 Jan 2018 18:50:36 +0100 >> Cc: Eli Zaretskii <eliz@gnu.org>, monnier@IRO.UMontreal.CA, >> 30078@debbugs.gnu.org >> >> 1) Make Elisp more approachable to newcomers. Lexical binding is the default >> in most programming languages and thus more people are familiar with it. This >> makes it easier for people to understand existing code since they don‘t have >> to get used to implicit dynamic binding first, which the code may take >> advantage of. > > Do we know for a fact that most users who extend Emacs by writing > their own Lisp have background in Lisps and other similar languages > where lexical binding is the default? If not, dynamic binding might > be easier to grasp for the newcomers. I learned Emacs Lisp by learning Common Lisp first when I set out to learn it. Prior to that, I had been programming in languages that have lexical scoping as the primary scope mechanism. I personally do not know of non-Lisp languages that have variables that work like dynamic variables do. And of course I can't comment from the perspective from a newcommer any more, but I'd be of the mind that entirely dynamic binding would be /less/ easy to grasp, because it does things that I personally find non-intuitive in certain circumstances. I have programmer friends that use Emacs but don't do their own Emacs Lisp, and I would hazard a guess that dynamic bindings would be unintuitive when they differ from lexical bindings in behavior. IMO, the fact that dynamic bindings happen to do the same thing as lexical bindings is the reason the whole thing isn't nearly as confusing as it could be. That's not to say that dynamic bindings are bad - far from it. Dynamic bindings are really useful. But I think that the potentially confusing behavior should be opt-in, not opt-out. -- ~Robert Cochran GPG Fingerprint - BD0C 5F8B 381C 64F0 F3CE E7B9 EC9A 872C 41B2 77C2 ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 21:04 ` Eli Zaretskii 2018-01-12 21:11 ` Michael Heerdegen @ 2018-01-13 18:19 ` Stefan Monnier 2018-01-13 19:34 ` Eli Zaretskii ` (2 more replies) 1 sibling, 3 replies; 40+ messages in thread From: Stefan Monnier @ 2018-01-13 18:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Heerdegen, 30078 > Lexical-binding is just a feature, albeit an important one. > It doesn't have to be introduced into every possible corner of Emacs, > not without a good reason. lexbind-Elisp and dynbind-Elisp are fundamentally two different languages. They are so similar that we don't think of it in those terms, but having those 2 introduces complexity (including for the users occasionally). And actually the fact they're so similar sometimes makes the problem worse because most people don't realize that they have to pay attention to it or how to know which language is used when. I very much hope to see Emacs shed its dynbind-Elisp support at some point, tho it still seems to be a pretty distant future and I'm not even sure how we'll get to that point. bug#30078 is about making another step in this direction. Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-13 18:19 ` Stefan Monnier @ 2018-01-13 19:34 ` Eli Zaretskii 2018-01-13 21:58 ` Stefan Monnier 2018-01-13 23:18 ` Richard Stallman 2018-01-14 2:07 ` Drew Adams 2 siblings, 1 reply; 40+ messages in thread From: Eli Zaretskii @ 2018-01-13 19:34 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: Michael Heerdegen <michael_heerdegen@web.de>, 30078@debbugs.gnu.org > Date: Sat, 13 Jan 2018 13:19:52 -0500 > > I very much hope to see Emacs shed its dynbind-Elisp support at some > point, tho it still seems to be a pretty distant future and I'm not even > sure how we'll get to that point. It's quite clear that these are your views, but going in that direction should be an explicit project-wide decision, widely agreed and accepted by main project contributors. Doing it one subtle step at a time is not the right way, IMO. If and when such a decision is made, we would not need to have these discussions, we could simply go lexical-bind as quickly as it's practical. My comments in this thread are largely because I feel uneasy about this undeclared policy for quite some time. For the record, I have nothing against making lexical-binding the default, if that's what everybody wants. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-13 19:34 ` Eli Zaretskii @ 2018-01-13 21:58 ` Stefan Monnier 0 siblings, 0 replies; 40+ messages in thread From: Stefan Monnier @ 2018-01-13 21:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, 30078 > It's quite clear that these are your views, but going in that > direction should be an explicit project-wide decision, widely agreed > and accepted by main project contributors. Of course. > If and when such a decision is made, we would not need to have these > discussions, we could simply go lexical-bind as quickly as > it's practical. That's what I think I'm doing. Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-13 18:19 ` Stefan Monnier 2018-01-13 19:34 ` Eli Zaretskii @ 2018-01-13 23:18 ` Richard Stallman 2018-01-14 2:07 ` Drew Adams 2 siblings, 0 replies; 40+ messages in thread From: Richard Stallman @ 2018-01-13 23:18 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 [[[ 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. ]]] We could introduce a warning for any Lisp file that fails to specify lexical vs dynamic. After a few years, we could assume that all files specify it, so we could change the default. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-13 18:19 ` Stefan Monnier 2018-01-13 19:34 ` Eli Zaretskii 2018-01-13 23:18 ` Richard Stallman @ 2018-01-14 2:07 ` Drew Adams 2018-01-15 2:34 ` Richard Stallman 2 siblings, 1 reply; 40+ messages in thread From: Drew Adams @ 2018-01-14 2:07 UTC (permalink / raw) To: Stefan Monnier, Eli Zaretskii; +Cc: Michael Heerdegen, 30078 > lexbind-Elisp and dynbind-Elisp are fundamentally two different > languages. If you want to argue that then Lisp itself is fundamentally several languages. (Yes, even Lisp 1.5, sans CLOS and all the rest.) Nothing says that a single language cannot "fundamentally" have more than one kind of binding/scoping. > They are so similar that we don't think of it in those > terms, but having those 2 introduces complexity (including for the users > occasionally). And actually the fact they're so similar sometimes makes > the problem worse because most people don't realize that they have to > pay attention to it or how to know which language is used when. There are plenty of things that one needs to pay attention to in Lisp. List-structure, for one. Lisp is not Haskell. Yes, Lisp can be complex, for both users and implementors. > I very much hope to see Emacs shed its dynbind-Elisp support at some > point, tho it still seems to be a pretty distant future and I'm not even > sure how we'll get to that point. I very much hope _not_. Lexical and dynamic binding each have their place in Lisp, especially in Emacs Lisp. RMS underlined the importance of dynamic binding for Emacs. That argument remains as potent and relevant today as when he wrote it. http://www.gnu.org/software/emacs/emacs-paper.html#SEC18 Lexical and dynamic binding have coexisted fine in Common Lisp for almost 40 years now. And lexical binding is the default in Common Lisp. That would be fine for Emacs Lisp too someday. I have no objection to a move toward that, in principle. It was a definite plus to add lexical binding to Emacs. Thank you very much for that. Bravo. (And a vacuous `defvar' is not a bad way to declare a special/dynamic variable.) On the other hand, it would be a definite impairment to remove dynamic binding from Emacs Lisp. No thank you. > bug#30078 is about making another step in this direction. If that's all bug#30078 is about then don't do it. (But I hope that's not all it's about.) ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-14 2:07 ` Drew Adams @ 2018-01-15 2:34 ` Richard Stallman 0 siblings, 0 replies; 40+ messages in thread From: Richard Stallman @ 2018-01-15 2:34 UTC (permalink / raw) To: Drew Adams; +Cc: michael_heerdegen, monnier, 30078 [[[ 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. ]]] > Lexical and dynamic binding each have their place in Lisp, > especially in Emacs Lisp. RMS underlined the importance > of dynamic binding for Emacs. Emacs must have dynamic binding, but that doesn't mean it needs to have a mode where dynamic binding is the default. It can be limited to the variables declared to be dynamic. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 20:03 ` Eli Zaretskii 2018-01-12 20:33 ` Noam Postavsky 2018-01-12 20:55 ` Michael Heerdegen @ 2018-01-13 18:05 ` Stefan Monnier 2018-01-13 19:37 ` Eli Zaretskii 2 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-01-13 18:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, 30078 >> No, they'll work pretty much as before. > Then you are saying that turning on lexical-binding in *scratch* will > change nothing at all? Not nothing at all, but the two languages are *very* similar and the differences rarely show up in a single expression. My gut feeling is that the main risk to bump into an undesirable behavior is something like (let ((foopkg-var t)) (foopkg-fun arg1 arg2)) where foopkg is not yet loaded and foopkg-fun is autoloaded: Emacs will only be told that `foopkg-var` is a dynamic-variable once the `foopkg-fun` call causes `foopkg` to be loaded, so Emacs will mistakenly use lexical scoping for the let binding because at that it still knows nothing about `foopkg-var`. Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-13 18:05 ` Stefan Monnier @ 2018-01-13 19:37 ` Eli Zaretskii 0 siblings, 0 replies; 40+ messages in thread From: Eli Zaretskii @ 2018-01-13 19:37 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: michael_heerdegen@web.de, 30078@debbugs.gnu.org > Date: Sat, 13 Jan 2018 13:05:58 -0500 > > (let ((foopkg-var t)) > (foopkg-fun arg1 arg2)) > > where foopkg is not yet loaded and foopkg-fun is autoloaded: Emacs will > only be told that `foopkg-var` is a dynamic-variable once the > `foopkg-fun` call causes `foopkg` to be loaded, so Emacs will mistakenly > use lexical scoping for the let binding because at that it still knows > nothing about `foopkg-var`. That indeed could be a confusing situation, perhaps we should have a special form for it, to avoid the confusing/incorrect/unexpected results. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-01-12 16:12 ` Stefan Monnier ` (2 preceding siblings ...) 2018-01-12 18:34 ` Eli Zaretskii @ 2018-03-19 19:32 ` Stefan Monnier 2018-03-19 19:34 ` Stefan Monnier 2018-03-19 20:10 ` Eli Zaretskii 3 siblings, 2 replies; 40+ messages in thread From: Stefan Monnier @ 2018-03-19 19:32 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30078 > I figured M-x ielm would qualify as well. Seeing how forcing lexical-binding within *ielm* raised some objections, I've changed my patch so it only sets lexical-binding in the *ielm* buffer but the evaluation mode will still depend on the lexical-binding setting in ielm-working-buffer (so evaluating `lexical-binding' will again return a value which indicates whether expressions are evaluated using lexical-binding). New patch below. There were some issues regarding the general long term goal of standardizing on lexical-binding. So I'm restarting this discussion below. I wrote: > > I very much hope to see Emacs shed its dynbind-Elisp support at some > > point, tho it still seems to be a pretty distant future and I'm not even > > sure how we'll get to that point. To which Eli replied: > It's quite clear that these are your views, but going in that > direction should be an explicit project-wide decision, widely agreed > and accepted by main project contributors. Doing it one subtle step > at a time is not the right way, IMO. If and when such a decision is > made, we would not need to have these discussions, we could simply go > lexical-bind as quickly as it's practical. Fully agreed. FWIW, this is the decision I took when I added lexical-binding into Emacs-24.1. I had no idea that someone might like to disagree: the lexbind-Elisp language is a strict superset of the dynbind-Elisp language and for that reason I don't see any reason other than backward compatibility to keep dynbind-Elisp. I'm not trying to fool people by "doing it one subtle step at a time", I'm only trying to make this switch as painless as possible. I don't yet have a plan for how we'll get rid of dynbind-Elisp and I'm sure it'll take many years and several more steps, some of them less subtle than others. Some of the steps I could imagine introducing in the not too distant future: - finish converting all Emacs's .el files to use lexical-binding:t. - emit a warning when opening an Elisp file which doesn't specify `lexical-binding:t' in its local vars. - emit a warning when `eval` is called without a nil 2nd arg. AFAICT by looking at packages on github, lexical-binding is very popular, despite the fact that it limits packages to Emacs≥24 and requires explicitly adding a magic cookie on the first line. Also I've only gotten positive feedback so far about it (more specifically, the above paragraph of yours is the most negative feedback I've hard about lexical-binding so far). Eli also wrote: > Do we know for a fact that most users who extend Emacs by writing > their own Lisp have background in Lisps and other similar languages > where lexical binding is the default? If not, dynamic binding might > be easier to grasp for the newcomers. Lexical scoping is not specific to Lisp or similar languages: it's the scoping supported by virtually all programming languages such as Javascript, Pascal, Fortran, Smalltalk, C, Python, Rust, Java, C#, Clojure, Ruby, Perl, ... The vast majority of those *only* supports lexical scoping. It's dynamic binding which is the odd one out: I can't think of too many languages supporting dynamic scoping other than Scheme, Common-Lisp, Elisp, Logo, sh, and Perl (and maybe Awk tho the doc I can find doesn't make it clear), most of which also support lexical scoping (the only exceptions I know are Logo, sh, and maybe Awk). Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-03-19 19:32 ` Stefan Monnier @ 2018-03-19 19:34 ` Stefan Monnier 2018-03-19 20:10 ` Eli Zaretskii 1 sibling, 0 replies; 40+ messages in thread From: Stefan Monnier @ 2018-03-19 19:34 UTC (permalink / raw) To: Michael Heerdegen; +Cc: 30078 > New patch below. Of course, I got side-tracked and forgot to include the patch. Here it is, Stefan diff --git a/etc/NEWS b/etc/NEWS index 99f3f27486..2d985aab9e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -71,6 +71,10 @@ moved to the early init file (see above). \f * Changes in Emacs 27.1 +** Lexical binding is now used when evaluating interactive Elisp forms +More specifically, lexical-binding is now used for M-:, --eval, as well +as in the *scratch* and *ielm* buffers. + --- ** The new option 'tooltip-resize-echo-area' avoids truncating tooltip text on GUI frames when tooltips are displayed in the echo area. Instead, diff --git a/lisp/ielm.el b/lisp/ielm.el index 59e333f19c..73cf37efbc 100644 --- a/lisp/ielm.el +++ b/lisp/ielm.el @@ -559,10 +559,11 @@ inferior-emacs-lisp-mode ;; Useful for `hs-minor-mode'. (setq-local comment-start ";") (setq-local comment-use-syntax t) + (setq-local lexical-binding t) - (set (make-local-variable 'indent-line-function) 'ielm-indent-line) + (set (make-local-variable 'indent-line-function) #'ielm-indent-line) (set (make-local-variable 'ielm-working-buffer) (current-buffer)) - (set (make-local-variable 'fill-paragraph-function) 'lisp-fill-paragraph) + (set (make-local-variable 'fill-paragraph-function) #'lisp-fill-paragraph) ;; Value holders (set (make-local-variable '*) nil) diff --git a/lisp/server.el b/lisp/server.el index ff03cbe622..a8a82922f5 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -793,7 +793,7 @@ server-eval-and-print ;; intended it to interrupt us rather than interrupt whatever Emacs ;; was doing before it started handling the process filter. ;; Hence `with-local-quit' (bug#6585). - (let ((v (with-local-quit (eval (car (read-from-string expr)))))) + (let ((v (with-local-quit (eval (car (read-from-string expr)) t)))) (when proc (with-temp-buffer (let ((standard-output (current-buffer))) @@ -1315,7 +1315,7 @@ server-execute (find-file-noselect initial-buffer-choice)) ((functionp initial-buffer-choice) (funcall initial-buffer-choice))))) - (if (buffer-live-p buf) buf (get-buffer-create "*scratch*"))))) + (if (buffer-live-p buf) buf (startup--get-buffer-create-scratch))))) ;; Set current buffer so that newly created tty frames ;; show the correct buffer initially. (frame (with-current-buffer (or (car buffers) diff --git a/lisp/simple.el b/lisp/simple.el index fa93cf87c7..f578efb7cb 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1579,12 +1579,12 @@ eval-expression (eval-expression-get-print-arguments current-prefix-arg))) (if (null eval-expression-debug-on-error) - (push (eval exp lexical-binding) values) + (push (eval exp t) values) (let ((old-value (make-symbol "t")) new-value) ;; Bind debug-on-error to something unique so that we can ;; detect when evalled code changes it. (let ((debug-on-error old-value)) - (push (eval (macroexpand-all exp) lexical-binding) values) + (push (eval (macroexpand-all exp) t) values) (setq new-value debug-on-error)) ;; If evalled code has changed the value of debug-on-error, ;; propagate that change to the global binding. diff --git a/lisp/startup.el b/lisp/startup.el index 2669342eda..77d6232924 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1357,7 +1357,8 @@ command-line (if (get-buffer "*scratch*") (with-current-buffer "*scratch*" (if (eq major-mode 'fundamental-mode) - (funcall initial-major-mode)))) + (funcall initial-major-mode)) + (setq-local lexical-binding t))) ;; Load library for our terminal type. ;; User init file can set term-file-prefix to nil to prevent this. @@ -2103,7 +2104,7 @@ normal-no-mouse-startup-screen (insert "\t\t") (insert-button "Open *scratch* buffer" 'action (lambda (_button) (switch-to-buffer - (get-buffer-create "*scratch*"))) + (startup--get-buffer-create-scratch))) 'follow-link t) (insert "\n") (insert "\n" (emacs-version) "\n" emacs-copyright "\n") @@ -2229,6 +2230,13 @@ display-about-screen (defalias 'about-emacs 'display-about-screen) (defalias 'display-splash-screen 'display-startup-screen) +(defun startup--get-buffer-create-scratch () + (or (get-buffer "*scratch*") + (with-current-buffer (get-buffer-create "*scratch*") + (set-buffer-major-mode (current-buffer)) + (setq-local lexical-binding t) + (current-buffer)))) + (defun command-line-1 (args-left) "A subroutine of `command-line'." (display-startup-echo-area-message) @@ -2378,7 +2386,7 @@ command-line-1 (unless (= end (length str-expr)) (error "Trailing garbage following expression: %s" (substring str-expr end))) - (eval expr))) + (eval expr t))) ((member argi '("-L" "-directory")) ;; -L :/foo adds /foo to the _end_ of load-path. @@ -2493,7 +2501,7 @@ command-line-1 (when (eq initial-buffer-choice t) ;; When `initial-buffer-choice' equals t make sure that *scratch* ;; exists. - (get-buffer-create "*scratch*")) + (startup--get-buffer-create-scratch)) ;; If *scratch* exists and is empty, insert initial-scratch-message. ;; Do this before switching to *scratch* below to handle bug#9605. @@ -2512,7 +2520,7 @@ command-line-1 ((functionp initial-buffer-choice) (funcall initial-buffer-choice)) ((eq initial-buffer-choice t) - (get-buffer-create "*scratch*")) + (startup--get-buffer-create-scratch)) (t (error "initial-buffer-choice must be a string, a function, or t."))))) (unless (buffer-live-p buf) diff --git a/lisp/window.el b/lisp/window.el index 8c5e441e4b..3f475ce8ae 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4578,7 +4578,7 @@ last-buffer (or (get-next-valid-buffer (nreverse (buffer-list frame)) buffer visible-ok frame) (get-buffer "*scratch*") - (let ((scratch (get-buffer-create "*scratch*"))) + (let ((scratch (startup--get-buffer-create-scratch))) (set-buffer-major-mode scratch) scratch))) ^ permalink raw reply related [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-03-19 19:32 ` Stefan Monnier 2018-03-19 19:34 ` Stefan Monnier @ 2018-03-19 20:10 ` Eli Zaretskii 2018-03-19 20:50 ` Stefan Monnier 1 sibling, 1 reply; 40+ messages in thread From: Eli Zaretskii @ 2018-03-19 20:10 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Date: Mon, 19 Mar 2018 15:32:23 -0400 > Cc: 30078@debbugs.gnu.org > > lexbind-Elisp language is a strict superset of the > dynbind-Elisp language and for that reason I don't see any reason other > than backward compatibility to keep dynbind-Elisp. > > I'm not trying to fool people by "doing it one subtle step at a time", > I'm only trying to make this switch as painless as possible. I don't > yet have a plan for how we'll get rid of dynbind-Elisp and I'm sure > it'll take many years and several more steps, some of them less subtle > than others. Some of the steps I could imagine introducing in the not > too distant future: > - finish converting all Emacs's .el files to use lexical-binding:t. > - emit a warning when opening an Elisp file which doesn't specify > `lexical-binding:t' in its local vars. > - emit a warning when `eval` is called without a nil 2nd arg. Really? Get rid of dynamic binding in ELisp? Why is that a good idea? It would mean old code will not run in Emacs for no good reason. > It's dynamic binding which is the odd one out Not for me, it isn't. Maybe that means _I_ amd the odd one out. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-03-19 20:10 ` Eli Zaretskii @ 2018-03-19 20:50 ` Stefan Monnier 2018-03-20 6:59 ` Eli Zaretskii 0 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-03-19 20:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, 30078 >> lexbind-Elisp language is a strict superset of the >> dynbind-Elisp language and for that reason I don't see any reason other >> than backward compatibility to keep dynbind-Elisp. >> >> I'm not trying to fool people by "doing it one subtle step at a time", >> I'm only trying to make this switch as painless as possible. I don't >> yet have a plan for how we'll get rid of dynbind-Elisp and I'm sure >> it'll take many years and several more steps, some of them less subtle >> than others. Some of the steps I could imagine introducing in the not >> too distant future: >> - finish converting all Emacs's .el files to use lexical-binding:t. >> - emit a warning when opening an Elisp file which doesn't specify >> `lexical-binding:t' in its local vars. >> - emit a warning when `eval` is called without a nil 2nd arg. > > Really? Get rid of dynamic binding in ELisp? Not sure if by "dynamic binding" you mean "the variant of Elisp corresponding to lexical-binding = nil" (which I call dynbind-Elisp) or "some new Elisp variant where dynamic binding has been removed altogether" (which doesn't currently exist AFAIK). I have no intention to eliminate dynamic binding from Elisp at all. What I'd like to see happen within the next, say, 20 years is to get rid of the `lexical-binding` variable (i.e. treat everything as if this var were always non-nil and as if `eval`s second arg was always non-nil), so that dynamic binding only ever happens for those variables that have been explicitly declared to be dynamic with `defvar` (as is the case in what I call the lexbind-Elisp language). > Why is that a good idea? Because, having two languages is a bit inconvenient and brings extra complexity: e.g. some code snippets only work right in one of the two languages (usually nowadays it's in the lexbind variant, AFAICT), so you need to label them appropriately. > It would mean old code will not run in Emacs for no good reason. That's true. Which is why it's a long-term goal only. Note that it's usually easy to tweak that code to make it work again, tho it is occasionally a bit more painful. And we usually introduce other backward incompatibilities along the way, so it's rather rare for 20 year old Elisp code to still run correctly unmodified. >> It's dynamic binding which is the odd one out > Not for me, it isn't. Maybe that means _I_ amd the odd one out. Beside Elisp, I know you're familiar with at least one other language which only supports lexical scoping: C. What other language(s) do you know/use? Which scoping do they support? Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-03-19 20:50 ` Stefan Monnier @ 2018-03-20 6:59 ` Eli Zaretskii 2018-03-20 19:20 ` Stefan Monnier 0 siblings, 1 reply; 40+ messages in thread From: Eli Zaretskii @ 2018-03-20 6:59 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: michael_heerdegen@web.de, 30078@debbugs.gnu.org > Date: Mon, 19 Mar 2018 16:50:34 -0400 > > > Really? Get rid of dynamic binding in ELisp? > > Not sure if by "dynamic binding" you mean "the variant of Elisp > corresponding to lexical-binding = nil" (which I call dynbind-Elisp) or > "some new Elisp variant where dynamic binding has been removed > altogether" (which doesn't currently exist AFAIK). > > I have no intention to eliminate dynamic binding from Elisp at all. > What I'd like to see happen within the next, say, 20 years is to get rid > of the `lexical-binding` variable (i.e. treat everything as if this var > were always non-nil and as if `eval`s second arg was always non-nil), so > that dynamic binding only ever happens for those variables that have > been explicitly declared to be dynamic with `defvar` (as is the case in > what I call the lexbind-Elisp language). > > > Why is that a good idea? > > Because, having two languages is a bit inconvenient and brings extra > complexity: e.g. some code snippets only work right in one of the two > languages (usually nowadays it's in the lexbind variant, AFAICT), so you > need to label them appropriately. Are that inconvenience and complexity really so bad? They don't sound like that. > > It would mean old code will not run in Emacs for no good reason. > > That's true. Which is why it's a long-term goal only. I'm asking why make it a goal at all. > >> It's dynamic binding which is the odd one out > > Not for me, it isn't. Maybe that means _I_ amd the odd one out. > > Beside Elisp, I know you're familiar with at least one other language > which only supports lexical scoping: C. Global variables in C are very similar to dynamic binding, so I had no problem getting used to ELisp at the time. > What other language(s) do you know/use? Which scoping do they support? Every language I ever used (which is not a lot) supports global variables, so again, no problems in that department. Or maybe I again misunderstand what you mean by "dynbind". Anyway, I don't think it's worth our while to discuss what is or isn't a problem for me personally. The popular style of writing Emacs Lisp nowadays is very different from what it was 20 or 25 years ago, when I learned the language, which is an obstacle to someone like myself, who is not very interested in programming languages and their facilities. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-03-20 6:59 ` Eli Zaretskii @ 2018-03-20 19:20 ` Stefan Monnier 2018-04-02 19:40 ` Richard Stallman 0 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-03-20 19:20 UTC (permalink / raw) To: Eli Zaretskii; +Cc: michael_heerdegen, 30078 >> Because, having two languages is a bit inconvenient and brings extra >> complexity: e.g. some code snippets only work right in one of the two >> languages (usually nowadays it's in the lexbind variant, AFAICT), so you >> need to label them appropriately. > Are that inconvenience and complexity really so bad? They don't sound > like that. It's a source of bugs, slows down the interpreter, complicates the compiler, complicates the doc, regularly confuses new users who copy snippets of code and use them in the wrong language, ... Also several macros need to know if the code they generate will be interpreted in the lexbind-Elisp or the dynbind-Elisp language, so those are also impacted. The clear tendency is for new developments to drop support for dynbind-Elisp whenever it gets in the way (e.g. some macros just signal an error when used from dynbind-Elisp). So dynbind-Elisp is slowly becoming second class citizen. >> > It would mean old code will not run in Emacs for no good reason. >> That's true. Which is why it's a long-term goal only. > I'm asking why make it a goal at all. I guess in the worst case we could keep it indefinitely. But I hope that in the future no code ends up using dynbind-Elisp "by accident". IOW dynbind-Elisp should only be used upon explicit request (e.g. by setting lexical-binding to nil in the file-local vars or by passing a special `:dynbind` second argument to `eval`). Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-03-20 19:20 ` Stefan Monnier @ 2018-04-02 19:40 ` Richard Stallman 2018-04-03 0:12 ` Stefan Monnier 0 siblings, 1 reply; 40+ messages in thread From: Richard Stallman @ 2018-04-02 19:40 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 [[[ 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. ]]] We need dynamic binding to run old programs which were written for it. We must keep it running forever for that reason. Aside from that, I don't see a case where we really need to use it. The 'e' command in the debugger needs to give access to the bindings of the code being debugged -- even if that code uses lexical binding. There are various ways to implement that. How is it implemented now? -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-04-02 19:40 ` Richard Stallman @ 2018-04-03 0:12 ` Stefan Monnier 2018-04-03 16:50 ` Richard Stallman 0 siblings, 1 reply; 40+ messages in thread From: Stefan Monnier @ 2018-04-03 0:12 UTC (permalink / raw) To: Richard Stallman; +Cc: michael_heerdegen, 30078 > We need dynamic binding to run old programs which were written for it. > We must keep it running forever for that reason. In any case, I realized in the mean time that the issue is not so much whether we'll keep this forever for backward compatibility but whether we want to actively discourage its use. > The 'e' command in the debugger needs to give access to the bindings > of the code being debugged -- even if that code uses lexical binding. > There are various ways to implement that. How is it implemented now? It pays attention to the frame in which point is located when you hit `e`, then "unwinds" the bindings on the stack upto that frame temporarily while evaluating the code you typed. That same mechanism happens to work both for the dynamically bound variables and for the lexically bound ones (because the lexical environment is kept internally by the interpreter in a dynamically bound variable). Stefan ^ permalink raw reply [flat|nested] 40+ messages in thread
* bug#30078: 27.0.50; Use lexical-binding for M-: 2018-04-03 0:12 ` Stefan Monnier @ 2018-04-03 16:50 ` Richard Stallman 0 siblings, 0 replies; 40+ messages in thread From: Richard Stallman @ 2018-04-03 16:50 UTC (permalink / raw) To: Stefan Monnier; +Cc: michael_heerdegen, 30078 [[[ 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. ]]] > In any case, I realized in the mean time that the issue is not so much > whether we'll keep this forever for backward compatibility but whether > we want to actively discourage its use. I think we don't need to worry about that in advance. -- Dr Richard Stallman President, Free Software Foundation (https://gnu.org, https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) Skype: No way! See https://stallman.org/skype.html. ^ permalink raw reply [flat|nested] 40+ messages in thread
[parent not found: <mailman.7210.1515688689.27995.bug-gnu-emacs@gnu.org>]
* Re: bug#30078: 27.0.50; Use lexical-binding for M-: [not found] <mailman.7210.1515688689.27995.bug-gnu-emacs@gnu.org> @ 2018-01-12 16:28 ` nazienham 0 siblings, 0 replies; 40+ messages in thread From: nazienham @ 2018-01-12 16:28 UTC (permalink / raw) To: bug-gnu-emacs Hello Madam and Mister. We are lenders who offer loans between individual national and international. You do not have the favor of the banks or you're looking for quick loan in 48 hours. We offer loan if you are able to repay with our interest which is 4% per year, we offer from $ 1000 to $ 800000. We do Hello Madam & Mr. Loans: Individual loan school ready group investment individual investment group thank you madam & Sir for your understanding, for more information contact us by email: nazienham@gmail.com ^ permalink raw reply [flat|nested] 40+ messages in thread
end of thread, other threads:[~2018-04-03 16:50 UTC | newest] Thread overview: 40+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-01-11 16:36 bug#30078: 27.0.50; Use lexical-binding for M-: Stefan Monnier 2018-01-11 20:58 ` Michael Heerdegen 2018-01-12 14:58 ` Stefan Monnier 2018-01-12 16:12 ` Stefan Monnier 2018-01-12 16:53 ` Glenn Morris 2018-01-12 17:23 ` Michael Heerdegen 2018-01-12 18:47 ` Stefan Monnier 2018-01-12 19:35 ` Michael Heerdegen 2018-01-13 17:58 ` Stefan Monnier 2018-01-12 18:34 ` Eli Zaretskii 2018-01-12 18:49 ` Stefan Monnier 2018-01-12 18:55 ` Eli Zaretskii 2018-01-12 19:06 ` Stefan Monnier 2018-01-12 20:03 ` Eli Zaretskii 2018-01-12 20:33 ` Noam Postavsky 2018-01-12 20:55 ` Michael Heerdegen 2018-01-12 21:04 ` Eli Zaretskii 2018-01-12 21:11 ` Michael Heerdegen 2018-01-13 17:50 ` Luis Gerhorst 2018-01-13 19:48 ` Eli Zaretskii 2018-01-13 20:19 ` Luis Gerhorst 2018-01-14 5:58 ` Robert Cochran 2018-01-13 18:19 ` Stefan Monnier 2018-01-13 19:34 ` Eli Zaretskii 2018-01-13 21:58 ` Stefan Monnier 2018-01-13 23:18 ` Richard Stallman 2018-01-14 2:07 ` Drew Adams 2018-01-15 2:34 ` Richard Stallman 2018-01-13 18:05 ` Stefan Monnier 2018-01-13 19:37 ` Eli Zaretskii 2018-03-19 19:32 ` Stefan Monnier 2018-03-19 19:34 ` Stefan Monnier 2018-03-19 20:10 ` Eli Zaretskii 2018-03-19 20:50 ` Stefan Monnier 2018-03-20 6:59 ` Eli Zaretskii 2018-03-20 19:20 ` Stefan Monnier 2018-04-02 19:40 ` Richard Stallman 2018-04-03 0:12 ` Stefan Monnier 2018-04-03 16:50 ` Richard Stallman [not found] <mailman.7210.1515688689.27995.bug-gnu-emacs@gnu.org> 2018-01-12 16:28 ` nazienham
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.