From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Pascal J. Bourguignon" Newsgroups: gmane.emacs.devel Subject: Re: lexical-binding defined by the caller not the called? Date: Sun, 28 Apr 2013 21:40:57 +0200 Organization: Informatimago Message-ID: <87ip361m0m.fsf@kuiper.lan.informatimago.com> References: <87a9oisxp5.fsf@ferrier.me.uk> <87txmq27nc.fsf@kuiper.lan.informatimago.com> <8738uasqlk.fsf@ferrier.me.uk> <87ppxe21al.fsf@kuiper.lan.informatimago.com> <87vc76r1d0.fsf@ferrier.me.uk> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1367178082 32643 80.91.229.3 (28 Apr 2013 19:41:22 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 28 Apr 2013 19:41:22 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Apr 28 21:41:26 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UWXTQ-00085o-2t for ged-emacs-devel@m.gmane.org; Sun, 28 Apr 2013 21:41:24 +0200 Original-Received: from localhost ([::1]:53492 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UWXTP-0007ZU-LW for ged-emacs-devel@m.gmane.org; Sun, 28 Apr 2013 15:41:23 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:48670) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UWXTL-0007ZO-6b for emacs-devel@gnu.org; Sun, 28 Apr 2013 15:41:21 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UWXTJ-000667-4r for emacs-devel@gnu.org; Sun, 28 Apr 2013 15:41:19 -0400 Original-Received: from plane.gmane.org ([80.91.229.3]:34699) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UWXTI-00065y-TG for emacs-devel@gnu.org; Sun, 28 Apr 2013 15:41:17 -0400 Original-Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1UWXTC-0007we-Ej for emacs-devel@gnu.org; Sun, 28 Apr 2013 21:41:10 +0200 Original-Received: from 90.24.180.197 ([90.24.180.197]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 28 Apr 2013 21:41:10 +0200 Original-Received: from pjb by 90.24.180.197 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 28 Apr 2013 21:41:10 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 121 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: 90.24.180.197 Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) Cancel-Lock: sha1:YzFhY2M1NjFhYjRjOTIwYzJlZDY5YjlkZTA2NDUyNTM3YWQ2Y2ZmMw== X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 80.91.229.3 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:159199 Archived-At: Nic Ferrier writes: > "Pascal J. Bourguignon" writes: > >> Nic Ferrier writes: > >>> How do I check for lexical-binding then? >> >> Read again the code I posted along. > > I did. I can't see how that shows me how to test lexical-binding though. You keep saying things that are rather meaningless. To test the value of the variable named lexical-binding, you just write lexical-binding in a place in the code where it's evaluated. For example: (insert (if lexical-binding "lexical" "dynamic")) To test whether a variable is a lexical variable or a special variable you can use this macro: (defmacro lexical-variable-p (symbol) `(let ((,symbol t)) (flet ((f () ,symbol)) (let ((,symbol nil)) (f))))) (eval-when (compile load eval) (setf lexical-binding t)) (let ((toto 42)) (list (lexical-variable-p toto) (lexical-variable-p lexical-binding))) ;; --> (t nil) (eval-when (compile load eval) (setf lexical-binding nil)) (let ((toto 42)) (list (lexical-variable-p toto) (lexical-variable-p lexical-binding))) ;; --> (nil nil) Notice that the result is independenant of the setting of lexical-binding at run-time: (eval-when (compile load eval) (setf lexical-binding t)) (let ((toto 42)) (list (lexical-variable-p toto) (lexical-variable-p lexical-binding) (let ((lexical-binding nil)) (list (lexical-variable-p toto) (lexical-variable-p lexical-binding))))) ;; --> (t nil (t nil)) (eval-when (compile load eval) (setf lexical-binding nil)) (let ((toto 42)) (list (lexical-variable-p toto) (lexical-variable-p lexical-binding) (let ((lexical-binding t)) (list (lexical-variable-p toto) (lexical-variable-p lexical-binding))))) ;; --> (nil nil (nil nil)) > It seems like I can't tell if I'm executing in a lexical-binding > environment or not. The dynamic variable named lexical-binding tells you whether the _current_, at the _time_ of execution, "environment" is lexical or not. Of course, this is entirely irrelevant, since at run-time you don't usually load or compile code. But if you do, then lexical-binding tells you whether let will establish lexical variables for new bindings. > I want to be able to write a macro that understands when it is, or is > not, executing code inside a lexical-binding environment. Macros are expanded at compilation time, so again, it's totally unrelated to whatever happens to lexical-binding at run-time. You can just test lexical-binding in the macro: (defmacro m (var init-expr incr-expr) (if lexical-binding `(let ((,var ,init-expr)) (lambda () ,incr-expr ,var)) (let ((unique-var (gensym))) `(progn (setf (symbol-value ',unique-var) ,init-expr) (lambda () (let ((,var (symbol-value ',unique-var))) ,incr-expr (setf (symbol-value ',unique-var) ,var))))))) (eval-when (compile load eval) (setf lexical-binding nil)) (let ((f (m x 0 (incf x)))) (list (macroexpand '(m x 0 (incf x))) (list (funcall f) (let ((x 42)) (funcall f)) (funcall f)))) ;; --> ((progn (setf (symbol-value (quote #1=#:G123027)) 0) ;; (lambda nil (let ((x (symbol-value (quote #1#)))) (incf x) (setf (symbol-value (quote #1#)) x)))) ;; (1 2 3)) (eval-when (compile load eval) (setf lexical-binding t)) (let ((f (m x 0 (incf x)))) (list (macroexpand '(m x 0 (incf x))) (list (funcall f) (let ((x 42)) (funcall f)) (funcall f)))) ;; --> ((let ((x 0)) (lambda nil (incf x) x)) ;; (1 2 3)) -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}.