Python's biggest compromises

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gerald Klix

    #16
    Re: Python's biggest compromises

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1



    Anthony_Barker wrote:
    | I have been reading a book about the evolution of the Basic
    | programming language. The author states that Basic - particularly
    | Microsoft's version is full of compromises which crept in along the
    | language's 30+ year evolution.
    |
    | What to you think python largest compromises are?
    |
    IHMO it is the lambda expression.
    These "functions" are not real functions. You can not use
    statements in them.

    What Python realy needs here is some means to make an expression
    from a list of statements (called suite in the syntax defintion).
    That given PEP 308 (If-then-else expression) or PEP 318 (Function/Method
    Decorator Syntax) are mostly pointless.

    Let me give an example:

    Suppose there some special braces like (: :) and a exit operator like a
    unary ^ one can write a conditional expession like that:
    (:
    ~ if f():
    ~ ^trueValue
    ~ else:
    ~ ^falseValue :)

    classmethods can be declared as follows:
    cm = (:
    ~ def im( arg0, arg1 ):
    ~ return answer
    ~ ^classmethod( im ) :)

    or
    cm = classmethod( (:
    ~ def im( arg0, arg1 ):
    ~ return answer
    ~ ^im
    ~ :) )

    obvously this demands for some means to write anonymous functions like

    def ( arg0, arg1 ):
    ~ return arg0 - arg1

    semanticly this should transform to

    (:
    ~ def newName( arg0, arg1 ):
    ~ return arg0 - arg1
    ~ ^newName :)

    giving

    cm = def ( arg0, arg1 ):
    ~ return answer

    Ok, I admit that this is difficult to be integrated in
    the existing syntax. Perhaps we can not drop the braces
    around such expression.

    Is this worth writing a PEP?

    |
    |>"No, we use Unit Testing in Zope".
    I am still missing a simple testing framework. doctest
    is a good idea, but conflicts with syntax hilighting in most
    editors.

    |
    |
    | That said, obvious Basic compromised by using things such as "Option
    | Explicit", thereby allowing both dynamic and more static style
    | variables. Yahoo groups moved from python to C due to dynamic typing.
    This is not a problem. They key to speed is using extension written
    in C for performance. Normaly you will find one that sloves your problem.

    |
    | Non-compiled - obviously there are times when performance matters more
    | than other things. Google I believe uses python to prototype (or used)
    | and then turns to c++ for heavy lifting.
    |
    | What about immutable strings? I'm not sure I understand Guido's
    | preference for them.
    In fact the array module provides mutable strings.

    |
    | Anthony
    | http://xminc.com/anthony

    HTH,
    Gerald
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.1 (GNU/Linux)
    Comment: Using GnuPG with Debian - http://enigmail.mozdev.org

    iD8DBQE/KjWgEDg9cqFA1jQ RAovzAJkBygPzdf HsoVXu9H2QHnxTD 9sMmACdHvY5
    dB1j4kXTzejml7f G0oSwhUg=
    =WGR+
    -----END PGP SIGNATURE-----

    Comment

    • Robin Becker

      #17
      Re: Python's biggest compromises

      In article <mailman.105970 7762.24307.pyth on-list@python.org >, Ian
      Bicking <ianb@colorstud y.com> writes[color=blue]
      >And Java's JIT is based on (at least originally) work done on Self,
      >which had to do type inference. And actually in many circumstances Java
      >requires type inference, because you can substitute in an instance of a
      >subclass.
      >
      >Anyway, JIT is all about runtime analysis -- if you could infer types
      >completely before running the program, you would just put in the
      >optimization s statically (i.e., compiling optimizations). JIT does
      >those optimizations at runtime by definition.
      >[/color]

      but Java does at least require specifying every type and that must at
      least cut down on the amount of work required.
      [color=blue]
      >And Bicycle Repair Man is inspired by the Refactoring Browser, an IDE
      >tool based on another dynamic language (Smalltalk), not on a tool from a
      >static language (like Java).
      >
      > Ian[/color]

      I don't have any data here, but I believe Python is just a little too
      weakly typed for compiling to float*float type assembler efficiently.
      --
      Robin Becker

      Comment

      • John Roth

        #18
        Re: Python's biggest compromises


        "Robin Becker" <robin@jessikat .fsnet.co.uk> wrote in message
        news:23bcqKAykj K$Ewhy@jessikat .fsnet.co.uk...[color=blue]
        > In article <mailman.105970 7762.24307.pyth on-list@python.org >, Ian
        > Bicking <ianb@colorstud y.com> writes[color=green]
        > >And Java's JIT is based on (at least originally) work done on Self,
        > >which had to do type inference. And actually in many circumstances Java
        > >requires type inference, because you can substitute in an instance of a
        > >subclass.
        > >
        > >Anyway, JIT is all about runtime analysis -- if you could infer types
        > >completely before running the program, you would just put in the
        > >optimization s statically (i.e., compiling optimizations). JIT does
        > >those optimizations at runtime by definition.
        > >[/color]
        >
        > but Java does at least require specifying every type and that must at
        > least cut down on the amount of work required.
        >[color=green]
        > >And Bicycle Repair Man is inspired by the Refactoring Browser, an IDE
        > >tool based on another dynamic language (Smalltalk), not on a tool from a
        > >static language (like Java).
        > >
        > > Ian[/color]
        >
        > I don't have any data here, but I believe Python is just a little too
        > weakly typed for compiling to float*float type assembler efficiently.[/color]

        The trick with JITs is that they don't depend on absolute type
        consistency. They depend on the observation that 99.44% of your
        code is type consistent, and that consistency will turn up at run time. So
        the code they generate depends on that discovered consistency, and
        checks in front of each section to discover if the types are what the
        code expects.

        If it is, they execute it, if it isn't, they abandon it and go back to
        the intepreter to discover what happened.

        John Roth[color=blue]
        > --
        > Robin Becker[/color]


        Comment

        • Michael Hudson

          #19
          Re: Python's biggest compromises

          hanzspam@yahoo. com.au (Hannu Kankaanpää) writes:
          [color=blue]
          > Worst of both indeed. Maybe the decision to choose reference
          > counting was driven by speed considerations.[/color]

          Ease of implementation, portability and playing nicely with C
          extensions are more likely candidates, IMO.
          [color=blue]
          > That might've been reasonable back in early 90's, but GC techniques
          > have evolved from those days and so GC would be a superior technique
          > now.[/color]

          <button nature="hot">
          Reference counting *is* a form of garbage collection.
          </button>

          Saying "Ref. counting sucks, let's use GC instead" is a statement near
          as dammit to meaningless.

          Given the desires above, I really cannot think of a clearly better GC
          strategy for Python that the one currently employed. AFAICS, the
          current scheme's biggest drawback is its memory overhead, followed by
          the cache-trashing tendencies of decrefs.

          What would you use instead?

          Cheers,
          mwh

          --
          After a heavy night I travelled on, my face toward home - the comma
          being by no means guaranteed. -- paraphrased from cam.misc

          Comment

          • John Roth

            #20
            Re: Python's biggest compromises


            "Hannu Kankaanpää" <hanzspam@yahoo .com.au> wrote in message
            news:840592e1.0 307312304.77a0a 05f@posting.goo gle.com...[color=blue]
            > anthony_barker@ hotmail.com (Anthony_Barker ) wrote in message[/color]
            news:<899f842.0 307310555.56134 f71@posting.goo gle.com>...[color=blue][color=green]
            > > What to you think python largest compromises are?[/color]
            >
            > I think reference counting is. Added to this the fact that
            > garbage collection is also possible (as in Jython). So we get
            > the worst of both worlds.
            >
            > 1. Idioms like this won't work portably:
            >
            > def foo():
            > f = file('x')
            > return f.read()
            >
            > Even though f.__del__ closes the file, in garbage
            > collected environment the f object might not get deleted
            > in a good while, and would cause problems.
            >
            > 2. And then, we still need to use weakref to ensure
            > that our crossreferenced stuff works both with and without GC.
            >
            > Worst of both indeed. Maybe the decision to choose reference
            > counting was driven by speed considerations. That might've
            > been reasonable back in early 90's, but GC techniques have
            > evolved from those days and so GC would be a superior
            > technique now.
            >
            > Well, since no one else pointed this out yet, maybe there's
            > some flaw in my reasoning.[/color]

            There's a flaw in your reasoning. The various techniques that
            descend from mark and sweep (which is what you're
            calling garbage collection) depend on being able to
            identify all of the objects pointed to. For objects that are
            owned by Python, that's a lengthy (that is, inefficient)
            process, and it's not possible in general for objects that
            are created by extensions.

            Reference counting only depends on having the
            object itself, and control of the creation and removal
            of references. The latter is a frequent source of bugs
            and memory leaks in extensions.

            It's easy to say that various languages would be improved
            by adding "real" garbage collection, but those techniques
            impose significant design constraints on the implementation
            model.

            John Roth


            Comment

            • Daniel Dittmar

              #21
              Re: Python's biggest compromises

              Michael Hudson wrote:[color=blue]
              > <button nature="hot">
              > Reference counting *is* a form of garbage collection.
              > </button>
              >
              > Saying "Ref. counting sucks, let's use GC instead" is a statement near
              > as dammit to meaningless.[/color]

              This statement is not meaningless because most programmers will correctly
              identify GC in this context as something like mark-and-sweep, generation
              scavenging etc.

              see also: DOS sucks, let's use an operating system instead.
              [color=blue]
              > current scheme's biggest drawback is its memory overhead, followed by
              > the cache-trashing tendencies of decrefs.[/color]

              plus it doesn't support independent threads as all reference counting would
              have to be protected, leading to poor performance.

              But a lot of Python code depends on reference counting or more exactly it
              depends on the timely call of the destructor. So even if a much better GC is
              added to Python, reference counting would perhaps be kept for backwards
              compatibility (see Python's biggest compromises)

              Daniel



              Comment

              • Daniel Dittmar

                #22
                Re: Python's biggest compromises

                John Roth wrote:[color=blue]
                > There's a flaw in your reasoning. The various techniques that
                > descend from mark and sweep (which is what you're
                > calling garbage collection) depend on being able to
                > identify all of the objects pointed to. For objects that are
                > owned by Python, that's a lengthy (that is, inefficient)[/color]

                That's what generation scavenging was developed for. One shouldn't argue by
                tradition alone, but the fact that the major implementations of dynamic
                languages like LISP and Smalltalk don't use reference counting should carry
                some weight.
                [color=blue]
                > process, and it's not possible in general for objects that
                > are created by extensions.[/color]

                This is generally handled by registering and unregistering objects in the
                extension code. Error prone as well, but probably less so than reference
                counting.
                [color=blue]
                > It's easy to say that various languages would be improved
                > by adding "real" garbage collection, but those techniques
                > impose significant design constraints on the implementation
                > model.[/color]

                True. But one could review these constraints from time to time.

                Daniel



                Comment

                • Paul Rubin

                  #23
                  Re: Python's biggest compromises

                  Michael Hudson <mwh@python.net > writes:[color=blue][color=green]
                  > > One shouldn't argue by tradition alone, but the fact that the major
                  > > implementations of dynamic languages like LISP and Smalltalk don't
                  > > use reference counting should carry some weight.[/color]
                  >
                  > True. But the major implementations of these languages are also
                  > usually less portable, and something more of a fiddle to write C
                  > extensions for (at least, for the implementations I know about, which
                  > are mostly CL impls).[/color]

                  I'd say the opposite, the Lisp implementations I've worked on are
                  considerably easier to write C extensions for, partly BECAUSE you
                  don't have to worry about constantly tweaking ref counts. In GNU
                  Emacs Lisp, for example, if you cons a new heap object and put it in a
                  C variable and (iirc) then call eval, you have to call a macro that
                  tells the GC not to sweep the object. But many C functions don't make
                  new objects, and most don't call eval, and you don't have to remember
                  what objects you've called the macro for. There's another macro that
                  you call before your function returns, and that cleans up all the GC
                  records in your stack frame made by any invocations of the first macro.

                  Comment

                  • Robin Becker

                    #24
                    Re: Python's biggest compromises

                    In article <vikh3ink3djc7c @news.supernews .com>, John Roth
                    <newsgroups@jhr othjr.com> writes[color=blue][color=green]
                    >>
                    >> I don't have any data here, but I believe Python is just a little too
                    >> weakly typed for compiling to float*float type assembler efficiently.[/color]
                    >
                    >The trick with JITs is that they don't depend on absolute type
                    >consistency. They depend on the observation that 99.44% of your
                    >code is type consistent, and that consistency will turn up at run time. So
                    >the code they generate depends on that discovered consistency, and
                    >checks in front of each section to discover if the types are what the
                    >code expects.
                    >
                    >If it is, they execute it, if it isn't, they abandon it and go back to
                    >the intepreter to discover what happened.
                    >
                    >John Roth[/color]
                    Yes I suspected they have to do that, but that implies that a discovered
                    'float' object must carry along a whole lot of baggage (I guess I mean
                    be a more generic object) to allow for the testing. Loops without method
                    or function calls would be good candidates for JIT as methods and
                    functions could alter attribute types.

                    Is the JIT object literally just a union of

                    type,values

                    or would it be an actual Python object? For example would an
                    innerproduct be over a pair of lists or would the magic convert these
                    into actual double arrays.
                    --
                    Robin Becker

                    Comment

                    • Anthony_Barker

                      #25
                      Re: Python's biggest compromises

                      > > What to you think python largest compromises are?[color=blue][color=green]
                      > >
                      > > The three that come to my mind are significant whitespace, dynamic
                      > > typing, and that it is interpreted - not compiled. These three put
                      > > python under fire and cause some large projects to move off python or
                      > > relegate it to prototyping.[/color]
                      >
                      > I don't view any of these as "compromise s". That word suggests that
                      > something was conceded, or that an intermediate position between two
                      > extremes was chosen to appease. I don't think that either sense really
                      > applies to these features.
                      >
                      > The three items that you listed are merely design choices. While arguments
                      > over them are continuous, two of the design choices (interpreter, dynamic
                      > typing) are consistent with Python's intended use as a language which
                      > excels at rapid prototyping. The third (white space) is merely a stylistic
                      > choice which is designed to encourage readable programs.
                      >
                      > "Compromise s" in language design occur usually when a committee tries to
                      > standardize a language, and each has differing views about how the language
                      > should be used. While this occurs somewhat in Python, other languages
                      > have suffered more mightily from this particular disorder.
                      >
                      > Mark[/color]

                      Excellent points - you are correct the ones I listed are design
                      choices.

                      Some people could be interpreted them as design "compromise s". The
                      kind of people who would like to use the same tool for all problems.

                      Comment

                      • Ian Bicking

                        #26
                        Re: Python's biggest compromises

                        On Fri, 2003-08-01 at 02:04, Hannu Kankaanpää wrote:[color=blue]
                        > Worst of both indeed. Maybe the decision to choose reference
                        > counting was driven by speed considerations. [/color]

                        Reference counting spreads the speed hit over the entire program, while
                        other techniques tend to hit performance hard every so often. But all
                        together I think reference counting is usually slower than a good GC
                        algorithm, and incremental garbage collection algorithms can avoid
                        stalling. And I'm sure that the current state -- references counting
                        plus another kind of garbage collection for circular references -- must
                        be worse than either alone. The advantage is predictable collection
                        (unless you are using Jython), without memory leaks (due to circular
                        references).

                        Oh well...

                        Ian



                        Comment

                        • OKB (not okblacke)

                          #27
                          Re: Python's biggest compromises

                          Gerald Klix wrote:
                          [color=blue]
                          > What Python realy needs here is some means to make an expression
                          > from a list of statements (called suite in the syntax defintion).[/color]

                          I believe this is called a "function".

                          --
                          --OKB (not okblacke)
                          "Do not follow where the path may lead. Go, instead, where there is
                          no path, and leave a trail."
                          --author unknown

                          Comment

                          • John Roth

                            #28
                            Re: Python's biggest compromises


                            "Robin Becker" <robin@jessikat .fsnet.co.uk> wrote in message
                            news:MM7ikWAxZo K$Ew0N@jessikat .fsnet.co.uk...[color=blue]
                            > In article <vikh3ink3djc7c @news.supernews .com>, John Roth
                            > <newsgroups@jhr othjr.com> writes[color=green][color=darkred]
                            > >>
                            > >> I don't have any data here, but I believe Python is just a little too
                            > >> weakly typed for compiling to float*float type assembler efficiently.[/color]
                            > >
                            > >The trick with JITs is that they don't depend on absolute type
                            > >consistency. They depend on the observation that 99.44% of your
                            > >code is type consistent, and that consistency will turn up at run time.[/color][/color]
                            So[color=blue][color=green]
                            > >the code they generate depends on that discovered consistency, and
                            > >checks in front of each section to discover if the types are what the
                            > >code expects.
                            > >
                            > >If it is, they execute it, if it isn't, they abandon it and go back to
                            > >the intepreter to discover what happened.
                            > >
                            > >John Roth[/color]
                            > Yes I suspected they have to do that, but that implies that a discovered
                            > 'float' object must carry along a whole lot of baggage (I guess I mean
                            > be a more generic object) to allow for the testing. Loops without method
                            > or function calls would be good candidates for JIT as methods and
                            > functions could alter attribute types.
                            >
                            > Is the JIT object literally just a union of
                            >
                            > type,values
                            >
                            > or would it be an actual Python object? For example would an
                            > innerproduct be over a pair of lists or would the magic convert these
                            > into actual double arrays.[/color]

                            As far as I'm aware, the JIT code doesn't fiddle with the data;
                            it just does the equivalent of assert tests at the beginning of the
                            blocks to verify that it's got the type of object it expects.

                            In other words, it does a very large amount of run-time type
                            checking. This only pays off if it can save even more expense
                            by compiling the code.

                            Now, this is going to be difficult for short segments of code,
                            but it can be quite a time saver if the JIT generated code can
                            make intermediate objects vanish so they don't have to be
                            created just to be discarded a short time later.

                            John Roth
                            [color=blue]
                            > --
                            > Robin Becker[/color]


                            Comment

                            • John Roth

                              #29
                              Re: Python's biggest compromises


                              "Anthony_Barker " <anthony_barker @hotmail.com> wrote in message
                              news:899f842.03 07310555.56134f 71@posting.goog le.com...[color=blue]
                              > I have been reading a book about the evolution of the Basic
                              > programming language. The author states that Basic - particularly
                              > Microsoft's version is full of compromises which crept in along the
                              > language's 30+ year evolution.
                              >
                              > What to you think python largest compromises are?[/color]

                              I'm not sure if we've beaten this one to death or not, but a real
                              example of a compromise just floated through my head.

                              Consider <list>.sort() and <list>.reverse( ). These two otherwise
                              admirable methods don't return the object, so they can't be chained.
                              Why not? Because they update the list in place, and Guido decided
                              that not returning the object was a cheap way to make it clear that
                              they were doing something unusual.

                              Now, *that's* a compromise. The worst of both worlds.

                              John Roth


                              Comment

                              • Hannu Kankaanpää

                                #30
                                Re: Python's biggest compromises

                                Michael Hudson <mwh@python.net > wrote in message news:<7h3brv9a9 oz.fsf@pc150.ma ths.bris.ac.uk> ...[color=blue]
                                > <button nature="hot">
                                > Reference counting *is* a form of garbage collection.
                                > </button>[/color]

                                You apparently have such a loose definition for garbage
                                collection, that even C programs have "a form of garbage
                                collection" on modern OSes: All garbage is reclaimed by
                                the OS when the program exits. It's just a very lazy collector.

                                I don't consider something a garbage collector unless it
                                collects all garbage (ref.counting doesn't) and is a bit more
                                agile than the one provided by OS.
                                [color=blue]
                                > Saying "Ref. counting sucks, let's use GC instead" is a statement near
                                > as dammit to meaningless.[/color]

                                You, I and everyone knows what I was talking about, so it could
                                hardly be regarded as "meaningles s".
                                [color=blue]
                                > Given the desires above, I really cannot think of a clearly better GC
                                > strategy for Python that the one currently employed. AFAICS, the
                                > current scheme's biggest drawback is its memory overhead, followed by
                                > the cache-trashing tendencies of decrefs.[/color]

                                It's not "the one currently employed". It's the *two* currently
                                employed and that causes grief as I described in my previous post.
                                And AFAIK, Ruby does use GC (mark-and-sweep, if you wish) and
                                seems to be working. However, this is rather iffy knowledge. I'm
                                actually longing for real GC because I've seen it work well in
                                Java and C#, and I know that it's being used successfully in many
                                other languages.
                                [color=blue]
                                > What would you use instead?[/color]

                                A trick question?

                                Comment

                                Working...