Live data from Hacker News

How Python 3 Should Have Worked (2012)

aaronsw.com

51–60 of 80 posts

Re: How Python 3 Should Have Worked (2012)

#51
post #43

Earlier quoted context omitted.

It's not flamewar material. GVR himself has acknowledged everything (edit in response to @EdwardDiego: most of what) I said. ( http://neopythonic.blogspot.com/2008/10/why-explicit-self-ha... ) The main contention holding back GVR and 3.1 from fixing this once and for all is that decorators currently need to manipulate the explicit self. From my perspective, it seems like Python decorators are [ab]used to reimplement…

> GVR himself has acknowledged everything I said I hate to be picky, but he only acknowledged portions of what you said. > but a couple decorators held this one back. @classmethod and @staticmethod are somewhat important language features to not break.

>@classmethod and @staticmethod are somewhat important language features

And strings aren't? Whatever, I understand that there are tradeoffs and to people that only use Python, the aesthetic blemishes tend to matter less. To people that use it in the context of other languages, it sticks out like a bad paint job or a prominent stain. This, and many more opinions than I could express succinctly, are on the reddit thread for GVR's post.

http://www.reddit.com/r/programming/comments/79h9y/guido_van...

@redditrasberry: To make a bad analogy, it's like a stain on your carpet in your front hallway. If you live with it for long enough you won't even see it any more. But to visitors coming to your house it's the most obvious thing. And it's particularly noticeable because the rest of Python is so nice - it's like I'm visiting an art gallery and everything is beautiful and pristine, but there on the carpet at the entrance is this huge stain that nobody has ever cleaned up.

Re: How Python 3 Should Have Worked (2012)

#52
post #32
post #20

Earlier quoted context omitted.

I agree with your general point -- I haven't switched to Python 3 because it doesn't really solve anything I need solved at the moment. I would incur a significant time (=money) penalty for converting all my code to use it without a perceived benefit. I would have to get say a 30% speed increase or a 30% code # of lines decrease to get of my butt and start converting to Python 3. I want to in principle, don't get me…

>I hate implicit hidden defaults and assumptions. Your implicit hidden default is my handy abbreviation. Imagine if we didn't have contractions in English. For that previous sentence, is it really at all frightening that the "didn't" meant "did not" but we haven't (ha) written it out? Could it possibly mean anything else? Wouldn't English be all the more stilted and ugly if there were only one explicit and verbose wa…

I'll agree with this entirely. As a newcomer to Python, I found the explicit "self" argument to be confusing. And now I just find it irritating. It breaks convention with every other OO language; it's additional meaningless noise in method definitions; and most importantly it violates the convention used by nearly every other programming language I'm aware of, which is that method definition argument lists and method call argument lists should match up.

When method call argument one is method definition argument two, things get confusing quickly. What's the benefit to readability? Python has plenty of other implicit rules (semantic whitespace being the most troublesome--though ironically its primary benefit of readability runs counter to the visual noise of the explicit self arg), and as pak points out, explicit "self" in the method def just moves the implicitness elsewhere in the code.

Re: How Python 3 Should Have Worked (2012)

#53
post #38

Earlier quoted context omitted.

People have been making the argument that QT or Wx should be the default for a while, the problem is and remains A: licensing or B: complexity of shipping "batteries included" distributions. For A, PyQT's license might surprise you: [1]. Python can not distribute this with the rest of the essentially-BSD-licensed Python distribution. For B, for instance, none of the linux distributions particularly want "Python", whi…

There's a new alternative to pyqt, though its name escapes me now.

PySide, though PyQt still has certain advantages if you can live with the licensing (which is either GPLv3 or a £350 per developer commercial license).

Re: How Python 3 Should Have Worked (2012)

#54
post #44
post #32

Earlier quoted context omitted.

>I hate implicit hidden defaults and assumptions. Your implicit hidden default is my handy abbreviation. Imagine if we didn't have contractions in English. For that previous sentence, is it really at all frightening that the "didn't" meant "did not" but we haven't (ha) written it out? Could it possibly mean anything else? Wouldn't English be all the more stilted and ugly if there were only one explicit and verbose wa…

Just for the record, you can do cool stuff that you couldn't do (as easily) if you had implicit `self`. Here's an example[1] that I'm moderately proud of. [1] https://github.com/MediaCrush/PyCrush/blob/master/pycrush.py...

[deleted]

Re: How Python 3 Should Have Worked (2012)

#55
post #35

Earlier quoted context omitted.

Ok but... you could do unicode in python 2, it just wasn't ideal. The problem was, python 3 doesn't actually solve most peoples actual day to day problems. Here are real problems with python: * It's slow (excluding pypy) * The C interface sucks (compared to something like Lua) and holds back language progress * It can't handle multicore well outside of multiprocess hacks (which are sold as "the right way" -- bullshit…

> Sometimes threads are useful). I would never in a million years look at a performance problem and given these two options: 1. Write the critical section in a faster language in serial (ie, rather than dynamic interpreted script, maybe compiled bytecode, or maybe even native machine code). 2. Write the critical section multithreaded in the script language. I would never think to use #2 first. I would always just mov…

