Could Emacs be rewritten in Python?
Kim Petersen
kp at kyborg.dk
Wed Apr 9 12:06:00 EDT 2003
Alexander Schmolck wrote:
> Kim Petersen <kp at kyborg.dk> writes:
>
>
>>Alexander Schmolck wrote:
>>
>>>Kim Petersen <kp at kyborg.dk> writes:
>>
>> >> (snip)
>>
>>>>function in elisp - do a shallow copy of local variable space (dictionary) and
>>>>send it as the local vars - you can safely throw away the dict after function
>>>>returns).
>>>
>>>Ahem, there are several thousand variables kicking about in global in emacs,
>>>you want to copy them all for each function call?
>>
>>look above - *Local* variable space ... globals stay globals.
>
>
> Maybe we have a misunderstanding.
>
> I thought in your scheme every call to a lisp function foo (from python *or*
> another lisp function) is to be implemented by making a copy of the locals and
> passing it to foo and this copy is discarded after return. If so, this won't
> work (because foo can mess with its callers *locals*; also globals *don't*
> stay globals -- a let binding of a global name means it can no longer be
> globally modified further up the call tree).
No misunderstanding... and possibly not efficient - thats why i said
that you could do push/pop of bindings instead... since then i
remembered that elisp (or any other lisp for that matter *doesn't* have
global variables - so it would be inefficient). But to make it efficient
and usable you can do it with a class instead (that simulates a dictionary):
class Borg: pass
class LispNameSpace:
def __init__(self):
self.nstack=[]
self.vars={}
self.undefined=Borg()
def getcontext(self): return len(self.nstack)
def restorecontext(self,n):
for i in xrange(len(self.nstack),n,-1):
if self.nstack[i][1]==self.undefined:
del self.vars[self.nstack[i][0]]
else:
self.vars[self.nstack[i][0]]=self.nstack[i][1]
def localvar(self,name,value=Null):
if self.vars.has_key(name):
self.nstack.append((name,self.vars[name]))
else:
self.nstack.append((name,self.undefined))
self.vars[name]=value
only thing missing now - is overwriting __getitem__,__setitem__ to do
lookup and set of variables - possibly on failure to find a name in
namespace default down to python namespace - making it really usefull.
implementation of let:
def let(cons,namespace):
# of course a scheme to reasonably map lisp functions to python
# implementations is needed - i just assume that (f x y z) is called
# here as f(lisplist(x,y,z),namespace)
#
context=namespace.getcontext()
defs=cons.car()
body=cons.cdr()
if iscons(defs.car()):
namespace.localvar(defs.car().car(),defs.car().cdr().car())
else:
namespace.localvar(defs.car())
lispeval(body,namespace)
>
> A better example to clarify:
>
> (defun foo()
> (message "when foo is called folding is: %s" case-fold-search)
> (setq case-fold-search :evil))
> (defun bar()
> (message "when bar is called folding is: %s" case-fold-search)
> (let ((case-fold-search t))
> (foo)
> (message "what did foo do to folding? %s!" case-fold-search))
> (message "bar's last folding is: %s again" case-fold-search))
> (defun quux()
> (message "before bar:%s" case-fold-search)
> (bar)
> (message "after bar:%s" case-fold-search))
> (quux)
>
and all this would be handled gracefully.
>
> before bar:nil
> when bar is called folding is: nil
> when foo is called folding is: t
> what did foo do to folding? :evil! ;; !!!
> bar's last folding is: t again
> after bar:nil
>
> Tell me if you think this would work, too and I'll just reread your message.
Yep it will - and no need to look back - i think i clarified?
>
>
> 'as
More information about the Python-list
mailing list