Some language proposals.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Anton Vredegoor

    #16
    Re: Some language proposals.

    Antoon Pardon <apardon@forel. vub.ac.be> wrote:
    [color=blue]
    >I don't see much difference between a function changing a higher up
    >variable that is global or just in between.[/color]

    If you want a function with its own namespace, that is already
    possible as you showed yourself in an earlier post. On the other hand,
    if a function has its own namespace what is the difference between a
    function and a class? Why not use a class in the first place?

    Remember that "global" is just a way for a function to tell the
    interpreter that this variable belongs to the global namespace.

    There is some inconsistency if one has a function inside a function
    and that function has a global 'x' but the outer function doesn't have
    a global 'x'. Modifications of 'x' from the deepest function do not
    reach the global namespace, in fact they do not even reach the
    namespace of the containing function.

    Only if both functions have a global 'x' the name is visible at the
    global and intermediate level.

    However there is already a mechanism to solve these kind of problems:
    namespaces! Why not use them?
    [color=blue][color=green]
    >> a,b = A.a,A.b[/color]
    >
    >Well maybe my wording was off, but this doesn't accomplisch what I
    >want since after your statement followed by: a = new_value; A.a will
    >not be changed.[/color]

    For that to work you'd have to imbue names with new magical powers.
    They would have to have some way of knowing who their fellow holders
    are with whom they share their objects and inform them about their new
    responsibilitie s.

    The fellow objects would need some instructions as to how to handle
    such things. Should they hold on to their previous bindings or let go
    and use the new objects? Maybe some automatic message passing between
    objects "behind the covers" would be necessary. Maybe it's a great
    idea or maybe we would get hit over the head with a stick. I don't
    know.

    By the way, would it then be really, really black magic to be able to
    call an object by its *real* name and force all holders to obey? One
    ring to rule them all!

    .... much, much, later ...

    Message from your Atoned Governor.

    Ok, after finally having relinquished the ring of power and freely
    dropping it into the crater, I would like to make a public
    announcement.

    It is a really bad idea to indiscriminatel y rip the structure and
    inner cohesion and the "whole is more than the sum of the parts"
    quality of existing cooperations of objects apart in order to gain
    access to a little trinket, and from now on I will desist from such
    actions until there is a way to replace the lost objects with
    functionality that is the same or better, according to the judgement
    of said cooperations, in order not to disrupt working ecosystems.

    Anton

    Comment

    • Paul Prescod

      #17
      Re: Some language proposals.

      Jacek Generowicz wrote:
      [color=blue]
      > Paul Prescod <paul@prescod.n et> writes:
      >
      >[color=green]
      >>I disagree. Closures are rare in Python because Python is primarily an
      >>OOP language.[/color]
      >
      > I disagree, Python is a multi-paradigm language ...[/color]

      In Python functions are objects but objects are not functions. In (e.g.)
      Scheme the opposite is true.
      [color=blue]
      > ... I fail to see how
      > this has any bearing on the use of closures ... all of which is
      > irrelevant to my original point, which was to note out that saying
      > "people don't use it much" is not a very convincing argument for not
      > fixing something that is broken ... because the very fact that it is
      > broken probably contributes to people not using it much.[/color]

      But the more important point is that people do not NEED it much. Guido
      writes hundreds of lines of Python code per week. If he often ran into
      situations where a mutable closure would make a big difference then he
      would presumably find some way of doing it. The people who want this
      seem most often to be people trying to import their coding styles from
      another language.

      Paul Prescod



      Comment

      • Paul Prescod

        #18
        Re: Some language proposals.

        While I'm thinking about it, let me refute your Sapir-Wharf claim (BTW,
        its been pretty widly debunked in linguistics)

        Before Python had nested scopes at all, it was VERY common to fake them
        using a linguistic trick: default arguments. This idiom was very common
        in Python's source base. Python didn't have a proper way to do the
        nesting but people figured out how to do it anyway and did it a LOT.
        (similarly people often emulate OO in C)

        The "wrap your mutables" feature is by comparison _much less intrusive_
        but I don't ever see it in real Python code. This suggests to me that
        people don't need the feature that badly.

        Jacek Generowicz wrote:
        [color=blue]
        >...
        > And using objects (err ... instances of classes) to fake stateful
        > functions sucks just as much.[/color]

        Let's step above the words "function" and "object" for a second.
        Sometimes you need to combine mutable state and code into a single unit.
        Python has a first-class feature for doing that: the object. That's the
        implementation of the requirement.

        But you are expressing an _implementation _ as a _requirement_. "I need a
        combination of state and data and it must be a function." Why?
        [color=blue]
        > Sure. I have some stateful methods of classes (which I create
        > dynamically and stick onto the class as the information about the
        > existence of the method becomes available).[/color]

        Why are the METHODS stateful rather than keeping their state in the
        class? If I had to maintain your code I would much rather that you keep
        state in the same place all the other Python programmers do.

        But if you must do this then use the well-known mutable closure hack.
        It'll take you just a few extra characters of code. When we start seeing
        dozens or hundreds of people making use of it then we'll know the
        community really needs it (and isn't just trying to turn Python into
        Lisp for its own sake).
        [color=blue]
        > ... By implementing them as
        > closures I can just stick them on to the class. If I were to implement
        > them as instances then I'd have to reimplement all the descriptors
        > that take care of turning functions into bound or unbound methods.[/color]

        Or you could wrap them in functions.

        inst = Class()

        someclass.metho d = lambda x, *args, **kwargs: inst(*args, **kwargs)

        You've cleverly found one of the very few places where Python
        distinguishes between "true" functions and callable objects. If one is
        looking at the overall Python system, the bug is in the way functions
        are bound. In general, Python very seldom distinguishes between objects
        based on type (rather than behaviour) and in particular, seldom
        distinguishes between functions and callable objects.

        I would argue that classes should distinguish between
        attributes-to-be-treated-as-methods and
        attributes-to-be-treated-as-just-attributes using something other than
        type. Consider the following program:

        class a:
        pass

        def func():
        pass

        lst = [1, 2, 3, "a", "b", "c", object(), lambda x:x ]

        for x in lst:
        a.b = x
        assert a.b is x, "What???? %s"% x
        print "Okay", x

        Frankly I think it is unpythonic that a second after assignment to a.b
        the thing I get back is different than the thing I put in.

        But now we're talking about a pretty subtle bug that has been in Python
        for over ten years and it so seldom bites anyone that it is probably nto
        worth fixing. (if I were to fix it I would add an add_method method to
        classes)
        [color=blue]
        > Another example. I make quite heavy use of a trivial memoizer. The
        > closure verison is much shorter, clearer and faster.[/color]

        Well it boils down to a question of who would believe it is clearer.
        Lisp programmers think mutable closures are clearer. Perl programmers
        think having a variety of different ways to spell "if" is clearer than
        having just one. Part of the Zen of Python is try to encourage different
        camps towards common spellings of idioms.

        bash-2.05a$ python -c "import this" | grep way
        There should be one-- and preferably only one --obvious way to do it.
        Although that way may not be obvious at first unless you're Dutch.
        [color=blue]
        > In short, whenever I want a _function_ which happens to have some
        > internal state, I'd much rather use a closure than an instance of a class.[/color]

        Barring the one ancient design misfeature above, callable instances are
        almost always good replacements for functions.
        [color=blue][color=green][color=darkred]
        >>>all of which is irrelevant to my original point, which was to note
        >>>out that saying "people don't use it much" is not a very convincing
        >>>argument for not fixing something that is broken ...[/color]
        >>
        >>OK, how about the argument above?[/color]
        > ...[/color]

        OK, how about the argument at the top? If people needed it they would
        fake it as they do many other missing feature (in Python and other
        languages). That they don't fake it despite how easy it is to do so
        indicates that they don't need it.

        Paul Prescod



        Comment

        • Michael Hudson

          #19
          Re: Some language proposals.

          Jacek Generowicz <jacek.generowi cz@cern.ch> writes:
          [color=blue]
          > Michael Hudson <mwh@python.net > writes:
          >[color=green]
          > > Jacek Generowicz <jacek.generowi cz@cern.ch> writes:
          > >[color=darkred]
          > > > Paul Prescod <paul@prescod.n et> writes:
          > > >
          > > > > I disagree. Closures are rare in Python because Python is primarily an
          > > > > OOP language.
          > > >
          > > > I disagree, Python is a multi-paradigm language ... I fail to see how
          > > > this has any bearing on the use of closures ...[/color]
          > >
          > > Really? Paul is saying "if you are in a situation in Python where you
          > > want to use a read-write closure, you'll probably be happier if you
          > > use an object-based solution instead".
          > >
          > > Now you may *disagree* with this point, but I find it hard to believe
          > > you don't *see* it.[/color]
          >
          > Aaah, OK, _if_ you think that closures are _only_ a way of faking
          > objects, _then_ claiming that Python is primarily OO does have a
          > bearing on the use of closures. Forgive me for not pursuing
          > this tangent any further.[/color]

          OK, you really hadn't seen this argument before. You must be new here
          :-) (or at least, new to this particular dispute).
          [color=blue][color=green]
          > > Using closures to fake objects sucks (in scheme or CL as much as in
          > > Python).[/color]
          >
          > And using objects (err ... instances of classes) to fake stateful
          > functions sucks just as much.[/color]

          Hmm. Really? I'm not sure that I often find myself wanting a
          "stateful function". I think I probably usually use bound methods.
          This could be the tail wagging the dog, of course.
          [color=blue]
          > When I need "objects" I use objects, and when I need closures I want
          > to be able to use closures.[/color]

          So could this :-)

          (trivially, you never *need* closures, just the same as you don't
          *need* objects, there's a rather dull and unhelpful isomorphism
          between the two concepts).
          [color=blue][color=green]
          > > Can you post an example of using a read-write closure that you think
          > > wouldn't be better off as an object (invent syntax as necessary...).
          > > No-one was very convincing at this last time it went around on
          > > python-dev.[/color]
          >
          > Sure. I have some stateful methods of classes (which I create
          > dynamically and stick onto the class as the information about the
          > existence of the method becomes available). By implementing them as
          > closures I can just stick them on to the class. If I were to implement
          > them as instances then I'd have to reimplement all the descriptors
          > that take care of turning functions into bound or unbound methods.[/color]

          Which isn't that hard... I think a code example might lend a bit more
          clarity.
          [color=blue]
          > [At this point I'd love someone to step up and show me how to re-use
          > the existing FunctionType descriptors in my own classes.][/color]

          Post some code, and I'll have a go.
          [color=blue]
          > Another example. I make quite heavy use of a trivial memoizer. The
          > closure verison is much shorter, clearer and faster.[/color]

          I'll grant you this: I've done the same.
          [color=blue]
          > (I want it to be writeable because I sometimes want to 'prime' the
          > cache, or do other things to it ... so I'm giving myself access to
          > the cache by binding the cache as a function attribute of the
          > closure, before returning it from the memoizer)[/color]

          Um, here, unless I misunderstand you, you don't want to mutate the
          closed over binding (which is what Python currently doesn't let you
          do) but mutate the object the closed over binding is bound to. In
          this respect, Python is no different from anything else, you need to
          arrange some way to expose said object outside the closure.

          What am I missing?
          [color=blue]
          > In short, whenever I want a _function_ which happens to have some
          > internal state, I'd much rather use a closure than an instance of a
          > class.[/color]

          Maybe, once you've been assimilated into the Python Borg mindset, you
          don't, actually.

          There are sort of two extreme possibilities here:

          1) I am so blinded by the fact that I know Python as of 2.3 FAR better
          than any other language that I don't see how wonderful Python would
          be if "full closures" were added.

          2) Full closures just aren't that appropriate to Pythonic programming.

          The truth, almost certainly, is somewhere in between these points.
          [color=blue][color=green][color=darkred]
          > > > all of which is irrelevant to my original point, which was to note
          > > > out that saying "people don't use it much" is not a very convincing
          > > > argument for not fixing something that is broken ...[/color]
          > >
          > > OK, how about the argument above?[/color]
          >
          > My original point, although prompted in a context which discussed
          > closures, in independent of closures.[/color]

          Fine. Let's have a real argument instead :-)

          Cheers,
          mwh

          --
          Never meddle in the affairs of NT. It is slow to boot and quick to
          crash. -- Stephen Harris
          -- http://home.xnet.com/~raven/Sysadmin/ASR.Quotes.html

          Comment

          • Aahz

            #20
            Re: Some language proposals.

            In article <tyfwu6bmfhx.fs f@pcepsft001.ce rn.ch>,
            Jacek Generowicz <jacek.generowi cz@cern.ch> wrote:[color=blue]
            >
            >Sure. I have some stateful methods of classes (which I create
            >dynamically and stick onto the class as the information about the
            >existence of the method becomes available). By implementing them as
            >closures I can just stick them on to the class. If I were to implement
            >them as instances then I'd have to reimplement all the descriptors
            >that take care of turning functions into bound or unbound methods.[/color]

            Why not use callable instances?
            --
            Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

            "Do not taunt happy fun for loops. Do not change lists you are looping over."
            --Remco Gerlich, comp.lang.pytho n

            Comment

            • Josiah Carlson

              #21
              Re: Some language proposals.

              Paul,

              Your outputs were all incorrect.
              [color=blue][color=green]
              >> Could somebody point me to an explanation of why closures are broken
              >> in this way in the first place, please ?[/color]
              >
              >
              > a = 5
              > def b():
              > a = 6
              > print a
              > b()
              > print a
              >
              > What will this print?
              >
              > 5
              > 6[/color]
              [color=blue][color=green][color=darkred]
              >>> a = 5
              >>> def b():[/color][/color][/color]
              .... a = 6
              .... print a
              ....[color=blue][color=green][color=darkred]
              >>> b()[/color][/color][/color]
              6[color=blue][color=green][color=darkred]
              >>> print a[/color][/color][/color]
              5

              [color=blue]
              > Okay, then.
              >
              > a = 5
              > def b():
              > a = 6
              > def c():
              > a = 7
              > print a
              > print a
              > c()
              >
              > print b()()
              > print a
              >
              > What does this print?
              >
              > 7
              > 6
              > 5[/color]

              What you give doesn't work, here's a slight modification:
              [color=blue][color=green][color=darkred]
              >>> a = 5
              >>> def b():[/color][/color][/color]
              .... a = 6
              .... def c():
              .... a = 7
              .... print a
              .... print a
              .... return c
              ....[color=blue][color=green][color=darkred]
              >>>
              >>> b()()[/color][/color][/color]
              6
              7[color=blue][color=green][color=darkred]
              >>> print a[/color][/color][/color]
              5


              I don't know what you were trying to prove, but next time, test it out.

              - Josiah

              Comment

              • Jacek Generowicz

                #22
                Re: Some language proposals.

                aahz@pythoncraf t.com (Aahz) writes:
                [color=blue]
                > In article <tyfwu6bmfhx.fs f@pcepsft001.ce rn.ch>,
                > Jacek Generowicz <jacek.generowi cz@cern.ch> wrote:[color=green]
                > >
                > >Sure. I have some stateful methods of classes (which I create
                > >dynamically and stick onto the class as the information about the
                > >existence of the method becomes available). By implementing them as
                > >closures I can just stick them on to the class. If I were to implement
                > >them as instances then I'd have to reimplement all the descriptors
                > >that take care of turning functions into bound or unbound methods.[/color]
                >
                > Why not use callable instances?[/color]

                Errrrr ...

                Reading the paragraph you quoted and trying to understand it is left
                as an exercise to you. (Hint: it's the last sentence.)

                Comment

                • Jacek Generowicz

                  #23
                  Re: Some language proposals.

                  Paul Prescod <paul@prescod.n et> writes:
                  [color=blue]
                  > But the more important point is that people do not NEED it much. Guido
                  > writes hundreds of lines of Python code per week. If he often ran into
                  > situations where a mutable closure would make a big difference then he
                  > would presumably find some way of doing it. The people who want this
                  > seem most often to be people trying to import their coding styles from
                  > another language.[/color]

                  Methinks that your image of just how much Guido drives new additions to
                  the language, is a little dated.

                  Comment

                  • Jacek Generowicz

                    #24
                    Re: Some language proposals.

                    Michael Hudson <mwh@python.net > writes:
                    [color=blue]
                    > Jacek Generowicz <jacek.generowi cz@cern.ch> writes:
                    >[color=green]
                    > > Aaah, OK, _if_ you think that closures are _only_ a way of faking
                    > > objects, _then_ claiming that Python is primarily OO does have a
                    > > bearing on the use of closures. Forgive me for not pursuing
                    > > this tangent any further.[/color]
                    >
                    > OK, you really hadn't seen this argument before. You must be new here
                    > :-) (or at least, new to this particular dispute).[/color]

                    Yes, I usually switch off rather early in the "Python purity vs
                    whatever" threads, and the "The current state of Python is programming
                    language Nirvana" threads. You see, I use Python because it lets me
                    gets certain jobs done easily and enjoyably, and don't really much
                    care for language patriotism. I will fiercely defend Python on its
                    merits (which are legion), but that does not preclude me from
                    sometimes noting that it would be handy if something were different
                    than it is right now.

                    My contribution to this thread started with a question: I paraphrase
                    "why are Python closures read only?". Paul gave me an answer which has
                    some merit and I am satisfied with that answer. Frankly, I have no
                    time for, or interest in discussing how often I should on should not be
                    using closures in Python. When they are convenient for me, I will use
                    them, and when callable instances are more convenient, I will use
                    those, regardless of what you and Paul might say, so there,
                    na-na-na-naaa-naaah !
                    [color=blue]
                    > (trivially, you never *need* closures, just the same as you don't
                    > *need* objects, there's a rather dull and unhelpful isomorphism
                    > between the two concepts).[/color]

                    Yes, and we all know about Turing equivalence too. So we don't need
                    Python at all.
                    [color=blue][color=green]
                    > > Sure. I have some stateful methods of classes (which I create
                    > > dynamically and stick onto the class as the information about the
                    > > existence of the method becomes available). By implementing them as
                    > > closures I can just stick them on to the class. If I were to implement
                    > > them as instances then I'd have to reimplement all the descriptors
                    > > that take care of turning functions into bound or unbound methods.[/color]
                    >
                    > Which isn't that hard...[/color]

                    It's not hard, but it's pointless, when there are ways of getting it
                    for free.
                    [color=blue]
                    > I think a code example might lend a bit more clarity.[/color]

                    What's unclear about it? I get the impression that you understand
                    exactly what the point is.
                    [color=blue][color=green][color=darkred]
                    >>> class foo: pass[/color][/color][/color]
                    ....[color=blue][color=green][color=darkred]
                    >>> class callable:[/color][/color][/color]
                    .... def __call__(self): print self
                    ....[color=blue][color=green][color=darkred]
                    >>> instance = callable()
                    >>> def meth(self): print self[/color][/color][/color]
                    ....[color=blue][color=green][color=darkred]
                    >>> foo.meth = meth
                    >>> foo.instance = instance
                    >>> f = foo()
                    >>> f[/color][/color][/color]
                    <__main__.foo instance at 0x815fa64>[color=blue][color=green][color=darkred]
                    >>> f.meth()[/color][/color][/color]
                    <__main__.foo instance at 0x815fa64> # self == f[color=blue][color=green][color=darkred]
                    >>> f.instance()[/color][/color][/color]
                    <__main__.calla ble instance at 0x815f624> # self != f[color=blue][color=green][color=darkred]
                    >>> f.meth[/color][/color][/color]
                    <bound method foo.meth of <__main__.foo instance at 0x815fa64>>[color=blue][color=green][color=darkred]
                    >>> f.instance[/color][/color][/color]
                    <__main__.calla ble instance at 0x815f624> # Hmm, it's not a method[color=blue][color=green][color=darkred]
                    >>>[/color][/color][/color]

                    meth behaves like a Python method, instance does not.
                    [color=blue][color=green]
                    > > [At this point I'd love someone to step up and show me how to re-use
                    > > the existing FunctionType descriptors in my own classes.][/color]
                    >
                    > Post some code, and I'll have a go.[/color]

                    Find some way of making callable [from above] use
                    types.FunctionT ype.__get__. I don't see what code examples could
                    possibly help in specifying the problem more clearly (unless the code
                    is the solution, of course).

                    But please don't bother unless you really want to do it for your own
                    entertainment. My not having found a way to do it, is in no way
                    stopping me from achieving my goals. (Which is more than can be said
                    for contributing to this thread :-) There being perfectly viable
                    alternatives to doing it, means that I haven't invested much time in
                    finding an answer, so it may well be that there is as simple solution.
                    [color=blue][color=green]
                    > > Another example. I make quite heavy use of a trivial memoizer. The
                    > > closure verison is much shorter, clearer and faster.[/color]
                    >
                    > I'll grant you this: I've done the same.[/color]

                    That's my point. Closures are there, sometimes they are more
                    appropriate than instances, so use them. No point in discussing the
                    merits and demerits of the two alternatives and pontificating on what
                    is Pythonic or not.
                    [color=blue][color=green]
                    > > (I want it to be writeable because I sometimes want to 'prime' the
                    > > cache, or do other things to it ... so I'm giving myself access to
                    > > the cache by binding the cache as a function attribute of the
                    > > closure, before returning it from the memoizer)[/color]
                    >
                    > Um, here, unless I misunderstand you, you don't want to mutate the
                    > closed over binding (which is what Python currently doesn't let you
                    > do) but mutate the object the closed over binding is bound to. In
                    > this respect, Python is no different from anything else, you need to
                    > arrange some way to expose said object outside the closure.
                    >
                    > What am I missing?[/color]

                    Nothing. It was an inappropriate example.
                    [color=blue][color=green]
                    > > In short, whenever I want a _function_ which happens to have some
                    > > internal state, I'd much rather use a closure than an instance of a
                    > > class.[/color]
                    >
                    > Maybe, once you've been assimilated into the Python Borg mindset, you
                    > don't, actually.[/color]

                    Aaah, this thread is an attempt to assimilate me :-) Now I understand.
                    [color=blue]
                    > There are sort of two extreme possibilities here:
                    >
                    > 1) I am so blinded by the fact that I know Python as of 2.3 FAR better
                    > than any other language that I don't see how wonderful Python would
                    > be if "full closures" were added.
                    >
                    > 2) Full closures just aren't that appropriate to Pythonic programming.
                    >
                    > The truth, almost certainly, is somewhere in between these points.[/color]

                    An excellent summary, which, in my opinion says all that remains to be
                    said in this thread.

                    And, with that, I take my leave. I bid you a good day, gentlemen.

                    Comment

                    • Jacek Generowicz

                      #25
                      Re: Some language proposals.

                      Paul Prescod <paul@prescod.n et> writes:
                      [color=blue]
                      > You've cleverly found one of the very few places where Python
                      > distinguishes between "true" functions and callable objects.[/color]

                      What bothers me more (I think, though I can't remember the exact
                      reasons why, right now, so maybe it's not that important), is that
                      Python distinguishes between "true" functions and "builtin" functions.
                      [color=blue]
                      > I would argue that classes should distinguish between
                      > attributes-to-be-treated-as-methods and
                      > attributes-to-be-treated-as-just-attributes using something other than
                      > type.[/color]

                      Look again. They do. [Hint: descriptors]
                      [color=blue]
                      > Consider the following program:
                      >
                      >
                      > class a:
                      > pass
                      >
                      > def func():
                      > pass
                      >
                      > lst = [1, 2, 3, "a", "b", "c", object(), lambda x:x ]
                      >
                      > for x in lst:
                      > a.b = x
                      > assert a.b is x, "What???? %s"% x
                      > print "Okay", x
                      >
                      > Frankly I think it is unpythonic that a second after assignment to a.b
                      > the thing I get back is different than the thing I put in.[/color]

                      I do wish you'd run your examples through a Python interpreter before
                      posting them. The little bugs you include, really interfere with
                      trying to understand what your point is.

                      I suspect that what you are trying to demonstrate is this:
                      [color=blue][color=green][color=darkred]
                      >>> for x in lst:[/color][/color][/color]
                      .... a.b = x
                      .... print a.b is x
                      ....
                      1
                      1
                      1
                      1
                      1
                      1
                      1
                      0

                      Though why you need 3 integers, and 3 strings, and a whole lot of line
                      noise to do it, escapes me.

                      [An I've stated in my followup to Michael, I have nothing else to say
                      about closures in Python.]

                      Comment

                      • Paul Prescod

                        #26
                        Re: Some language proposals.

                        Jacek Generowicz wrote:[color=blue]
                        > I do wish you'd run your examples through a Python interpreter before
                        > posting them. The little bugs you include, really interfere with
                        > trying to understand what your point is.[/color]

                        Sorry. Don't know what else I can do:

                        bash-2.05a$ cat foo.py
                        class a:
                        pass

                        def func():
                        pass

                        lst = [1, 2, 3, "a", "b", "c", object(), lambda x:x ]

                        for x in lst:
                        a.b = x
                        assert a.b is x, "What???? %s"% x
                        print "Okay", x

                        bash-2.05a$ python foo.py
                        Okay 1
                        Okay 2
                        Okay 3
                        Okay a
                        Okay b
                        Okay c
                        Okay <object object at 0x116e20>
                        Traceback (most recent call last):
                        File "foo.py", line 11, in ?
                        assert a.b is x, "What???? %s"% x
                        AssertionError: What???? <function <lambda> at 0x122190>
                        bash-2.05a$

                        And this is after cutting and pasting the program from your reply back
                        into a file.

                        Given that I was trying to demonstrate an inconsistency in behaviour I
                        felt it helpful to show examples of logical behaviour.

                        Paul Prescod


                        Comment

                        • Jacek Generowicz

                          #27
                          Re: Some language proposals.

                          Ooops, sorry, you're right, the bug was of _my_ creation this time.

                          Comment

                          • Michael Hudson

                            #28
                            Re: Some language proposals.

                            Jacek Generowicz <jacek.generowi cz@cern.ch> writes:
                            [color=blue]
                            > Michael Hudson <mwh@python.net > writes:
                            >[color=green]
                            > > Jacek Generowicz <jacek.generowi cz@cern.ch> writes:
                            > >[color=darkred]
                            > > > Aaah, OK, _if_ you think that closures are _only_ a way of faking
                            > > > objects, _then_ claiming that Python is primarily OO does have a
                            > > > bearing on the use of closures. Forgive me for not pursuing
                            > > > this tangent any further.[/color]
                            > >
                            > > OK, you really hadn't seen this argument before. You must be new here
                            > > :-) (or at least, new to this particular dispute).[/color]
                            >
                            > Yes, I usually switch off rather early in the "Python purity vs
                            > whatever" threads,[/color]

                            Me too. I wonder why we're both still in this one?

                            [...][color=blue][color=green]
                            > > (trivially, you never *need* closures, just the same as you don't
                            > > *need* objects, there's a rather dull and unhelpful isomorphism
                            > > between the two concepts).[/color]
                            >
                            > Yes, and we all know about Turing equivalence too. So we don't need
                            > Python at all.[/color]

                            Indeed. Break out the infinitely long tapes. But it does make "need"
                            a difficult word, is all.
                            [color=blue][color=green][color=darkred]
                            > > > Sure. I have some stateful methods of classes (which I create
                            > > > dynamically and stick onto the class as the information about the
                            > > > existence of the method becomes available). By implementing them as
                            > > > closures I can just stick them on to the class. If I were to implement
                            > > > them as instances then I'd have to reimplement all the descriptors
                            > > > that take care of turning functions into bound or unbound methods.[/color]
                            > >
                            > > Which isn't that hard...[/color]
                            >
                            > It's not hard, but it's pointless, when there are ways of getting it
                            > for free.
                            >[color=green]
                            > > I think a code example might lend a bit more clarity.[/color]
                            >
                            > What's unclear about it? I get the impression that you understand
                            > exactly what the point is.[/color]

                            Well, now we're even on assuming too much about the other's
                            comprehension front :-)
                            [color=blue][color=green][color=darkred]
                            > >>> class foo: pass[/color][/color]
                            > ...[color=green][color=darkred]
                            > >>> class callable:[/color][/color]
                            > ... def __call__(self): print self
                            > ...[color=green][color=darkred]
                            > >>> instance = callable()
                            > >>> def meth(self): print self[/color][/color]
                            > ...[color=green][color=darkred]
                            > >>> foo.meth = meth
                            > >>> foo.instance = instance
                            > >>> f = foo()
                            > >>> f[/color][/color]
                            > <__main__.foo instance at 0x815fa64>[color=green][color=darkred]
                            > >>> f.meth()[/color][/color]
                            > <__main__.foo instance at 0x815fa64> # self == f[color=green][color=darkred]
                            > >>> f.instance()[/color][/color]
                            > <__main__.calla ble instance at 0x815f624> # self != f[color=green][color=darkred]
                            > >>> f.meth[/color][/color]
                            > <bound method foo.meth of <__main__.foo instance at 0x815fa64>>[color=green][color=darkred]
                            > >>> f.instance[/color][/color]
                            > <__main__.calla ble instance at 0x815f624> # Hmm, it's not a method[color=green][color=darkred]
                            > >>>[/color][/color]
                            >
                            > meth behaves like a Python method, instance does not.[/color]

                            Ah, ok. To make it behave like a method, you need to make it a
                            descriptor, i.e. implement __get__ (and make everything in sight
                            new-style classes, of course).
                            [color=blue][color=green][color=darkred]
                            > > > [At this point I'd love someone to step up and show me how to re-use
                            > > > the existing FunctionType descriptors in my own classes.][/color]
                            > >
                            > > Post some code, and I'll have a go.[/color]
                            >
                            > Find some way of making callable [from above] use
                            > types.FunctionT ype.__get__.[/color]

                            I don't think I can do *that*:
                            import types

                            class foo(object):
                            pass

                            class Callable(object ):
                            __get__ = types.FunctionT ype.__get__

                            foo.inst = Callable()

                            print foo.inst

                            yields:

                            Traceback (most recent call last):
                            File "<stdin>", line 1, in ?
                            File "/usr/tmp/python-10511jfs.py", line 11, in ?
                            print foo.inst
                            TypeError: descriptor '__get__' requires a 'function' object but received a 'Callable'

                            but you can do something nearly equivalent:

                            import types

                            class foo(object):
                            pass

                            class Callable(object ):
                            def __init__(self): # wonder why this is needed:
                            self.__name__ = 'Callable'
                            def __call__(self, ob):
                            return ob
                            def __get__(self, ob, cls=None):
                            return types.UnboundMe thodType(self, ob, cls)

                            foo.inst = Callable()

                            print foo.inst
                            print foo().inst()

                            (needs 2.3, for 2.2 use new.instancemet hod instead).
                            [color=blue]
                            > I don't see what code examples could possibly help in specifying the
                            > problem more clearly (unless the code is the solution, of course).
                            >
                            > But please don't bother unless you really want to do it for your own
                            > entertainment.[/color]

                            Well, I've signed up to give a talk on new-style classes at Python-UK,
                            so I'd hope not to have to work too hard for this :-)

                            [...][color=blue][color=green][color=darkred]
                            > > > In short, whenever I want a _function_ which happens to have some
                            > > > internal state, I'd much rather use a closure than an instance of a
                            > > > class.[/color]
                            > >
                            > > Maybe, once you've been assimilated into the Python Borg mindset, you
                            > > don't, actually.[/color]
                            >
                            > Aaah, this thread is an attempt to assimilate me :-) Now I understand.[/color]

                            Damn, you noticed.
                            [color=blue][color=green]
                            > > There are sort of two extreme possibilities here:
                            > >
                            > > 1) I am so blinded by the fact that I know Python as of 2.3 FAR better
                            > > than any other language that I don't see how wonderful Python would
                            > > be if "full closures" were added.
                            > >
                            > > 2) Full closures just aren't that appropriate to Pythonic programming.
                            > >
                            > > The truth, almost certainly, is somewhere in between these points.[/color]
                            >
                            > An excellent summary, which, in my opinion says all that remains to be
                            > said in this thread.
                            >
                            > And, with that, I take my leave. I bid you a good day, gentlemen.[/color]

                            And to you!

                            Cheers,
                            mwh

                            --
                            It's actually a corruption of "starling". They used to be carried.
                            Since they weighed a full pound (hence the name), they had to be
                            carried by two starlings in tandem, with a line between them.
                            -- Alan J Rosenthal explains "Pounds Sterling" on asr

                            Comment

                            • Aahz

                              #29
                              Re: Some language proposals.

                              In article <tyfoermmgp7.fs f@pcepsft001.ce rn.ch>,
                              Jacek Generowicz <jacek.generowi cz@cern.ch> wrote:[color=blue]
                              >aahz@pythoncra ft.com (Aahz) writes:[color=green]
                              >> In article <tyfwu6bmfhx.fs f@pcepsft001.ce rn.ch>,
                              >> Jacek Generowicz <jacek.generowi cz@cern.ch> wrote:[color=darkred]
                              >>>
                              >>>Sure. I have some stateful methods of classes (which I create
                              >>>dynamicall y and stick onto the class as the information about the
                              >>>existence of the method becomes available). By implementing them as
                              >>>closures I can just stick them on to the class. If I were to implement
                              >>>them as instances then I'd have to reimplement all the descriptors
                              >>>that take care of turning functions into bound or unbound methods.[/color]
                              >>
                              >> Why not use callable instances?[/color]
                              >
                              >Errrrr ...
                              >
                              >Reading the paragraph you quoted and trying to understand it is left
                              >as an exercise to you. (Hint: it's the last sentence.)[/color]

                              Nope. Got nothing to do with my point:

                              class Callable:
                              def __call__(self):
                              print "!"

                              class C:
                              def __init__(self):
                              self.foo = Callable()

                              C().foo()

                              Now tell me why this doesn't do what you want.
                              --
                              Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

                              "Do not taunt happy fun for loops. Do not change lists you are looping over."
                              --Remco Gerlich, comp.lang.pytho n

                              Comment

                              • Terry Reedy

                                #30
                                Re: Some language proposals.


                                "Jacek Generowicz" <jacek.generowi cz@cern.ch> wrote in message
                                news:tyfk72amei 6.fsf@pcepsft00 1.cern.ch...[color=blue]
                                > language Nirvana" threads. You see, I use Python because it lets me
                                > gets certain jobs done easily and enjoyably, and don't really much
                                > care for language patriotism. I will fiercely defend Python on its
                                > merits (which are legion), but that does not preclude me from
                                > sometimes noting that it would be handy if something were different
                                > than it is right now.[/color]

                                Sounds sensible.
                                [color=blue]
                                > My contribution to this thread started with a question: I paraphrase
                                > "why are Python closures read only?".[/color]

                                As I said before, because Python has a 'write locally unless directed
                                otherwise' rule, which is not going to change, and because no one has yet
                                come up with a convincingly good syntax or method to replace or extend the
                                global directive for directing otherwise -- where convincely good mean
                                enough better than mutable wrapping to be worth the bother. And because no
                                one has yet cared enough to effectively push the issue further.

                                On the aesthetics of wrapping: with a C background, the notion of rebind
                                vars in something else's strikes me as 'odder' that mutating a mutable. So
                                I do not see n = [n] as being that ugly, while understanding that someone
                                with a 'full-closure' language background well might. On the other hand,
                                the non-uniformity of write local, write global, but not in between, is
                                bothersome enough to enough developers that there was serious discussion of
                                how to do it.

                                Terry J. Reedy




                                Comment

                                Working...