Your argument is essentially that one can write slow things in Python and fast things in C, and that this solves the majority of problems (let's even be generous and call it 98% of them that fit neatly into these two categories). The trouble here is that "the number of programs" is a large number, and 2% of a large number is still large, and leaves important classes of programs without a good solution.

One class of programs left out in the cold is the network server. Now a network server must respond to a large number of requests. From a basic software engineering perspective, a 16-core machine should be responding to AT LEAST 16 requests at once (much more if some of the requests are IO bound). So the network server needs some kind of parallel processing (whether threads, subprocesses, or whatever you want to suggest). Under your philosophy, programs that need threading (thus all network servers) should not be written in Python, but somebody should be stepping down to C. While it is probably true that a very small minority of network servers should not be written in Python, the broader claim is absurd; you should be able to write reasonably-performing network servers in Python with relative ease. It is, after all, a server-side language; "writing a server" should be very high on the list of "things you can do".

Now more broadly, the existence of greenlet, Twisted, gevent, and their popularity (we're talking top-100 packages here) speak to the fact that there are a LOT of python programmers who have threading-related requirements. Are they on crack? Now mix in the new standard library stuff like asyncio (3.4) and threading is clearly an important enough issue to get major attention from the core committers. Are they on crack?

Now you might operate in a world where every time you need threads is an isolated case and it's fairly simple to drop down to C. But there are a lot of people (in absolute terms; I don't know if they are in the majority) where when they want threads the right solution is to use threads.

The thing I hear from the core committers whenever the GIL comes up is "if we worked on the GIL, we would be taking lots of time away from more important things." But when you look at the things they work on instead--unicode, iterators, ordered dictionaries, argparse, etc.--plenty of people in this thread are insufficiently motivated to upgrade. Are ordered dictionaries really more important than GIL work? To me, the answer is clear. I would rather have some progress on the GIL problem than every single py3k feature combined.

Re: How Python 3 Should Have Worked (2012)

#56

This misses the point of why Python 3 was invented: Unicode. Python 2's string handling is broken in the presence of unicode characters, often leading to subtle errors that wouldn't cause exceptions until far away from the place where the error was introduced, and oftentimes didn't produce exceptions at all, just wrong data. Strings were defined as sequences of bytes, and then provided a .decode method to convert the…

It's exceedingly rare that you need a sequence of codepoints. As evidence, consider that the native string types in many languages with pervasive Unicode support, such as Java and C#, do not provide a codepoint sequence.

Programs generally need to deal with textual data at one of three levels:

1. Manipulate strings and substrings. e.g., "does string x contain substring y"? Byte sequences of utf8 data are fine for this. You may need to normalize the data first, but that's true of codepoint sequences as well.

2. Deal with a small number of specific ASCII codepoints--e.g., the filename separator character. Again, utf8 byte strings are fine for this.

3. Deal with glyphs, including glyphs composed of multiple combining characters. You need to iterate to assemble the glyphs, so a codepoint sequence offers no advantages over a byte sequence of utf8 with a codepoint iterator.

A sequence of bytes is just fine as a native string type. Store Unicode data as utf8-encoded byte strings. Provide easy iteration over codepoints in utf8 strings, transcoding for I/O, normalization functions, etc. Call it a day.

Re: How Python 3 Should Have Worked (2012)

#57
post #12

Earlier quoted context omitted.

Unrelated: You do know that pypy also uses GIL. CFFI is to call C functions from Python. It won't allow you to run C extensions for CPython (something should implement Python C API).

I do know that; although they've done some interesting work with STM recently and hopefully that works out. I remember in the past hearing about someone actually submitting a patch to cpython remove the GIL about 10 years ago, but it was rejected because it made the language about 2-10x slower. IMO, that decision was INSANE. I have a 16 core machine right now and it can only really use 1/16th of it. Nobody uses pytho…

Have you tried multiprocessing? My experience is that people seriously overestimate how expensive processes are, especially on Unixy operating systems.

Re: How Python 3 Should Have Worked (2012)

#58
post #35

Earlier quoted context omitted.

> Sometimes threads are useful). I would never in a million years look at a performance problem and given these two options: 1. Write the critical section in a faster language in serial (ie, rather than dynamic interpreted script, maybe compiled bytecode, or maybe even native machine code). 2. Write the critical section multithreaded in the script language. I would never think to use #2 first. I would always just mov…

Your argument is essentially that one can write slow things in Python and fast things in C, and that this solves the majority of problems (let's even be generous and call it 98% of them that fit neatly into these two categories). The trouble here is that "the number of programs" is a large number, and 2% of a large number is still large, and leaves important classes of programs without a good solution. One class of p…

So here's some perspective on the concurrency problem. I write network servers for a living - most are in C++ or Java, but I would love to be able to use Python.

There are a number of high-level approaches you can use to concurrency. Shared-nothing processes. Threads and locks. Callback-based events. Coroutines. Dependency graphs and data-flow programming.

They all suck, and they all suck in different ways. Processes have large context-switching overheads, and take up a lot of memory, and require that you serialize any data you want to communicate across them. Threads and locks make it very easy to corrupt memory if you forget a lock, very easy to deadlock if you don't have a clear convention for what order to take locks in, and ends up being non-composable when you have libraries written under different such conventions. Callbacks require that you give up the usage of "semicolon" (or "newline") as a statement terminator; instead you have to break up your program into lots of little functions whenever you make a call that might block, and you have to manually manage state shared between these callbacks. Coroutines requires explicit yield points in your code, and opens up the possibility of a poorly-behaving coroutine monopolizing the CPU. Dependency graphs also require manual state management and lots of little functions, and often a lot of boilerplate to specify the graph.

Python has a "There should be one - and only one - obvious way to do things" philosophy, and with asyncio, Guido seems to have decided that the obvious way for Python is going to be coroutines. It's an interesting choice, and he's not alone in that - I recall Knuth writing that coroutines were an under-studied and under-utilized language concept that had many desirable properties. Coroutines free you from having to worry about your global mutable state potentially changing on every single expression, and they also give you the state-management and composition benefits that explicit callbacks lack.

There are parts of them that suck - like having to explicitly adds "yield from" at any blocking suspension point, and having to propagate that "yield from" down the call stack if added to a synchronous call. But having written a bunch of threaded Java server and (desktop) GUI code, a lot of callback-based Javascript, and a lot of C++ in both callback and dependency-graph style, all of those models suck a whole lot as well.

Re: How Python 3 Should Have Worked (2012)

#59
post #51

Earlier quoted context omitted.

> GVR himself has acknowledged everything I said I hate to be picky, but he only acknowledged portions of what you said. > but a couple decorators held this one back. @classmethod and @staticmethod are somewhat important language features to not break.

>@classmethod and @staticmethod are somewhat important language features And strings aren't? Whatever, I understand that there are tradeoffs and to people that only use Python, the aesthetic blemishes tend to matter less. To people that use it in the context of other languages, it sticks out like a bad paint job or a prominent stain. This, and many more opinions than I could express succinctly, are on the reddit thre…

> And strings aren't?

Not sure how explicit self breaks strings? You've lost me on the way I'm afraid.

If we're quoting Reddit comments at each other:

> You may be used to a different kind of magic. Perhaps the magic of a variable called this appearing inside your method, or the magic in which an un-prefixed variable name somevar is sometimes a local but at other times a member variable this.somevar. So it may take a little time to get used to Python's style, but isn't it only because you are used to the other magic?

Explicit self is hardly a burden after about 10 minutes of learning Python, and there's really little objective argument to be made in favour of or against it as opposed to everything else.

You quoted JavaScript as 'not needing it' before, and dear God, JS is the worst of all languages to reference, given how the this keyword is a calling context, which every man and his framework takes liberties with.

Re: How Python 3 Should Have Worked (2012)

#60

This misses the point of why Python 3 was invented: Unicode. Python 2's string handling is broken in the presence of unicode characters, often leading to subtle errors that wouldn't cause exceptions until far away from the place where the error was introduced, and oftentimes didn't produce exceptions at all, just wrong data. Strings were defined as sequences of bytes, and then provided a .decode method to convert the…

Ok but... you could do unicode in python 2, it just wasn't ideal. The problem was, python 3 doesn't actually solve most peoples actual day to day problems. Here are real problems with python: * It's slow (excluding pypy) * The C interface sucks (compared to something like Lua) and holds back language progress * It can't handle multicore well outside of multiprocess hacks (which are sold as "the right way" -- bullshit…

There're already huge discussions on explicit self, FFIs, and speed, so I'm not going to address those. I largely agree with you on both counts - I'm annoyed by them as well, but don't think that my opinion is going to change the Python maintainers'.

However, I'll point out that they're following a very sensible "stop the bleeding" maintenance strategy in targeting Unicode and async first. Whenever you need to upgrade a massive old codebase to a new way of doing things, your first priority needs to be to stop things from getting worse. That means getting everybody onto the new system, either via a shim or (worst case, but true in this case) by fiat, and then cleaning up the older code and introducing new cool stuff that's enabled by the new features.

The big problem with Python 2's Unicode handling was that it made things easy on people who handled only ASCII and then dumped the problem on top of people who wanted to handle Unicode and still rely on libraries from people who didn't know what Unicode was. As a result, the latter people just didn't use Python, because of the pain involved. Guido and the core maintainers (correctly, IMHO) identified this group of people as important to the future of Python, and so they want to make things viable for them even if it's inconvenient for a large section of Python's existing userbase.

Post reply on HN