From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Marius Vollmer Newsgroups: gmane.emacs.devel Subject: Re: Emacs Lisp and Guile Date: 01 Aug 2002 21:39:29 +0200 Sender: emacs-devel-admin@gnu.org Message-ID: References: <200207200035.g6K0ZAb27891@aztec.santafe.edu> <200207212015.g6LKF4c00874@aztec.santafe.edu> <200207251807.g6PI75d07615@aztec.santafe.edu> <874renlito.fsf@zagadka.ping.de> <200207271853.g6RIre710837@aztec.santafe.edu> <200207310554.g6V5ssc16508@aztec.santafe.edu> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1028230841 14561 127.0.0.1 (1 Aug 2002 19:40:41 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Thu, 1 Aug 2002 19:40:41 +0000 (UTC) Cc: neil@ossau.uklinux.net, raeburn@raeburn.org, emacs-devel@gnu.org Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.33 #1 (Debian)) id 17aLoN-0003mk-00 for ; Thu, 01 Aug 2002 21:40:39 +0200 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 17aM7A-0007XQ-00 for ; Thu, 01 Aug 2002 22:00:04 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.35 #1 (Debian)) id 17aLok-0004BU-00; Thu, 01 Aug 2002 15:41:02 -0400 Original-Received: from krusty.dt.e-technik.uni-dortmund.de ([129.217.163.1] helo=mail.dt.e-technik.uni-dortmund.de) by fencepost.gnu.org with esmtp (Exim 3.35 #1 (Debian)) id 17aLoC-000459-00; Thu, 01 Aug 2002 15:40:28 -0400 Original-Received: from burns.dt.e-technik.uni-dortmund.de (burns.dt.e-technik.uni-dortmund.de [129.217.163.19]) by mail.dt.e-technik.uni-dortmund.de (Postfix) with ESMTP id DED83A3831; Thu, 1 Aug 2002 21:40:26 +0200 (CEST) Original-Received: by burns.dt.e-technik.uni-dortmund.de (Postfix, from userid 520) id 55E8F25F3A; Thu, 1 Aug 2002 21:39:29 +0200 (CEST) Original-To: rms@gnu.org In-Reply-To: <200207310554.g6V5ssc16508@aztec.santafe.edu> Original-Lines: 94 User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.1 Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.11 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:6231 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:6231 Richard Stallman writes: > > Scheme variables are normally lexical. What do people normally do in > > Scheme when you want a dynamically scoped value? > > In plain Scheme, you use 'dynamic-wind' to establish a dynamic > context. Entering and leaving that context will run specified > procedures that can swap values in and out of variables that should > have dynamically scoped values. > > It is very undesirable for Lisp dynamic variables to be different > from Scheme dynamic variables. It makes the system specs incoherent. There really aren't dynamic Scheme variables (in the sense that there are dynamic 'special' variables in Common Lisp). The effect where a variable takes on a certain value during an dynamic extent and reverting to its previous value when the context is left is not implemented with a special kind of variable, but with a special control flow construct that allows you to run hooks when a certain dynamic context is entered or left. These hooks can be used to swap the values of a variable. You normally hide these things behind some functions. 'dynamic-wind' is the fundament upon which these functions are built, but it is too clumsy to explicitly use it for dynamically scoped values. For example, there is no visible variable that holds the 'current output port' (the Scheme analogon of C's stdout), but there is a function 'current-output-port' that returns the current output port, and there is a function 'with-output-to-port' that established a new dynamic context in which 'current-output-port' returns the specified port. For example (with-output-to-port (current-error-port) (lambda () (display "Hi\n"))) will output "Hi\n" on the current error port by temporarily switching the current output port to the error port. I don't think this has to be inconsistent with Lisp. What is a typical part of the system specification that makes use of Elisp's dynamic scoping? Maybe I understand you wrong. If you are saying that we should implement Elisp's variables the way Scheme normally mimics dynamic scoping, as opposed to saying that we should add dynamic scoping to Scheme in order to handle the existing Emacs spec, then we have no problem. We already have '@bind' which can be used to implement Elisp 'let' and argument binding for function calls. It will use 'dynamic-wind' as outlined above. > Is it possible to extend dynamic-wind so that it can handle > buffer-local, frame-local, etc. contexts? No, dynamic-wind is only for control flow. Think of it like an extended unwind-protect (where the extension is only useful in the presence of captured continuations). However, we could have something like it for buffer-local contexts, say 'buffer-wind'. That is, we could have a way to specify hooks that are run whenever the value of (current-buffer) changes. The hooks would then install the right values in the variables that are supposed to behave buffer-locally. I'm afraid this might turn out to be expensive and it is not a good solution in a multi-threaded system. I don't know whether you consider making Emacs multi-threaded, but we should keep that option. With something like 'buffer-wind', the values would be swapped at every thread switch. It wouldn't work at all for true concurrent threads. (We are far away from true concurrent thread support in Guile, but we have nice cooperative threading.) What about exporting all Elisp variables to Scheme as settable functions? For example (set! (require-final-newline) 'ask) This would lead to a divergence between Scheme variables and Lisp variables, but I don't think this is bad. > In Guile, we also have 'fluids'. A fluid is a normal object like a > cons pair that holds one object per thread. That is, fluids are our > mechanism for thread local variables. > > Could this be unified with dynamic-wind also? It complements dynamic-wind and works together with it. Fluids provide thread-local storage and dynamic-wind is used to swap values in and out of these locations to establish dynamic contexts. Fluids don't incur an overhead on every thread switch, but on every access. They are meant to be used to implement things like 'current-output-port' in a thread-safe manner. For example, 'current-buffer' could be implemented with a fluid.