LWN.net Logo

PyCon: Evangelizing Python

PyCon: Evangelizing Python

Posted Apr 1, 2013 16:16 UTC (Mon) by kleptog (subscriber, #1183)
In reply to: PyCon: Evangelizing Python by marcH
Parent article: PyCon: Evangelizing Python

Is it possible it's just because there are many people, like me, who don't know lisp and wouldn't know what a "with-statement in lisp" would look like if it stared them in the face. Certainly google isn't returning me any results, I guess they didn't call it the "with-statement" :). Perhaps someone who does know lisp should actually describe what it was the lisp did first.

I hope people aren't just referring to lisp's ability to transform source code at compile time because that (IMO) trivialises what the with-statement adds to the language: the ability to factor out certain idioms that would otherwise require explicit handling of exceptions. There's a difference between "language X makes it possible to do idiom Y" and "language X includes explicit support for idiom X".

While it may be that lisp did it first Python is the only contemporary language I know that includes something like the with-statement, which does say something.


(Log in to post comments)

PyCon: Evangelizing Python

Posted Apr 1, 2013 18:16 UTC (Mon) by nybble41 (subscriber, #55106) [Link]

In Common Lisp the form is known as "unwind-protect" [1], and in Scheme it's "dynamic-wind" [2]. The latter is more complicated because it attempts to handle the case where the inner code is re-entered through a continuation after the cleanup code has already been executed, but the idea is similar.

Both expressions execute a block of code with a guarantee that some other code will be executed when control leaves the block, no matter how that happens (e.g. normal exit, exception, calling a continuation). Operations built on top of this mechanism often start with "with-" by convention, e.g. "with-open-file" (Common Lisp) and "call-with-input-file" (Scheme) both ensure that the file provided to the inner block is closed afterward.

[1] http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node96.html
[2] http://www.schemers.org/Documents/Standards/R5RS/HTML/r5r...

PyCon: Evangelizing Python

Posted Apr 1, 2013 22:57 UTC (Mon) by nix (subscriber, #2304) [Link]

Needless to say, nothing remotely as complicated as the protocols needed in Python to implement 'with' are needed in Lisp. The macro system and unwind-protect/dynamic-wind provides all you need, and implementing new with-*'s is a matter of a few lines of extremely not difficult code. (I emphasise this because macros can often be extremely arcane. Writing a with-blah isn't one of those: the most you have to worry about is a bit of variable capture.)

PyCon: Evangelizing Python

Posted Apr 2, 2013 16:15 UTC (Tue) by lab (subscriber, #51153) [Link]

> Python is the only contemporary language I know that includes something like the with-statement, which does say something

The C# 'using' statement?
http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.110).aspx

PyCon: Evangelizing Python

Posted Apr 2, 2013 17:06 UTC (Tue) by hummassa (subscriber, #307) [Link]

Every single C++ variable initialization is the equivalent to python's with and C#'s using...

PyCon: Evangelizing Python

Posted Apr 2, 2013 17:23 UTC (Tue) by intgr (subscriber, #39733) [Link]

Similar, yes. Equivalent, no.

1. Python's "with" statement is more flexible, it has access to the exception when it occurs. A "with db_transaction():" block can automatically decide to commit or roll back, unlike C++/C#. You can also implement something like "with ignore_exception(OSError):"

2. Python doesn't require you to create a local variable to hold the state; this always annoys me when using the RAII pattern to hold locks in C++.

3. Prettier syntax ;)

PyCon: Evangelizing Python

Posted Apr 2, 2013 19:13 UTC (Tue) by hummassa (subscriber, #307) [Link]

1. std::uncaught_exception() allows for your commit/rollback scenario, but not your ignore_this_exception scenario. The latter does not seem a good idea to me, but...
2. the lock thing can be implicit... it's a matter of how you do it. Anyway,
{
some_lock_t lock(x);
x.do_something();
}
does not seem sooo wrong to me... although I usually put it on X and do
x.do_something_locked<some_lock_t>();
only, or even
some_locking_scaffold(x).do_something();
and this last one is really easy.
3. it's not! :-D

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds