From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Andy Wingo Newsgroups: gmane.lisp.guile.devel Subject: elisp glimpses Date: Sun, 01 Aug 2010 13:27:18 +0200 Message-ID: References: <87mxuutd12.fsf@lupus.terpri.org> <87d3upe1nm.fsf@lupus.terpri.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1280682458 5842 80.91.229.12 (1 Aug 2010 17:07:38 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sun, 1 Aug 2010 17:07:38 +0000 (UTC) Cc: guile-devel To: Brian Templeton Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sun Aug 01 19:07:36 2010 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1OfbzY-0004lL-Fg for guile-devel@m.gmane.org; Sun, 01 Aug 2010 19:07:36 +0200 Original-Received: from localhost ([127.0.0.1]:48597 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OfbzR-0002Bm-RF for guile-devel@m.gmane.org; Sun, 01 Aug 2010 13:06:21 -0400 Original-Received: from [140.186.70.92] (port=52464 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OfbSg-0003u9-Au for guile-devel@gnu.org; Sun, 01 Aug 2010 12:32:33 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OfWfb-0001MC-BR for guile-devel@gnu.org; Sun, 01 Aug 2010 07:25:32 -0400 Original-Received: from a-pb-sasl-quonix.pobox.com ([208.72.237.25]:59393 helo=sasl.smtp.pobox.com) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OfWfb-0001Gj-6f for guile-devel@gnu.org; Sun, 01 Aug 2010 07:25:31 -0400 Original-Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id 1A2BBC9CE2; Sun, 1 Aug 2010 07:24:29 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=CS467nBHMFOwnGVvxrKT/KfPJyU=; b=GwBd6d dwUn6p8ZrI7sOtpRmJTvRUvv0AjTmYQ0dO8swB6803dCiD73Flfy10S9D8Xrt0kk nGRZyXiN18Jxq3q+oMBqMeR3R0zPGl/puZkB4Oqy7dOUINPcq86q/rXBnmi00aM6 v6iv9mCPdST4ga5pxiLf1Vc4J9SsjHkXxXU/k= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=nLqCR7cRwqrJVH+qGqpJY8GKFlZRZU/5 izMTn2IeKO7ZG9lLiKITg5hYr2md0ppEJ+dy/4kcfrsiiu/wwxNNBqxfKynhg/46 /d6D3rEYzOHpZh7aqYZksv62+RcfzX0/hWqdbJ/YsCisKDLDLSEgnzRQjOousm4j vADOkRViuUI= Original-Received: from a-pb-sasl-quonix. (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id 047E7C9CE1; Sun, 1 Aug 2010 07:24:28 -0400 (EDT) Original-Received: from unquote.localdomain (unknown [83.44.189.117]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTPSA id 0655EC9CDF; Sun, 1 Aug 2010 07:24:25 -0400 (EDT) In-Reply-To: <87d3upe1nm.fsf@lupus.terpri.org> (Brian Templeton's message of "Thu, 15 Jul 2010 01:48:13 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) X-Pobox-Relay-ID: 58AC96A4-9D5F-11DF-B694-9056EE7EF46B-02397024!a-pb-sasl-quonix.pobox.com X-detected-operating-system: by eggs.gnu.org: Solaris 10 (beta) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:10750 Archived-At: Hello! Sorry for the delay, I got swamped with the GHM. Which was cool! But distracting :) I'm copying the list on my answer; hope you don't mind. On Thu 15 Jul 2010 07:48, Brian Templeton writes: > I've started pushing stable patches into the 'bpt/elisp' branch of > Cool. I like it. I like defspecial. A couple things: * If pmatch doesn't match, it's not an error. It's more like cond not matching. You need to add an error case. Probably best to make an amatch macro that uses pmatch or something, and ensures there is an error case. * The quasiquote stuff is incredibly ugly. Why is ` not a reader macro? If it has to be like it is, OK, but why not expand to the more schemely quasiquote, unquote, and unquote-splicing? > At the moment I'm rebasing to master frequently OK, cool. > * Multi-cell symbols and module system integration Hmmm, very good questions. Currently of course there is no module system in Elisp, so to a large degree we can punt on this, but it would be good to have an answer for the future. Other questions that would have to be answered at the same time: * What is the default elisp module called? * Do Guile modules and Elisp modules share a namespace? * What does it mean to import a module in Elisp? Is the import restricted to the importing file, or does it import into the global namespace? Or, can you only import a module when defining a new module? * Is it even a good idea to give Elisp a module system, or should that only be available from Scheme? > Currently Elisp symbols are Scheme symbols, and their value and function > cell contents are looked up in submodules of (language elisp runtime). > This works well enough for now, but it will get quite ugly if Elisp is > ever integrated with Guile's module system to any degree. Every module > containing Elisp function bindings might need to have a 'function-cell' > submodule, for example; an uninterned symbol could be used to avoid name > clashes, but it would still pollute the namespace. It would be cleaner > to maintain multiple hash tables in every module, and then e.g. (@ > (emacs) set-buffer function) could refer to the function binding. > > But here's another alternative: Guile already has function and plist > slots in symbols, so clearly it's okay to waste a few bytes for features > nobody uses. (: Why not keep the extra cells in variable objects, or in > a new type of variable object? (I call this option "big variables" or > "bigvars".) Guile's double cells are just the right size; there's enough > room for a function cell as well as a pointer to a properties object, > which would contain the plist cell and implementation-internal > annotations. I've implemented the (trivial) libguile side of this, but > at least Tree-IL, the module system, and the VM would also need to be > modified to support this, if it's even a good idea. Hmmm. Yes, I think this is a good idea. Does it make sense to be a subtype of variables -- that is, with the same tc7, but with a flag in the first word? Then we could make Guile's variables all be treated as having a value binding already. Perhaps the new variable-function-ref / toplevel-function-ref / etc opcodes (you are adding them, yes? :) should return the value if it's a narrow variable holding a procedure. We would need toplevel-value-define / toplevel-function-define as well, to ensure that the binding is a wide variable. But also... we should think about threads here. Elisp doesn't have flet, right? So perhaps the default binding of a narrow var should be a function binding, or something; and then we can guarantee that the third word of a wide var is a fluid. Then a toplevel-value-ref can cache the fluid instead of the var, and we get thread-local bindings for free. I'm being brief here; let me know if I'm not being clear. When you add this, please make your patches small, correct, and orthogonal :) > Also, Elisp really needs a package system, not a module system -- in the > context of Guile Emacs Lisp that probably means having a "packaged > symbol" type that refers to an (unpackaged) symbol in the context of a > specific module. (This is only necessary if Elisp is going to have some > level of integration into the module system, of course.) Guile appears > to handle imported bindings in some way less direct than storing the > other module's variable object in the obarray, so it can even work as > required for CL's `symbol-package', etc. (although who knows what > `symbol-name' on an imported and renamed symbol would actually mean) Hm. Well, Guile's symbols do have four words, and space for some flags. It's a bit ridiculous really, looking at the code now -- every time you make a symbol you cons an extra pair too. I would prefer to have symbols only be two words, and the stringbuf in the second word should have a hash inside it. This would be advantageous for hash maps with string keys too. Then symbol properties could be implemented with a weak map. That way the deprecated features pay their own way, and symbols are lighter. But, I digress. I don't really know what a packaged symbol is. Is it a separate data type from a "normal" symbol? Could we pull similar narrow-vs-wide subtyping tricks, perhaps? Maybe that is the best option. > * Aliases > > Elisp has both defalias and defvaralias. My first thought was to assign > the same variable object to multiple names in an obarray; that works for > the submodule-based implementation of symbol cells currently used, but > not for the bigvars implementation. It would be useful to have a special > object like SCM_UNDEFINED to mark cells to be redirected, but if that's > not practical, redirected cells can remain SCM_UNBOUND, redirection > information information can be stored in the property cell, references > to aliases can be processed in an error handler, and Elisp setq can > check the property cell for every assignment. I think I'll implement a > proper def(var)alias next; subr.el and other basic libraries load with > defalias = fset, but Emacs implements buffer- and frame-local variables > using a similar technique so this will make it easier to implement that > when it becomes necessary. Yes, I don't know how to do this nicely. Redirection is not so nice. Necessary perhaps, though... > * Performance > > The only real optimization I've added so far has been to introduce > 'unbound fluids,' by analogy with unbound variables; with this change, > TAK is 3.7x slower in Guile Elisp than in Emacs, vs. 4.8x slower > without. (And Guile Scheme is about twice as fast as GNU Emacs Elisp.) Well, good to have these numbers. I think caching the fluids in functions' object tables for lexical variable access will be the real "equalizer", so to speak; but that's just a guess. > think Guile Elisp could get away with using lexical function bindings > while remaining technically compatible with GNU Emacs Elisp, but cl.el's > CL-incompatible `flet' simulates dynamically scoped function bindings -- > which don't even exist in standard CL! I may be missing something > obvious, but I can't think of an efficient way to dynamically shadow the > value of a globally lexical variable. What does "globally lexical" mean? There are certainly a number of cases in which we can prove that a variable reference may be lexical, and not dynamic. E.g. in (defun foo (bar) bar) `bar' may be lexically accessed, and no fluid need be set. But in: (defun foo (bar) (baz bar)) We may access the `bar' binding lexically, but we still have to include a dynlet in the generated code. Actually I don't see a make-dynlet or the like in the compiler code; surely an oversight? > * Nil > > My initial inclination was to remove #nil entirely and to simply use the > symbol `nil' as Elisp's EOL and false. I now think it's probably worth > keeping it since it would be useful for a Common Lisp implementation. > Note that (symbol? #nil) => #f in Scheme and (symbolp nil) => nil in > Elisp, when it will eventually need to be true in at least the latter > case. But I would guess that, for symbols, only the type and equality > predicates need to be especially fast, so I think it's okay to just > special-case these in the Elisp symbol functions, even though it's an > ugly hack. The fact that t and nil are symbols for the purpose of elisp is really going to bite us at some point, I think... We can get it right but there will be a number of bugs along the way I think. > * Where should I put Elisp files to be packaged with Guile? (I'm writing > most new subrs in Elisp -- ideally all subrs should be in Elisp and > all macros should be loaded from the Emacs source.) Just under > "module/language/elisp"? It seems odd to put them under the module > directory since, well, they're not modules, but that's what gets > installed to /usr/share/guile... Sure, that sounds fine to me, for now at least. > * The Tree-IL program `(begin)' does not compile. Is it supposed to be a > valid program? No, this is not a valid program. Tree-IL's begin is a sequencing operator, not a splicing operator -- you need 1 or more expressions to sequence. Happy hacking, Andy -- http://wingolog.org/