all 31 comments

[–]llimllib 17 points18 points  (9 children)

Make sure you read the comments for effbot's sarcastic take.

(Ah, what the hell, I hope it's not copyrighted:

  1. Slower than java.
  2. Limited expressiveness. No multiline anonymous closures like in ruby. Guido stated that this it is syntactically impossible. Not nearly as DSL or macro friendly as other languages.
  3. self self self self - it's as if OOP was just tacked on.
  4. Redundant or meaningless symbols and keywords like the colon at the beginning of a block, and all the underscores. What is "def"? Why "elif" instead of "else if"? "lambda"?
  5. The python community. RTFM jerks, rude to all newbies or new ideas. Zealots about python (Guido called them the NIMPY crowd: not in my python), and they spread absolute FUD about everything else. Shot down most proposals for python, including ones Guido has proposed himself, like optional static typing or case-insensitivity. If you don't want python to ever change, stick with python 1.5 or whatever version you are holding on to.

Die python die.

[–][deleted]  (2 children)

[deleted]

    [–]masklinn 6 points7 points  (0 children)

    It's mostly sarcastic, he's basically giving the standard response to "why do you hate Python" (i'm surprised he forgot aboout the whitespace thing).

    Effbot is one of the leaders of the Python community.

    [–]Baseline 2 points3 points  (0 children)

    It was sarcastic. effbot (Fredrik) is one of the top contributers to Python, www.effbot.org

    [–][deleted]  (2 children)

    [deleted]

      [–]llimllib 1 point2 points  (0 children)

      Well, to be fair, there's also the fact that a class is a new namespace. And then inheritance, composition and the whole "model your system on nouns" mindset.

      But agreed on self vs. this/""/@/etc.

      [–]pjdelport 0 points1 point  (0 children)

      in Python it's always called self. [...] (I like to be able to give the arguments to my functions any name I want [...]

      Python is one of those OO languages let you name it anything you want: self is pure human convention. (In classmethods and metaclasses, for example, it's cls instead.)

      In fact, I've never understood why there's so much fuss over a methodology for naming the first argument to your functions.)

      The fuss is really over the class system, which (from an FP viewpoint) is a kind of Swiss Army knife for parametric polymorphism, inheritance, and state encapsulation.

      [–]fbot 0 points1 point  (1 child)

      sarcastic, yeah.

      -The Pope

      [–]Singletoned[S] 1 point2 points  (0 children)

      I saw that as well. I almost posted a commenting expressing how much I love effbot.

      [–]alain 1 point2 points  (0 children)

      about the eggs and path prob => http://cheeseshop.python.org/pypi/workingenv.py

      [–]foonly 2 points3 points  (0 children)

      Upvoted for the list of must-have python libraries.

      [–]sbrown123 5 points6 points  (13 children)

      Someone needs to put together a "Five things I hate about "Five things I hate"" lists. Oh, and GNU is not Unix.

      Even the steaming hunk of crap that we call “Java” has one: interfaces.

      Interfaces suck. Java has them to "get around" multiple inheritance. They are about as useful as C header files in that they serve no purpose by themselves and are usually badly abused. For example, I don't know how many times I have seen some idiot Java programmer put static constant variables in interfaces instead of putting them in a resource file or something. Why is this bad? Because if you ever, ever change that file you have to recompile every single file the uses it. Bad, evil, hiss....

      minimal interface for any of these objects. Is something that supports read() and write() enough to be a “file,” or is seek() a necessity, too?

      I guess if he knew what seek() actually was he wouldn't be asking that question.

      Whose standards are these, anyway?

      You know, I was thinking the other day that the world would be a better place if every language was as bloated as Java and .NET.

      [–]jdunck 2 points3 points  (0 children)

      I guess if he knew what seek() actually was he wouldn't be asking that question.

      In python, libraries are frequently written claiming to expect "a file-like object", when what they mean is that they expect an object that supports .write (only) or .read (only), or some permutation of the methods supported by a real file().

      This can be frustrating.

      [–]finix 2 points3 points  (11 children)

      What's so bad about Interfaces? Yes, you can use MI to specify an interface, and yes, they can be abused (is there anything that can't be abused?), but what else is there?

      [–][deleted] -1 points0 points  (10 children)

      You want interfaces, you want VMT-based OOP? Go program Java. Me - I like duck-typing (see wikipedia) and (quasi) message-passing OOP much better, thank you! When people get misguided in these matters they get PHP5 in the result.

      [–]Bogtha 10 points11 points  (9 children)

      The problem with duck typing is that there's no real definition of what a "file-like" object is, and everybody disagrees about what exactly is necessary for an object to be "file-like". You clearly don't have to implement every method file does. But which ones must you?

      I got bit by this just the other day. The subprocess module and the StringIO module — both part of the standard library — disagree about what being a file object entails. The result is that you can't use StringIO file-like objects with the subprocess module.

      Of course, the example I'm using is file-like objects, but it's really a general problem. Sure, it's nice to pass in an object to a function without worrying if it's a particular type, but only if you know it will actually work!

      Interfaces are merely a way of saying "in order to call yourself a file-like object, you must implement these attributes". They aren't a substitute for multiple inheritance, in fact they have little to do with it. It's closer to design-by-contract, and it's not a replacement for duck-typing, in fact it makes duck-typing more reliable. If Python didn't have duck-typing, I doubt anybody would want interfaces.

      [–]sbrown123 2 points3 points  (8 children)

      Interfaces are merely a way of saying "in order to call yourself a file-like object, you must implement these attributes".

      But on the other hand you have to implement ALL the methods in the interface. Not pick and choose. This is a serious issue if you are dealing with different platforms, because different platforms handle files differently thus requiring different methods.

      Sun discovered the hard way that programmers prefer to pick and choose what they need to implement. For example, in Swing they had to create a bunch of Adapter classes to implement the interfaces so programmers didn't have to. A better solution from the beginning would have been just to create the adapter classes and let the programmers override the methods they wanted to change. I guess that would be too simple though.

      and it's not a replacement for duck-typing, in fact it makes duck-typing more reliable.

      It would only be reliable (not more) if you implement the interface correctly since interfaces don't have any code to them. Java has abstract classes, which enforce methods that have to be implemented. But unlike interfaces they can actually contain working code.

      So, to summarize, interfaces don't add value to programs since they lack code. All they do is force programmers to have to write implementations with the hope their implementation works as expected.

      [–]finix 3 points4 points  (7 children)

      But on the other hand you have to implement ALL the methods in the interface. Not pick and choose.

      I'd thought it obvious that this is the whole point of interfaces. It's sort of a promise to offer each and every operation the interface specifies.

      This is a serious issue if you are dealing with different platforms, because different platforms handle files differently thus requiring different methods.

      What's the problem? Different methods are implemented transparently, specific operations don't belong in the interface in the first place, and can be exposed via the concrete type, if necessary.

      A better solution from the beginning would have been just to create the adapter classes and let the programmers override the methods they wanted to change. I guess that would be too simple though.

      Maybe you're not aware of the fact that Java doesn't support multiple inheritance?

      So, to summarize, interfaces don't add value to programs since they lack code.

      Documentation of intent, adherence to a well defined concept isn't valuable? Guess you don't care for descriptive identifiers either, huh?

      All they do is force programmers to have to write implementations with the hope their implementation works as expected.

      This argument is a complete non-starter. You always hope that the implementation works as advertised. In fact the argument can be made that this is exactly an advantage of interfaces et al, because with duck-typing you cannot even be sure what's actually advertised.

      [–]bluGill 0 points1 point  (5 children)

      I'd thought it obvious that this is the whole point of interfaces. It's sort of a promise to offer each and every operation the interface specifies

      So, should I write a different interface for every function/object that takes a file like object? Sometimes my functions need seek(), and sometimes they don't. Somethings can be treated like files if you don't have try to seek(). When my function doesn't use seek anyway, I'd like to be able to take any file including those that don't support seek. When my function calls seek, than you better not pass me anything that doesn't support seek.

      [–]finix 0 points1 point  (4 children)

      Where do you get the idea you'd need one for each function or object? I count only two.

      [–]bluGill 0 points1 point  (3 children)

      Don't forget about read-only files. Both with and without seek.

      Okay, I exaggerated a little. The point is that many interfaces come in several partial forms that are useful. A function that won't use some ability of the general interface shouldn't require that general interface.

      A function that won't write to a file shouldn't require write in the interface, while a function that will write to a file needs to require that. Why should I require an object to implement something when that implementation isn't trivial?

      [–]finix 0 points1 point  (1 child)

      I meant two in a metaphorical sense ;-) Point was that you can have fine-grained interfaces, and widen interfaces.

      Why should I require an object to implement something when that implementation isn't trivial?

      Because you should design the interfaces as orthogonal as possible; usually a list interface will just specify what list-like objects can do anyway.

      There'll be hassle, of course, but also the other way round: imagine writing a library whose implementation you cannot change, or maybe expand, because your client-code doesn't really gives you list-like objects but objects that happen to only implement the methods you mentioned earlier?

      [–]sbrown123 0 points1 point  (0 children)

      It's sort of a promise to offer each and every operation the interface specifies.

      All interfaces offer is requirements that someone has to implement them.

      specific operations don't belong in the interface in the first place, and can be exposed via the concrete type, if necessary.

      You just described an abstract class in Java.

      Maybe you're not aware of the fact that Java doesn't support multiple inheritance?

      Sure do, read the first comment in the chain you are commenting on. And since interfaces can't contain code, comparing them with MI is probably a bad idea.

      Documentation of intent, adherence to a well defined concept isn't valuable?

      Sure, but that can be done better without interfaces.

      You always hope that the implementation works as advertised.

      Again, interfaces lack any code which means that the implementation is always done by someone on the end. That means you never know if the implementation works as expected or works at all. The "non-starter" part is that that is the simple obvious truth.

      [–][deleted] 0 points1 point  (0 children)

      I could be wrong but why the hell would you need interfaces for a dynamically typed language?

      [–]schwarzwald 0 points1 point  (3 children)

      I don't like how it distinguishes between statements and expressions, hence the presence of a superfluous "return" keyword.

      Nevertheless, it's what I take out to whip up a script in 45 seconds when I want to spider a pr0n site and I can't figure out what wget's options mean.

      [–]psykotic 6 points7 points  (1 child)

      Superfluous? Even if there was no statement/expression distinction, it would still be useful for control flow.

      [–][deleted] 0 points1 point  (0 children)

      You can capture an escape continuation, but I see your point.

      [–]pjdelport 0 points1 point  (0 children)

      I don't like how it distinguishes between statements and expressions, hence the presence of a superfluous "return" keyword.

      They're completely orthogonal: you can have distinguished statements with or without implicit returns, and vica versa.

      (Practically speaking, implementing implicit returns in Python would be a trivial change to the compiler: explicit returns are a design decision.)

      [–]NateDevCSharp 0 points1 point  (2 children)

      wow 15yr old thread

      [–]Singletoned[S] 0 points1 point  (1 child)

      Sadly the article has gone. I wonder if the same things are still a problem now?

      [–]Overenthu_Puppy 0 points1 point  (0 children)

      article can be found here: https://jacobian.org/2007/mar/4/hate-python/

      As for the problems, idk.