'build' keyword

4 views
Skip to first unread message

Owen Taylor

unread,
Sep 12, 2011, 7:38:23 PM9/12/11
to reint...@googlegroups.com
build replot.Axes() as p:

Owen Taylor

unread,
Sep 12, 2011, 7:38:57 PM9/12/11
to reint...@googlegroups.com
Sorry about that, accidentally hit send - real version of this message
coming later :-)

On Mon, Sep 12, 2011 at 7:38 PM, Owen Taylor <owta...@gmail.com> wrote:
> build replot.Axes() as p:
>

Owen Taylor

unread,
Sep 12, 2011, 10:52:34 PM9/12/11
to reint...@googlegroups.com
So, returning to a past topic, it's come up that sometimes you want to
do a series of statements with side-effects "at once". With replot:

p = replot.Axes()
p.plot(x, sin(x), 'bo')
p.plot(x, cos(x))
p

works because of some inner logging magic, but that doesn't work well
for a lot of things. For example, from
http://www.reinteract.org/trac/wiki/SidebarDesign, we mght want to do:

surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 200, 200)
cr = cairo.Context(surface)
cr.set_source_rgba(1,1,1) # white
cr.paint()
cr.set_source_rgba(1,1,1) # black
cr.move_to(0, 0)
cr.line_to(100, 100)
cr.stroke()
surface

which not only doesn't work, it isn't natural to write. With
refigure2, Robert came up the idea of doing magic behind the scenes so
that a 'with' statement could magically output as the last thing it
did:

with Figure() as f:
plot(x, sin(x), 'bo')
plot(x, cos(x))

The figure is then output as a "result" of the with statement. Though
I'm not fond of the implicit figure object and the global functions
that act on it, I think that's pretty neat. But the issue is that now
we've made 'with' do something that with doesn't do - have a "return
value" that gets output. It seems to me that if we want to extend
Python it's better to go ahead and /extend/ Python in a clear way -
and indeed, we can do magic at the rewrite step so:

build Figure() as f:
f.plot(x, sin(x), 'bo')
f.plot(x, cos(x))

works without requiring any magic from the implementation of Figure().
This also extends naturally to the idea of a sidebar; since we're now
defining the output before drawing on it, it make sense to support:

build Figure(float=Right) as f:
f.plot(x, sin(x), 'bo')
f.plot(x, cos(x))

so the figure pops up in a sidebar to the right of the worksheet.

Possible variants
=================

* Allow not providing a variable name, and have some default:

build Figure():
_.plot(x, sin(x), 'bo')
_.plot(x, cos(x))

* Make it possible to use a naked build: as a synonym for 'if True'
for grouping side-effectful statements:

build:
f = open("/etc/passwd")
passwords = f.read()
f.close()

* Allow not supplying an initializer but just a name for the case
where the variable can't be allocated up front:

build as passwords
f = open("/etc/passwd")
passwords = f.read()
f.close()

Proof of concept
================

To show that the "magic at the rewrite step" is not an empty claim,
the attached patch makes something like the last variant work, so you
can do:

build passwords
f = open("/etc/passwd")
passwords = f.read()
f.close()
<outputs passwords>

This isn't really saying this is the best variant - I think using 'as'
for naming is likely better, it's just what I happened to have in my
head when I started implementing.

0001-Draft-Add-a-build-keyword.patch

Owen Taylor

unread,
Sep 14, 2011, 8:15:01 AM9/14/11
to reint...@googlegroups.com
I've now pushed a more cleaned up version of the build keyword to Git
- documentation at:

http://git.fishsoup.net/cgit/reinteract/tree/examples/build.rws

I went ahead and implemented most of the possibilities discussed in my
last mail - except for the implicit '_' variable, which seemed more
like Perl than Python.

- Owen

Robert Schroll

unread,
Sep 14, 2011, 10:15:53 PM9/14/11
to reint...@googlegroups.com
On 09/14/2011 08:15 AM, Owen Taylor wrote:
> I've now pushed a more cleaned up version of the build keyword to Git
> - documentation at:
>
> http://git.fishsoup.net/cgit/reinteract/tree/examples/build.rws

This is very cool. Unfortunately, it doesn't work for me with Python
2.6. (I'm guessing you're using 2.7?) The AST for the with statement
is different from the pattern in rewrite.py. I've figured out a fix
works in 2.6 and I think doesn't screw up 2.7, though I haven't tested
that. Here's the bug and the patch:
https://bugzilla.gnome.org/show_bug.cgi?id=659113 It's sort of a
brute-force solution, but I figured this section of the code is
complicated enough without adding more code paths.


>
> I went ahead and implemented most of the possibilities discussed in my
> last mail - except for the implicit '_' variable, which seemed more
> like Perl than Python.

The implicit _ strikes me as too clever, promising to cause confusion.
If you need the build variable, it's not that hard to name it.

Thanks,
Robert

Owen Taylor

unread,
Sep 15, 2011, 7:57:54 PM9/15/11
to reint...@googlegroups.com
On Wed, Sep 14, 2011 at 10:15 PM, Robert Schroll <rsch...@gmail.com> wrote:
> On 09/14/2011 08:15 AM, Owen Taylor wrote:
>>
>> I've now pushed a more cleaned up version of the build keyword to Git
>> - documentation at:
>>
>>  http://git.fishsoup.net/cgit/reinteract/tree/examples/build.rws
>
> This is very cool.  Unfortunately, it doesn't work for me with Python 2.6.
>  (I'm guessing you're using 2.7?)  The AST for the with statement is
> different from the pattern in rewrite.py.  I've figured out a fix works in
> 2.6 and I think doesn't screw up 2.7, though I haven't tested that. Here's
> the bug and the patch: https://bugzilla.gnome.org/show_bug.cgi?id=659113
>  It's sort of a brute-force solution, but I figured this section of the code
> is complicated enough without adding more code paths.

Sorry about that ... glad you figured a way to get it working. We used
to do something like that for Python 2.4 support. (See commit
917ef386a for where it was removed), so I'm not opposed to that kind
of thing, though I'd wonder if we could figure out a way to share the
code and only use different patterns.

I actually started working on a rewrite last night to make rewrite.py
use the ast module rather than the parser module - working with the
abstract syntax tree rather than the raw parse tree. Boy is it simpler
that way! Still a bit from actually trying running it, so I'm not sure
if that's a short term direction or not. If it doesn't work out or is
going to take a while to land, we can definitely go with something
like your patch. If it does work out, we'll probably need some testing
on different Python versions there too, though hopefully it will be
more robust against inter-version differences.

- Owen

Reply all
Reply to author
Forward
0 new messages