Python syntax in Lisp and Scheme

Daniel P. M. Silva dsilva at ccs.neu.edu
Wed Oct 8 12:50:39 EDT 2003


<posted & mailed>

Alex Martelli wrote:

> Daniel P. M. Silva wrote:
>    ...
>> You still can't add new binding constructs or safe parameterizations like
>> a with_directory form:
>> 
>> with_directory("/tmp", do_something())
>> 
>> Where do_something() would be evaluated with the current directory set to
>> " tmp" and the old pwd would be restored afterward (even in the event of
>> an exception).
> 
> Right: you need to code this very differently, namely:
>     with_directory("/tmp", do_something)
> *deferring* the call to do_something to within the with_directory
> function.  Python uses strict evaluation order, so if and when you
> choose to explicitly CALL do_something() it gets called,
> 
> So, I would code:
> 
> def with_directory(thedir, thefunc, *args, **kwds):
>     pwd = os.getcwd()
>     try: return thefunc(*args, **kwds)
>     finally: os.chdir(pwd)
> 
> this is of course a widespread idiom in Python, e.g. see
> unittest.TestCase.assertRaises for example.
> 
> The only annoyance here is that there is no good 'literal' form for
> a code block (Python's lambda is too puny to count as such), so you
> do have to *name* the 'thefunc' argument (with a 'def' statement --
> Python firmly separates statements from expressions).
 
That was my point.  You have to pass a callable object to with_directory,
plus you have to save in that object any variables you might want to use,
when you'd rather say:

x = 7
with_directory("/tmp",
        print "well, now I'm in ", os.getpwd()
        print "x: ", x
        x = 3
        )

>> Last year -- I think at LL2 -- someone showed how they added some sort of
>> 'using "filename":' form to Python... by hacking the interpreter.
> 
> A "using" statement (which would take a specialized object, surely not
> a string, and call the object's entry/normal-exit/abnormal-exit methods)
> might often be a good alternative to try/finally (which makes no provision
> for 'entry', i.e. setting up, and draws no distinction between normal
> and abnormal 'exits' -- often one doesn't care, but sometimes yes).  On
> this, I've seen some consensus on python-dev; but not (yet?) enough on
> the details.  Consensus is culturally important, even though in the end
> Guido decides: we are keen to ensure we all keep using the same language,
> rather than ever fragmenting it into incompatible dialects.

The point is that the language spec itself is changed (along with the
interpreter in C!) to add that statement.  I would be happier if I could
write syntax extensions myself, in Python, and if those extensions worked
on CPython, Jython, Python.Net, Spy, etc.

> 
> 
>> Some people use Python's hooks to create little languages inside Python
>> (eg. to change the meaning of instantiation), which are not free of
>> problems:
>> 
>> class Object(object):
>>   def __init__(this, *args, **kwargs):
> 
> [invariably spelt as 'self', not 'this', but that's another issue]
> 
>>     this.rest = args
>>     this.keys = kwargs
>> 
>> def new_obj_id(count=[0]):
>>    count[0] = count[0] + 1
>>    return count[0]
>> 
>> def tag_obj(obj, id):
>>    obj.object_id = id
>>    return obj
>>    
>> def obj_id(obj): return obj.object_id
>>    
>> type.__setattr__(Object, "__new__", staticmethod(lambda type, *args:
>> tag_obj(object.__new__(type), new_obj_id())))
>    ...
>> # forgot to check for this case...
>> print Object(foo="bar")
> 
> It's not an issue of "checking": you have written (in very obscure
> and unreadable fashion) a callable which you want to accept (and
> ignore) keyword arguments, but have coded it in such a way that it
> in fact refuses keyword arguments.  Just add the **kwds after the
> *args.  This bug is not really related to "little languages" at all:
> you might forget to specify arguments which you do want your callable
> to accept and ignore in a wide variety of other contexts, too.

I think changing the meaning of __new__ is a pretty big language
modification...

- Daniel




More information about the Python-list mailing list