any trick to allow anonymous code blocks in python?

Discussion in 'Python' started by Doug Holton, Jun 25, 2004.

  1. Doug Holton

    Doug Holton Guest

    Is there any metaclass trick or something similar to allow anonymous
    code blocks?

    I'd like to be able to let users do something like this fictitious example:
    b = Button()
    b.OnClick =:
    print "you clicked me"

    But that would require adding a special "=:" operator to bind a code
    block to a function.
    Is there any PEP for something like that? I see 310 might allow:
    b=Button()
    with b.OnClick:
    print "you clicked me"

    I know I can already do it like these examples:
    def OnClick(self,event):
    print "you clicked me"
    b.OnClick = OnClick
    or
    b = Button(OnClick=OnClick)
    or subclassing Button.
    Doug Holton, Jun 25, 2004
    #1
    1. Advertising

  2. Doug Holton

    John Roth Guest

    "Doug Holton" <> wrote in message
    news:...
    > Is there any metaclass trick or something similar to allow anonymous
    > code blocks?
    >
    > I'd like to be able to let users do something like this fictitious

    example:
    > b = Button()
    > b.OnClick =:
    > print "you clicked me"


    No. If you're looking for GUI callbacks, there's a significant
    gap between lambdas and bound methods. You could
    use something like (not tested):

    b.OnClick = (lambda : sys.stdout("You clicked me"))

    which will work (assuming I've got the syntax right).

    If you're doing anything other than a toy program, though,
    the best approach is to wrap the GUI widget in a class,
    and use a bound method of that class for the callbacks.

    The example in the Tkinter chapter of the Python Library
    Reference (16.1.2.2 in the Python 2.3.3 docs) shows
    how to do it. It's amazingly simple, it's completely object
    oriented, and it gives you full access to the instance within
    the callback.

    John Roth
    John Roth, Jun 26, 2004
    #2
    1. Advertising

  3. Doug Holton

    Tyler Eaves Guest

    lambda?
    Tyler Eaves, Jun 26, 2004
    #3
  4. Tyler Eaves wrote:

    > lambda?


    Looks like, since it does not put a name on the
    function. But there is anyway a function object
    created, not just a code object.
    The similar to using an unnamed lambda is
    defining a function, bindin it into some context,
    and deleting it immediately.
    There is no difference, in principle.

    --
    Christian Tismer :^) <mailto:>
    Mission Impossible 5oftware : Have a break! Take a ride on Python's
    Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/
    14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
    work +49 30 89 09 53 34 home +49 30 802 86 56 mobile +49 173 24 18 776
    PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
    whom do you want to sponsor today? http://www.stackless.com/
    Christian Tismer, Jun 26, 2004
    #4
  5. Doug Holton wrote:

    > Is there any metaclass trick or something similar to allow anonymous
    > code blocks?
    >
    > I'd like to be able to let users do something like this fictitious example:
    > b = Button()
    > b.OnClick =:
    > print "you clicked me"


    What exactly do you want to do?
    Why is defining a function too much for you?
    I can't see it is your problem since you are a Python programmer
    (or you would not ask for metaclass tricks) :)

    Looks like a problem with an interface for users.
    Do you want to make the definition
    of actions in a GUI simpler for your users?

    In the latter case, it is probably simplest to define
    a smallish sub-language by a few rules, and create
    proper Python functions at initialization time?

    Feel free to contact me in private email if I'm right.

    ciao - chris

    p.s.: But please give me a real email address. I have no time
    to guess.
    --
    Christian Tismer :^) <mailto:>
    Mission Impossible 5oftware : Have a break! Take a ride on Python's
    Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/
    14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
    work +49 30 89 09 53 34 home +49 30 802 86 56 mobile +49 173 24 18 776
    PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
    whom do you want to sponsor today? http://www.stackless.com/
    Christian Tismer, Jun 26, 2004
    #5
  6. Doug Holton

    Doug Holton Guest

    John Roth wrote:
    >>Is there any metaclass trick or something similar to allow anonymous
    >>code blocks?
    >>

    ....
    > No. If you're looking for GUI callbacks, there's a significant
    > gap between lambdas and bound methods. You could
    > use something like (not tested):
    >
    > b.OnClick = (lambda : sys.stdout("You clicked me"))


    Yeah, I didn't mention the lambda option. I was thinking about
    designing a framework meant for beginners, and I'd rather stay away from
    lambdas. I'm surprised no one is even proposing support for anonymous
    code blocks in Python that support multiple lines, similar to what Ruby,
    Java, and other languages have.

    > If you're doing anything other than a toy program, though,
    > the best approach is to wrap the GUI widget in a class,
    > and use a bound method of that class for the callbacks.


    Right, that is the subclass example I mentioned in the original note,
    but I didn't spell it out:
    class MyButton(Button):
    def OnClick(self,event):
    print "you clicked me"
    b = MyButton()
    I already know that will work, and that is what I would use myself, and
    it is more elegant than lambdas. I was just looking to see if anyone
    had a hack for anonymous code blocks, but thankyou for your help.
    Doug Holton, Jun 26, 2004
    #6
  7. Doug Holton

    Doug Holton Guest

    Christian Tismer wrote:
    > Looks like a problem with an interface for users.
    > Do you want to make the definition
    > of actions in a GUI simpler for your users?


    Right, that is what I was trying to do.

    > In the latter case, it is probably simplest to define
    > a smallish sub-language by a few rules, and create
    > proper Python functions at initialization time?


    That's a great goal, creating a simplified python dialect that can be
    converted to regular Python syntax and bytecode. It's a little outside
    of my reach right now though. And prothon which was mentioned recently
    is incompatible with the python "virtual machine".

    I just saw recently someone made a bytecode hack to allow for decorators
    in Python:
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286147
    and I just thought I'd ask if anyone had done anything similar to allow
    for code blocks, but I guess not. No big deal.
    Doug Holton, Jun 26, 2004
    #7
  8. Doug Holton

    Chris S. Guest

    Doug Holton wrote:

    > Is there any metaclass trick or something similar to allow anonymous
    > code blocks?
    >
    > I'd like to be able to let users do something like this fictitious example:
    > b = Button()
    > b.OnClick =:
    > print "you clicked me"
    >
    > But that would require adding a special "=:" operator to bind a code
    > block to a function.


    Why can't b.OnClick simply be a handle for a function encapsulating that
    statement?

    > Is there any PEP for something like that? I see 310 might allow:
    > b=Button()
    > with b.OnClick:
    > print "you clicked me"
    >
    > I know I can already do it like these examples:
    > def OnClick(self,event):
    > print "you clicked me"
    > b.OnClick = OnClick
    > or
    > b = Button(OnClick=OnClick)
    > or subclassing Button.


    Then what's the problem? wxPython allows you to Bind() functions to
    events. Why obfuscate the code with unnecessary statements?
    Chris S., Jun 26, 2004
    #8
  9. In article <>,
    Doug Holton <> wrote:

    > > b.OnClick = (lambda : sys.stdout("You clicked me"))

    >
    > Yeah, I didn't mention the lambda option. I was thinking about
    > designing a framework meant for beginners, and I'd rather stay away from
    > lambdas. I'm surprised no one is even proposing support for anonymous
    > code blocks in Python that support multiple lines, similar to what Ruby,
    > Java, and other languages have.


    Presumably the right (but non-Python) syntax for such a code block would
    be:

    def b.onClick():
    print "You clicked me"

    One reason for not adding this to Python would be the difficulty of
    determining where the expression for the def'd object ends and where the
    argument list for its definition begins. One could imagine working
    backwards from the colon but I don't think Python's parser can do that,
    and anyway if it's difficult for machines to parse it's also difficult
    for humans to read.

    --
    David Eppstein http://www.ics.uci.edu/~eppstein/
    Univ. of California, Irvine, School of Information & Computer Science
    David Eppstein, Jun 26, 2004
    #9
  10. Doug Holton

    Chris S. Guest

    David Eppstein wrote:

    > In article <>,
    > Doug Holton <> wrote:
    >
    >
    >>>b.OnClick = (lambda : sys.stdout("You clicked me"))

    >>
    >>Yeah, I didn't mention the lambda option. I was thinking about
    >>designing a framework meant for beginners, and I'd rather stay away from
    >>lambdas. I'm surprised no one is even proposing support for anonymous
    >>code blocks in Python that support multiple lines, similar to what Ruby,
    >>Java, and other languages have.

    >
    >
    > Presumably the right (but non-Python) syntax for such a code block would
    > be:
    >
    > def b.onClick():
    > print "You clicked me"
    >
    > One reason for not adding this to Python would be the difficulty of
    > determining where the expression for the def'd object ends and where the
    > argument list for its definition begins. One could imagine working
    > backwards from the colon but I don't think Python's parser can do that,
    > and anyway if it's difficult for machines to parse it's also difficult
    > for humans to read.
    >


    Plus there's little difference between that and:

    def onClick(self):
    print "You clicked me"

    where this is a class method. It's redundant notation and contrary to
    Python's "there should be one-- and preferably only one --obvious way to
    do it" philosophy.
    Chris S., Jun 26, 2004
    #10
  11. Doug Holton

    Mark Hahn Guest

    "Doug Holton" <> wrote

    > That's a great goal, creating a simplified python dialect that can be
    > converted to regular Python syntax and bytecode. It's a little outside
    > of my reach right now though. And prothon which was mentioned recently
    > is incompatible with the python "virtual machine".


    I'm not trolling for Prothon users, since Prothon isn't ready for use
    anyway, but I'm curious why you have to use the Python intepreter. Can you
    fill me in?

    Prothon by the way doesn't have anonymous code blocks, but it can do:

    b = button()
    def b.onClick():
    print "You clicked me"

    Is that what you wanted?
    Mark Hahn, Jun 26, 2004
    #11
  12. Doug Holton

    Doug Holton Guest

    Mark Hahn wrote:
    > Prothon by the way doesn't have anonymous code blocks, but it can do:
    >
    > b = button()
    > def b.onClick():
    > print "You clicked me"


    That's the alternative David Eppstein mentioned, and I like it even
    better than my =: suggestion ( b.onclick =: <code block> ).

    Perhaps that should be a proposal for Python. It's like the decorators
    proposal (318). It just saves an extra step and is helpful for
    framework designers (people who use metaclasses, etc.). Instead of
    having to do this (or the other ways I mentioned):
    def onclick(..):
    ...code here
    b.onclick = onclick

    You can save a step and just do like you said:
    def b.onclick(...):
    ...code here

    Similarly, decorators will save a step: (exact syntax TBD)
    def myfunc (params) [synchronized]:
    ...
    instead of:
    def myfunc (params):
    ...
    myfunc = synchronized(myfunc)


    > I'm not trolling for Prothon users, since Prothon isn't ready for use
    > anyway, but I'm curious why you have to use the Python intepreter.

    Can you
    > fill me in?


    You know better than me, but last I checked, in prothon you can't use
    any of the wealth of python bindings to 3rd-party code libraries.
    Perhaps eventually either prothon could be made compatible with python,
    or SWIG/Boost/Pyrex etc. could be made compatible with prothon so that
    it would be easy for example to compile wxpython for prothon. wxprothon.
    Doug Holton, Jun 26, 2004
    #12
  13. Doug Holton

    Mark Hahn Guest

    Doug Holton wrote:

    > Mark Hahn wrote:
    >> I'm not trolling for Prothon users, since Prothon isn't ready for
    >> use anyway, but I'm curious why you have to use the Python
    >> intepreter. Can you fill me in?

    >
    > You know better than me, but last I checked, in prothon you can't use
    > any of the wealth of python bindings to 3rd-party code libraries.
    > Perhaps eventually either prothon could be made compatible with
    > python, or SWIG/Boost/Pyrex etc. could be made compatible with
    > prothon so that it would be easy for example to compile wxpython for
    > prothon. wxprothon.


    Oh, ok. I thought you meant there was some inherent reason you had to use
    the Python interpreter no matter what.

    When I said Prothon wasn't ready I was including lack of 3rd-party libraries
    as one reason. We hope to have all the big ones on board by early next
    year. SWIG, Boost etc. will be the obvious places to start to get leverage
    on a lot of libs.

    We plan to have wxWidgets (what used to be wxWindows) as our standard GUI
    when we release 1.0 late this year. The only thing keeping it from being
    our standard might be how hard it is to install on Linux.

    In any case we will have our own wrapper for wxWidgets. We hope to have
    cool new wxWidget wrapper features that take advantage of our native OS
    threads and some of our unique language features like functions-as-commands
    and caller access (kind of like macros).

    It's easy to brag about it now. We haven't started on it yet. :)
    Mark Hahn, Jun 26, 2004
    #13
  14. Doug Holton

    Mark Hahn Guest

    Doug Holton wrote:
    > Mark Hahn wrote:
    > > Prothon by the way doesn't have anonymous code blocks, but it can

    > do: >
    > > b = button()
    > > def b.onClick():
    > > print "You clicked me"

    >
    > That's the alternative David Eppstein mentioned, and I like it even
    > better than my =: suggestion ( b.onclick =: <code block> ).


    FYI...

    If you don't need b, you could also do this:

    def button().onClick():
    print "You clicked me"

    If you need b and you want to write compact (some would argue Perl-like)
    code, you could use a new syntax we are debating right now that allows
    assignments-as-expressions with ":=".

    def (b := button()).onClick(): print "You clicked me"

    There are valid non-Perl-like uses for := also. :)
    Mark Hahn, Jun 26, 2004
    #14
  15. Christian Tismer <> writes:

    > What exactly do you want to do?
    > Why is defining a function too much for you?


    One argument for "anonymous functions to be assigned to another
    object" is that defining such functions "pollute" the namespace with
    names that only serve one purpose, yet remain in some scope where they
    are no longer needed unless you delete them.

    def myAction():
    print "You clicked me"

    b.OnClick = myAction

    del(myAction)

    etc.
    Tor Iver Wilhelmsen, Jun 26, 2004
    #15
  16. Doug Holton

    Roger Binns Guest

    Mark Hahn wrote:
    > In any case we will have our own wrapper for wxWidgets. We hope to have
    > cool new wxWidget wrapper features that take advantage of our native OS
    > threads and some of our unique language features like functions-as-commands
    > and caller access (kind of like macros).


    One thing to be aware of is that wxPython actually has a fair amount
    of widgets coded entirely in Python. That means you get to lack
    some of it, or have to re-implement it.

    An example of a nice one is the maskededit. Obviously you won't
    need to duplicate all of them, but they do exist since they were
    useful to enough people for Robin to include them.

    And the biggest issue with wxPython users seems to have been the
    documentation. There are some people who find the C++ derived
    doc as unPythonic and unreadable. Robin has been doing all sorts
    of clever stuff with SWIG to try and make the __doc__ be useful
    although method signatures still aren't (they are all *args, **kwargs).

    It would be interesting to see the Prothon version of the wxPython
    demo. If you were a real masochist you could do one showing the
    Python demo code and the corresponding Prothon demo code side
    by side to demonstrate which one is better :)

    Roger
    Roger Binns, Jun 26, 2004
    #16
  17. Doug Holton

    Peter Otten Guest

    Doug Holton wrote:

    > Is there any metaclass trick or something similar to allow anonymous
    > code blocks?
    >
    > I'd like to be able to let users do something like this fictitious
    > example: b = Button()
    > b.OnClick =:
    > print "you clicked me"
    >
    > But that would require adding a special "=:" operator to bind a code
    > block to a function.
    > Is there any PEP for something like that? I see 310 might allow:
    > b=Button()
    > with b.OnClick:
    > print "you clicked me"
    >
    > I know I can already do it like these examples:
    > def OnClick(self,event):
    > print "you clicked me"
    > b.OnClick = OnClick
    > or
    > b = Button(OnClick=OnClick)
    > or subclassing Button.


    Maybe you can use something as simple as a naming convention, i. e.
    automatically associate a function b1OnClick() with a button b1:

    import types

    class Widget:
    pass

    class Button(Widget):
    def __init__(self, name):
    self.name = name

    def makeMethod(widget, methodname, function):
    setattr(widget, methodname, lambda: function(widget))

    def collectMethods():
    ns = globals()
    widgets = []
    functions = []
    for n, i in ns.items():
    if isinstance(i, Widget):
    widgets.append((n, i))
    elif isinstance(i, types.FunctionType):
    functions.append((n, i))

    for fn, f in functions:
    for wn, w in widgets:
    if fn.startswith(wn):
    makeMethod(w, fn[len(wn):], f)
    break

    #begin client code
    b1 = Button("one")
    b2 = Button("two")
    b3 = Button("three")

    def b1OnClick(self):
    print "you clicked button 1"

    def b2OnClick(self):
    print "you clicked button %s" % self.name

    b3OnClick = b2OnClick
    #end client code

    collectMethods()
    b1.OnClick()
    b2.OnClick()
    b3.OnClick()
    Peter Otten, Jun 26, 2004
    #17
  18. il Sat, 26 Jun 2004 00:58:49 -0500, Doug Holton <> ha
    scritto::

    >Perhaps that should be a proposal for Python. It's like the decorators
    >proposal (318). It just saves an extra step and is helpful for
    >framework designers (people who use metaclasses, etc.). Instead of
    >having to do this (or the other ways I mentioned):
    >def onclick(..):
    > ...code here
    >b.onclick = onclick
    >
    >You can save a step and just do like you said:
    >def b.onclick(...):
    > ...code here
    >


    just my two cents: you can do this in ruby with nearly the same
    syntax:
    def b.onkclick()
    ..code here..
    end

    But even if that sounds like a great idea I have to admit it's not
    widely used, probably because every framework with callbacks like
    these already uses the common bind-a-function-to-this-event idiom,
    instead of allowing method overriding.

    Maybe this relates to the fact that GUI toolkits are mostly C/C++
    based, and that years of limited languages have directed our mind
    toward the 'you have to subclass' dictat. I wonder if SmallTalk GUIs
    have something like this.

    It would be nice to have singleton method definition with this syntax
    in python, anyway.
    gabriele renzi, Jun 26, 2004
    #18
  19. Doug Holton

    Paul McGuire Guest

    > Maybe this relates to the fact that GUI toolkits are mostly C/C++
    > based, and that years of limited languages have directed our mind
    > toward the 'you have to subclass' dictat. I wonder if SmallTalk GUIs
    > have something like this.

    Smalltalk supports inline anonymous code blocks, looking something like:

    mylist sort: [ :a :b | b-a ]

    invokes the sort message on mylist, using a code block with two arguments, a
    and b, using b-a as the comparison (implements a descending order sort).

    -- Paul
    Paul McGuire, Jun 26, 2004
    #19
  20. Doug Holton

    John Roth Guest

    "Doug Holton" <> wrote in message
    news:...
    > John Roth wrote:
    > >>Is there any metaclass trick or something similar to allow anonymous
    > >>code blocks?
    > >>

    > ...
    > > No. If you're looking for GUI callbacks, there's a significant
    > > gap between lambdas and bound methods. You could
    > > use something like (not tested):
    > >
    > > b.OnClick = (lambda : sys.stdout("You clicked me"))

    >
    > Yeah, I didn't mention the lambda option. I was thinking about
    > designing a framework meant for beginners, and I'd rather stay away from
    > lambdas. I'm surprised no one is even proposing support for anonymous
    > code blocks in Python that support multiple lines, similar to what Ruby,
    > Java, and other languages have.


    It's been proposed a number of times, and you can find the
    discussions (some of which amount to flame wars) by searching
    Google Groups.

    IIRC, there are two fundamental issues. One is syntax: it's not easy
    to find a decent syntax that looks good, lets you shift back to statement
    level from expression level, and handles blocks for each parameter
    of a method.

    The other issue is that blocks themselves don't do all that much.
    Ruby's facility with blocks actually comes from the very nice
    intersection of several features, including the pervasive implementation
    of the visitor pattern in all collection objects and the provision of
    a block as a special parameter. There are a couple of other
    features that also help. Blocks without those other features
    wouldn't do what Ruby does.

    The same thing is true of, for example, Smalltalk. Blocks
    have to be seen in the context of the entire language.

    John Roth
    John Roth, Jun 26, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Rivers
    Replies:
    29
    Views:
    829
    Kevin Spencer
    Sep 7, 2005
  2. Jeff
    Replies:
    2
    Views:
    918
    clintonG
    Sep 19, 2006
  3. Ryan Taylor
    Replies:
    1
    Views:
    664
    Ryan Taylor
    Sep 9, 2004
  4. TEN TOD PSA

    TRICK: ASP.NET methods with code blocks

    TEN TOD PSA, Aug 18, 2005, in forum: ASP General
    Replies:
    1
    Views:
    114
    Bob Barrows [MVP]
    Aug 19, 2005
  5. matt
    Replies:
    1
    Views:
    233
    George Ogata
    Aug 6, 2004
Loading...

Share This Page