emacs lisp help

6 views
Skip to first unread message

x3...@my-deja.com

unread,
Feb 1, 2000, 3:00:00 AM2/1/00
to
Hello,

I am trying to get this function to work so that I could use it to
toggle color. I am pasting below session for scratch buffer in emacs.
How do I have color variable to hold previous values?

Thanks.


(defun traffic-light (s)
(lambda (s)
(let ((color "RED"))
(cond
((eq s 'SHOW) (message color))
((eq s 'CHANGE) (if (equal color "RED")

(setq color "GREEN")

(setq color "RED"))))
)))

(setq tl (traffic-light 'SHOW))
(lambda (s) (let ((color "RED")) (cond ((eq s (quote SHOW)) (message
color)) ((eq s (quote CHANGE)) (if (equal color "RED") (setq
color "GREEN") (setq color "RED"))))))

(apply tl '(CHANGE))
(apply tl '(SHOW))
"RED"


Sent via Deja.com http://www.deja.com/
Before you buy.

Barry Margolin

unread,
Feb 1, 2000, 3:00:00 AM2/1/00
to
In article <877k4u$4o7$1...@nnrp1.deja.com>, <x3...@my-deja.com> wrote:
>I am trying to get this function to work so that I could use it to
>toggle color. I am pasting below session for scratch buffer in emacs.
>How do I have color variable to hold previous values?

It looks like you were hoping to create a lexical closure. There are two
problems:

1) Emacs Lisp doesn't implement lexical closures.

2) You didn't do it right. The variable you're closing over has to be
bound *outside* the lambda. In Common Lisp, your function would be:

(defun traffic-light (s)
(let ((color "RED"))
(lambda (s)


(cond ((eq s 'SHOW) (message color))
((eq s 'CHANGE)
(if (equal color "RED")
(setq color "GREEN")
(setq color "RED")))))))

P.S. The right groups for Emacs Lisp questions are comp.emacs or
gnu.emacs.help.

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

x3...@my-deja.com

unread,
Feb 2, 2000, 3:00:00 AM2/2/00
to
Hello,

You are right about closure. Also I was trying to get it to work under
emacs lisp. Now as you said emacs lisp does not support it does that
mean I cannot use it because I heard that emacs support common lisp via
a module called cl.el. should that let me use this function? how?

Thanks.

P.S. I shall ask same in emacs group.

In article <eaJl4.40$xI3.485@burlma1-snr2>,

Tom Breton

unread,
Feb 2, 2000, 3:00:00 AM2/2/00
to
x3...@my-deja.com writes:

> Hello,


>
> I am trying to get this function to work so that I could use it to
> toggle color. I am pasting below session for scratch buffer in emacs.
> How do I have color variable to hold previous values?
>

> Thanks.
>
>
> (defun traffic-light (s)
> (lambda (s)
> (let ((color "RED"))


> (cond
> ((eq s 'SHOW) (message color))
> ((eq s 'CHANGE) (if (equal color "RED")
>
> (setq color "GREEN")
>
> (setq color "RED"))))
> )))

Use the cl package and replace `let' with `lexical-let'.

Also, you want the lexical-let around the lambda expression, not vv.

--
Tom Breton, http://world.std.com/~tob
Not using "gh" since 1997. http://world.std.com/~tob/ugh-free.html

x3...@my-deja.com

unread,
Feb 2, 2000, 3:00:00 AM2/2/00
to
Hello,

Thanks it works fine.

In article <m3zotkp...@world.std.com>,

Stig Hemmer

unread,
Feb 2, 2000, 3:00:00 AM2/2/00
to
x3...@my-deja.com writes:
> You are right about closure. Also I was trying to get it to work under
> emacs lisp. Now as you said emacs lisp does not support it does that
> mean I cannot use it because I heard that emacs support common lisp via
> a module called cl.el. should that let me use this function? how?

Sorry, cl.el does not give you lexical closures.

It only gives you the parts of CL that doesn't conflict too much with
how Emacs-lisp does things.

Lexical closures conflict too much. Packages does too. Not sure what
else is missing.

Stig Hemmer,
Jack of a Few Trades.

Stig Hemmer

unread,
Feb 2, 2000, 3:00:00 AM2/2/00
to
Tom Breton <t...@world.std.com> writes:
> Use the cl package and replace `let' with `lexical-let'.

Ignore my previous note. I was wrong, it seems.

Barry Margolin

unread,
Feb 2, 2000, 3:00:00 AM2/2/00
to
In article <ekv1z6v...@iq.pvv.ntnu.no>,

Stig Hemmer <st...@pvv.ntnu.no> wrote:
>Tom Breton <t...@world.std.com> writes:
>> Use the cl package and replace `let' with `lexical-let'.
>
>Ignore my previous note. I was wrong, it seems.

Be aware that lexical-let is a relatively simple macro that tries to
simulate lexical closures by walking the code looking for references to the
lexical variables and rewriting them, but it doesn't handle some complex
cases. It should work for the original poster's code, though.

Marco Antoniotti

unread,
Feb 3, 2000, 3:00:00 AM2/3/00
to

Stig Hemmer <st...@pvv.ntnu.no> writes:

Not much. What irks me a lot is that some people in Emacs circles,
argue against (require 'cl) on the basis that "it is too big".

Then they re-implement many of the features from cl.el :)

Cheers

--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa

Tim Bradshaw

unread,
Feb 3, 2000, 3:00:00 AM2/3/00
to
* Marco Antoniotti wrote:

> Not much. What irks me a lot is that some people in Emacs circles,
> argue against (require 'cl) on the basis that "it is too big".

They may argeue that way *now*, old hats argue against it because once
upon a time it was so ludicrously buggy that letting it anywhere near
emacs would cause all sorts of mysterious lossage. I think it got
rewritten at some point, but I certainly have an averse reaction to it
still.

--tim

Marco Antoniotti

unread,
Feb 3, 2000, 3:00:00 AM2/3/00
to

Tim Bradshaw <t...@cley.com> writes:

I am talking about the 'rewritten' version, which is very stable and
error free for the use I make of it.

Besides, if you use ILISP, you get (require 'cl) anyway, and I have
*no* intentions to remove the requirement. :)

Gareth Rees

unread,
Feb 3, 2000, 3:00:00 AM2/3/00
to
Marco Antoniotti <mar...@parades.rm.cnr.it> wrote:
> Not much. What irks me a lot is that some people in Emacs circles,
> argue against (require 'cl) on the basis that "it is too big".

It's true that packages in the Emacs distribution aren't allowed
run-time use of the cl package, but the argument isn't about size, it's
about namespaces.

Emacs Lisp doesn't have a proper package mechanism, instead it relies on
packages distinguishing themselves by putting a prefix on all global
symbols; thus all variables and functions in the gnus package start with
'gnus-'. But the cl package doesn't follow this convention -- it uses
the Common Lisp names. So there is understandable concern about name
conflicts between the cl package and user code if the cl package were
loaded automatically by Emacs (there are a lot of Common Lisp functions
and macros that might be prone to these conflicts: push, pop, first,
second, case, values, reduce, fill, etc.). Here Richard Stallman on the
subject (http://www.deja.com/getdoc.xp?AN=562517360&fmt=text):

Emacs packages for "general use" should not require cl at run time.
cl is not a standard part of the Emacs Lisp name space: users can
legitimately define those same names with other meanings. Thus, if a
package loads cl at run time, it could cause a name conflict with the
user's own code.

If you want to make your package convenient for wide use, that is
something to be avoided.

However, even though *runtime* loading of cl is forbidden for packages
in the Emacs distribution, it's OK to do

(eval-when-compile (require 'cl))

This permits use of the cl package macros -- dolist, dotimes, loop,
setf, push, pop, case, typecase, and so on. So you can get a lot of the
syntactic benefit of Common Lisp in Emacs without having to load it at
runtime.

There are dozens of packages in the Emacs distribution that do this.
But on the other hand there are packages like tar-mode, which contains
the following:

;;; First, duplicate some Common Lisp functions; I used to just
;;; (require 'cl) but "cl.el" was messing some people up (also it's
;;; really big).

(defmacro tar-setf (form val) ...)
(defmacro tar-dolist (control &rest body) ...)
(defmacro tar-dotimes (control &rest body) ...)

which really ought to be fixed (I'll submit a bug report).

--
Gareth Rees

Robert Monfera

unread,
Feb 3, 2000, 3:00:00 AM2/3/00
to

Gareth Rees wrote:

> It's true that packages in the Emacs distribution aren't allowed
> run-time use of the cl package, but the argument isn't about size,
> it's about namespaces.

Would it be possible to solve it by introducing packages into Emacs?
Maybe (require 'cl) does this already, as packages are part of the
standard? Non-CL emacs code could sit in their own compatibility
namespace - I don't see why this problem could not be solved has there
been a desire to do so.

Your quote:

;;; First, duplicate some Common Lisp functions; I used to just
;;; (require 'cl) but "cl.el" was messing some people up (also it's
;;; really big).

(defmacro tar-setf (form val) ...)
(defmacro tar-dolist (control &rest body) ...)
(defmacro tar-dotimes (control &rest body) ...)

This is analogous with the Scheme RFIs, where the difference is that CL
features are reimplemented (instead of just using CL) not only because
CL is big, but because it is not elegant :-)

Robert

Marco Antoniotti

unread,
Feb 3, 2000, 3:00:00 AM2/3/00
to

Gareth Rees <garet...@pobox.com> writes:

> Marco Antoniotti <mar...@parades.rm.cnr.it> wrote:
> > Not much. What irks me a lot is that some people in Emacs circles,
> > argue against (require 'cl) on the basis that "it is too big".
>

> It's true that packages in the Emacs distribution aren't allowed
> run-time use of the cl package, but the argument isn't about size, it's
> about namespaces.
>

> Emacs Lisp doesn't have a proper package mechanism, instead it relies on
> packages distinguishing themselves by putting a prefix on all global
> symbols; thus all variables and functions in the gnus package start with
> 'gnus-'. But the cl package doesn't follow this convention -- it uses
> the Common Lisp names. So there is understandable concern about name
> conflicts between the cl package and user code if the cl package were
> loaded automatically by Emacs (there are a lot of Common Lisp functions
> and macros that might be prone to these conflicts: push, pop, first,
> second, case, values, reduce, fill, etc.). Here Richard Stallman on the
> subject (http://www.deja.com/getdoc.xp?AN=562517360&fmt=text):
>
> Emacs packages for "general use" should not require cl at run time.
> cl is not a standard part of the Emacs Lisp name space: users can
> legitimately define those same names with other meanings. Thus, if a
> package loads cl at run time, it could cause a name conflict with the
> user's own code.
>
> If you want to make your package convenient for wide use, that is
> something to be avoided.

I am aware of what RMS says about the (require 'cl) use. He is wrong
(or, better, I politely disagree :) ).

The reason why I disagree is that the Emacs CL package is extremely
careful in avoiding name conflicts, while avoiding the obnoxious 'cl-'
prefix. Instead the CL package uses a less intrusive postfix '*'
notation.

On top of that, IMHO, RMS made a big mistake (again, I respectfully
disagree :) ) by choosing and supporting the idea of Yet Another
Scheme Derivative and Implementation.

> However, even though *runtime* loading of cl is forbidden for packages
> in the Emacs distribution, it's OK to do
>
> (eval-when-compile (require 'cl))
>
> This permits use of the cl package macros -- dolist, dotimes, loop,
> setf, push, pop, case, typecase, and so on. So you can get a lot of the
> syntactic benefit of Common Lisp in Emacs without having to load it at
> runtime.
>
> There are dozens of packages in the Emacs distribution that do this.
> But on the other hand there are packages like tar-mode, which contains
> the following:
>

> ;;; First, duplicate some Common Lisp functions; I used to just
> ;;; (require 'cl) but "cl.el" was messing some people up (also it's
> ;;; really big).
>
> (defmacro tar-setf (form val) ...)
> (defmacro tar-dolist (control &rest body) ...)
> (defmacro tar-dotimes (control &rest body) ...)
>

> which really ought to be fixed (I'll submit a bug report).

Exaclty. And once you loaded a number of
'my-package-redefines-dolist-because-cl-is-too-big-dolist', you
quickly end up with the same space occupancy of the full CL package.

Alas, some constructs are slowly ending up in the main Elisp code base
(WHEN, UNLESS, etc.) But what is really, really missing is DEFSTRUCT.
Hence, I favor (require 'cl) period.

Let's have people should bite the bullet on this. :) I don't want to
be nice here :)

Of course the solution would be to have packages in Emacs, but I am
afraid it will never happen. Or better, it will never happen the
simple way: just implement the CL substrate. Not because the CL
substrate is "the best", but because it is fairly well understood and
well defined.

Gareth Rees

unread,
Feb 3, 2000, 3:00:00 AM2/3/00
to
Marco Antoniotti <mar...@parades.rm.cnr.it> wrote:
> Exaclty. And once you loaded a number of
> 'my-package-redefines-dolist-because-cl-is-too-big-dolist', you
> quickly end up with the same space occupancy of the full CL package.
> [...] what is really, really missing is DEFSTRUCT.

dolist and defstruct aren't problematic: the cl package defines them as
macros, so you only need the cl package at compile time. Many Emacs
packages use dolist.

IMO the CL features whose lack really hurts in Emacs Lisp are the
features that are missing from the cl package -- packages, conditions,
reader macros, the format language.

--
Gareth Rees

Tom Breton

unread,
Feb 3, 2000, 3:00:00 AM2/3/00
to
Stig Hemmer <st...@pvv.ntnu.no> writes:

> Tom Breton <t...@world.std.com> writes:
> > Use the cl package and replace `let' with `lexical-let'.
>
> Ignore my previous note. I was wrong, it seems.

Well, not entirely wrong. Elisp doesn't have native lexical closures,
lexical-let has a macro/gensym trick under the hood.

Tom Breton

unread,
Feb 4, 2000, 3:00:00 AM2/4/00
to
Robert Monfera <mon...@fisec.com> writes:

> Gareth Rees wrote:
>
> > It's true that packages in the Emacs distribution aren't allowed
> > run-time use of the cl package, but the argument isn't about size,
> > it's about namespaces.
>

> Would it be possible to solve it by introducing packages into Emacs?
> Maybe (require 'cl) does this already, as packages are part of the
> standard?

No it doesn't.

> Non-CL emacs code could sit in their own compatibility
> namespace - I don't see why this problem could not be solved has there
> been a desire to do so.

ISTM it would be difficult or impossible to implement packages in
Elisp. You can define more obarrays easily enuff, but making the all
the other code respect them is a whole 'nother matter. If you define
another reader, what happens to code that's already loaded?

So ISTM one would have to add the basic functionality to Emacs itself
(in C).

Tom Breton

unread,
Feb 4, 2000, 3:00:00 AM2/4/00
to
Gareth Rees <garet...@pobox.com> writes:

Packages, yes, painfully missing.

Reader macros are available in Guido Bosch's cl-read. (Does anyone
know where Guido Bosch is nowadays?)

Elisp errors are second-rate conditions.

The byzantine format language in Common Lisp is a pet peeve of mine,
but that's for another thread. I'd just as soon Elisp didn't try to
imitate it. (Using "%" instead of "~" hurts, tho)

Tom Breton

unread,
Feb 4, 2000, 3:00:00 AM2/4/00
to
Tim Bradshaw <t...@cley.com> writes:

> * Marco Antoniotti wrote:
>
> > Not much. What irks me a lot is that some people in Emacs circles,
> > argue against (require 'cl) on the basis that "it is too big".
>

> They may argeue that way *now*, old hats argue against it because once
> upon a time it was so ludicrously buggy that letting it anywhere near
> emacs would cause all sorts of mysterious lossage. I think it got
> rewritten at some point, but I certainly have an averse reaction to it
> still.

You're talking about the old Quiroz version? cl's been rewritten and
stable for some time now. I use it for a lot of things, and have
never seen serious bugs.

There are minor things, of course, like (not a bug, just a
non-feature; it's in the docs) the way it parses keyword arglists so
that the first instance of a key is used regardless whether it's in an
even or odd position, which bit me yesterday, but it's rarely a
problem and easy to write around.

Another minor bug, destructuring doesn't treat dotted lists properly,
so use &rest instead.

I hope this gives you the flavor of how tiny and obscure the problems
are now.

Erik Naggum

unread,
Feb 13, 2000, 3:00:00 AM2/13/00
to
* Robert Monfera <mon...@fisec.com>

| Would it be possible to solve it by introducing packages into Emacs?

I wrote the basics of package support in Emacs Lisp. what we have right
now, however, is only proper support for uninterned symbols. anything
more would require rather massive changes that were deemed inappropriate
at the time. [sorry for the response time.]

#:Erik

Marco Antoniotti

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to

Erik Naggum <er...@naggum.no> writes:

I suppose at the reader level, isn't it?

Erik Naggum

unread,
Feb 15, 2000, 3:00:00 AM2/15/00
to
* Marco Antoniotti <mar...@parades.rm.cnr.it>

| I suppose at the reader level, isn't it?

well, since the package system is basically a reader-level thing to begin
with, naturally, that's where the problems begin, but they don't end
there. Emacs is currently so hard-wired on the "one namespace" idea that
it is intractable to make FOO:BAR and BAR be _perceived_ to be the same
symbol by any code _other_ than the reader, meaning that code that makes
its own symbols needs to be made ware of packages, and code that tries to
write and read back data needs to be very carefully reviewed. I didn't
feel like doing that work.

#:Erik

Reply all
Reply to author
Forward
0 new messages