Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
What Python Fixes (paulgraham.com)
67 points by garret on June 2, 2010 | hide | past | favorite | 101 comments


Python is like a piano: anyone can sit down and tap out Three Blind Mice within a few minutes, but a virtuoso can play Rachmaninoff's Symphony No. 2.

The language is well designed; the barrier to entry is low; the language allows for progressive discovery of its advanced features; it is powerful and flexible enough to allow an arbitrary combination of imperative, object oriented and functional programming; and the large, mature ecosystem of third party libraries means it can already do about 80% of just about any problem you can think to throw at it.


Piano is actually somewhat notorious for being excessively baroque and difficult to play at the higher skill levels, the keyboard having been originally designed to play only in a single key with a different tuning system.


I didn't know that and that sounds interesting to me. Can you elaborate? (I know this is an article about Python, but I love pianos)


Sure. It's actually pretty interesting, and involves math.

http://en.wikipedia.org/wiki/Just_intonation http://en.wikipedia.org/wiki/Equal_temperament http://en.wikipedia.org/wiki/Well_temperament

Basically, when you play music aloud naturally with your voice or acoustic instruments where you have complete control of the pitch, people tend towards using whole numbers for representing harmony, like 3:2, since it sounds the best. Unfortunately there are 12 notes in an octave in the Western music system so you end up with bad ratios if you want to use instruments which are tuned to play anything more than a single key. If you are in complete control of your pitch, like with voice or violin or other stringed instruments, the all of the players can adjust their intonation on the fly when the keys change, and still keep the nice whole number ratios.

Enter church organs, which are huge, expensive, and can't be tuned while they're being played. But they're very nice and impressive. So they were tuned to play in only one key -- C. That's why the keys representing the scale of C major on a keyboard are all white, and the other (less important) notes are smaller black keys. You won't be pressing these very often, better to get them out of the way.

Then along came some math people who calculated tables of compromises that ended up giving a pretty decent sound to harmonies, but was laid out in a way so that you could play different keys without having to adjust your tuning or intonation. There were different systems, but they were referred to as having temperament. Hence the name "Well-Tempered Clavier" in the famous composition for keyboard instruments, which made ample use of the newfound ability to change keys whenever one pleases.

So now there are a bunch of keyboard players who can suddenly play in any key they want with the new tuning systems. But the keyboard layout is still same one used for playing only in C. That all happened hundreds of years ago, but we're still stuck with the original layout for keyboards.


Wow! That's fascinating. I'd lke to see more music related posts 'round here


This was posted to HN a month and a half ago:

http://news.ycombinator.com/item?id=1283523


It sounds rather like the origins of the QWERTY keyboard, which was designed in the late 1800s to minimize mechanical jams when the typebars swung up to hit the paper but persists to this day due to lock-in.


QWERTY was designed as a compromise between speed and jams. Characters which are frequently used as pairs together are placed on opposite sides, one for each hand. This has the effect of letting you use both hands pretty frequently. One of the compromises was that only the vowel 'a' ended up on the middle row. 'Maximally efficient' layouts like Dvorak are not provably any faster under real conditions.


As a Dvorak user, I can testify that, while it may not be faster (I didn't have an appreciable speed increase after switching), it sure feels more comfortable and natural when you do most of your typing on the home and upper rows, and common key clusters fall nicely in pinky-to-index order.


Python fixes maintenance.

You know that sinking feeling when you crack open 3-year-old code written by your predecessor's predecessor and realize it's a load of garbage and that you'll never be able to fix the bug?

Yeah, well, with Python that doesn't happen. At least, not at all frequently.

Python forces you to spend a bit more time up-front and then saves you time each and every time you need to read, edit, or improve your code. People choose Python for the same reasons they choose good testing practices. Python's a mature language for mature developers who want to produce mature software.


> well, with Python that doesn't happen. At least, not at all frequently.

That's a bold statement. It happened to me just last week.

The difference from Perl is that common tasks are standardized ... stuff like OOP is built-in, so you don't have to chose or stay in touch with several frameworks for doing OOP, and you could care less about integration issues between modules that use different OOP systems.

It also has a clean syntax, which makes (good code, written by good developers) readable ... but that's not what bugs me about Perl ... after all, why should you read text in some language (natural or not) if you haven't bothered to learn it?

That's about it. Otherwise I'm beginning to hate Python's limitations.


>> well, with Python that doesn't happen. At least, not at all frequently.

> That's a bold statement. It happened to me just last week.

Look, different strokes for different folks: I'm not trying to suggest that you should use Python; I'm explaining why I do.

That said, anecdote ≠ data. Your cited experience doesn't match up with what I've seen in a decade as a Python developer, and, more importantly, it doesn't match up with the data I've seen [1] suggesting that Python code takes 1/2 to 1/4 as much time to maintain as other comparable languages.

When I choose Python, it's because I know that the vast majority of my time is spent maintaining code (mine and other people's), not writing new code. I choose Python because, of all the languages I've tried in my career, it's the one that makes this task easiest.

[1] To forestal the obvious questions: no none of this data is publicly available (at least to my knowledge). I can share some rough details -- contact me privately if you want them -- but you'll pretty much have to either believe that I'm reliable or decide that I'm full of shit. I don't much care either way -- again, this is about my choices, not evangelism.


>>> well, with Python that doesn't happen. At least, not at all frequently.

>> That's a bold statement. It happened to me just last week.

>Look, different strokes for different folks: I'm not trying to suggest that you should use Python; I'm explaining why I do.

You made a pretty definitive assertion, and when someone points out that they had an experience to the contrary you say "different strokes for different folks"? Seriously?

I like Python a lot. I've been using it for about 12 years now. My experience doesn't really line up with yours.

I've found that Python is great for writing small (<2000 loc) programs. However, every single time I've seen a large project written in Python it's ended up collapsing under its own weight.

I'm sure I'll get flamed for saying this, but I think part of the problem is Python's dynamic nature. Python is the dynamic language I have the most experience with, so perhaps I'm over-generalizing, but the problem I've seen with large Python projects is that they get to a point where a major refactoring is needed and it's impossible to pull it off because of the dynamic nature of the language. Perhaps with 100% test coverage things would be easier, but in the real world that's rare/nonexistent. (Also, I find that more tests are necessary in Python than in a static language because you end up having to test a lot of the same things your static language would have been proving for you.) In the bigger Python projects I've seen they eventually rewrote the whole system in a static language.


It's OK if your choice is Python, it's my choice too, for now at least.

But regardless, if you haven't worked with badly written Python code that makes you want to switch career, that's just luck.


Can you elaborate on what python limitations really frustrate you?


My opinion very subjective ... I'm looking for 2 things out of a programming language ...

1) (proper) anonymous code blocks ... it's the only sane way to have declarative APIs, although I've found for some tasks that Python's features (like decorators, meta-classes) are enough ... but not for all things I want to do

2) a limited form of macro support ... like, I want to get the syntax-tree out of a closure, instead of a reference to the compiled method ... to abstract the way some processing takes place. In Python you can workaround it with some magic (a la Django's ORM), but I love to be able to write Python syntax for those queries (e.g. something like Linq) ... and have for example a unified querying interface for collections of data


> 1) (proper) anonymous code blocks ... it's the only sane way to have declarative APIs, although I've found for some tasks that Python's features (like decorators, meta-classes) are enough ... but not for all things I want to do [.]

Is the anonymous bit necessary? Or asking another way: What about throw-away names? I find that even in Haskell I rarely use lambdas, but tend to name nearly all of my functions.


Sad to say it, but given enough programmer ambition, eventually any language is going to annoy you this way!


Can you go into more detail about how Python fixes maintenance? I'm really curious what language features of Python are conducive to good or easy maintenance, and how those features are unique to Python. Color me skeptical, but I can be convinced.


I'm really curious what language features of Python are conducive to good or easy maintenance

My guess is that "Less is More" in this situation. Python often does tend to read like pseudocode.

The problem with this, though, is that idiocy has seemingly infinite resources on its side. Occasionally, you will have an outlier who has vast holes in their understanding of programming and writes large amounts of jaw-dropping bad code and can do this even in simple elegant languages. In fact, there's one on the team I'm working with right now. (He was maneuvered onto the testing team to mitigate the damage.)


Occasionally, you will have an outlier who has vast holes in their understanding of programming and writes large amounts of jaw-dropping bad code and can do this even in simple elegant languages.

One interesting quirk of Python is that such code superficially resembles good code in everything except the length of functions and methods.


Perhaps not always a good thing. Kent Beck's preferred Smalltalk indentation style made good Smalltalk look good, and bad Smalltalk look really bad. That's actually useful.


Could you please elaborate?


As far as "Less is More" goes, this could be practiced in other languages by voluntarily choosing a simpler subset of features in a language with a complex feature set. Think RISC style in CISC architecture.


> Can you go into more detail about how Python fixes maintenance?

It's pervasive, so there isn't any single feature I could point to. Python embraces a general philosophy that starts from the observation that programmers spend much more time reading code then they spend time writing it [1]. Thus, most trade-offs between readability and writability should fall in favor of readability.

For instance, let's look at the whitespace thing. It's the first thing new Python users bump up against, and it's a source of perpetual controversy. There's a not-insignificant group of users who try Python, hit whitespace-for-control-flow, and leave in a huff. I won't argue that these people are wrong, but I will point out that it's ridiculously nice to have all the code you read always use the same control flow indentation conventions. Though Python's my primary language, I do more and more work in JavaScript theses days, and I could go on and on about my frustration trying to follow the flow of code written with varying intendation, brace, and semicolon styles.

This is encapsulated by the observation, from The Zen of Python, that "there should be one — and preferably only one — obvious way to do it" (http://www.python.org/dev/peps/pep-0020/). At its best, Python code eliminates any stylistic differences. This sounds like it's a stifling of creativity (and perhaps it is), but in practice it means maintaining someone else's code is just as easy as maintaining your own.

Take Django, for example: I can tell at a glance who's responsible for any given line of JavaScript in the framework, but it usually takes digging into SVN history to discover who's written some given line of Python [2].

Or look at Python's general lack of language features. There's a `while` loop but no `do ... while`. There's a `for` loop, but it's really just `foreach` and nothing else. There's `if/else`, but no `switch/case`. There's language-level primitives for basic types list, dicts and tuples, but not regexes, ranges, heredocs, or anything else more exotic. Python's a little language; I can keep it all in my head. I never have to run to the docs to find out what some obscure syntax does; there isn't any obscure syntax.

If I got to do green-fields development all of the time, I might very well choose a different language. I've certainly used languages that are easier to write. But I live in a world filled with old code, so I've tried to make sure my career involves code that sucks as little as possible.

[1] Indeed, I'd argue that reading code — especially other people's — is the most important skill a developer can have. I'd go so far as to argue that asking people to write code during interviews is pointless; we should be asking them to read it. But that's another show.

[2] I'm often surprised to find that the code was written by me, though I'm not sure if that's a praise of Python or a remark on my generally shitty memory…

[3] Well, until Python 3. Again, that's another show.


> I'd go so far as to argue that asking people to write code during interviews is pointless; we should be asking them to read it.

An excellent idea.

> [3] Well, until Python 3. Again, that's another show.

This doesn't seem to be referenced in the body of your comment. What are you referring to?


Thank you for the reply. I've had some opportunity to work with Python, read some other people's code, and yes Python lends itself to regularity of form. If you squint and turn your head a bit, you can almost see the abstract syntax tree that the compiler ought to create. That is beside the point I think. For me the most difficult thing in maintenance is understanding the intention of certain functions, classes, methods etc. Why did the original author make the choices that he made? What exactly was the intent? Sometimes the accompanying commentary is short on those details. Commentary on why a particular design choice was made and what the intent of the design was is many times more valuable to me when I maintain code.


>For instance, let's look at the whitespace thing.

I immediately fell in love with significant whitespace. Since I was already indenting anyway, why not make it meaningful and skip the additional overhead of matched curly braces?


I am in the same camp. Interestingly I also find Scheme's approach quite nicely: The syntax is so uniform and thus the editor support so good, that you can just pretend that you have significant whitespace and that the parens are just a hint for your editor.


You might want to have a look at Haskell, if you like this trade-off of making writing somewhat more complicated but reading much simpler.

Also if you browse some PEPS (and other sources) you will find that Python and Haskell's history are more intertwined that one would guess at first.


I'm willing to bet you haven't seen a lot of Zope 2 code. :-)


Given that he developed Django, the framework that thankfully euthanized Zope, he's probably seen things us people wouldn't believe.


OTOH C is a more difficult language to use, so it takes a certain level of care to write in it. Does that mean that any working C program is readable and maintainable as long as you crossed that threshold and now know how to read and write C?


Python is not static

Python is not monkey-patched

Python is not multiple coding styles

Python is not enterprise

Python is not overly verbose

Python is not overly concise

Python is not lacking in libraries

Python is not a dialect

Python is not manual memory management

Python is not hard to learn

Python is not a roadblock to writing code quickly

And really the only important issue: Python is not a pain to use.


Not all of these things are 100% true, but those that aren't are true enough to make Python less painful to use than a lot of the alternatives.

Python is not multiple coding styles - not entirely true, but probably true enough.

Python is not monkey-patched - again not entirely true, but maybe true enough.

Python is not overly concise - mostly true, though I've seen abuses of array slicing and passing/storing/calling functions.

Python is not overly verbose - pretty much at the mercy of whoever is writing code, but again, seems to be true enough.

Python seems to be pretty good or good enough in a lot of ways, and deserves credit for this. The far-sighted view will recognize it as a local maxima, however.

(A "perfect" language is like a perfect predator. A tireless, scentless, invisible, silent, indestructible, ultra-fast killing machine would probably wreck its environment. Considered in the context of evolutionary change, it's practically impossible for such a thing to come about.)


I agree completely. Python isn't perfect but, for me, it solves the issues I listed. I don't like Java and Perl can be the Pit of Despair. I don't have to worry about 4.days working depending on if I loaded a library that loaded another library that properly patched the integer class and the Scheme/Lisp (perceived by me) clusterfuck of libraries, reader macros, slight incompatibilities etc is just non-existent.

I would drop python in an instant of a better language came along. For me, the question isn't what it fixes, but what it succeeds at. It makes my professional life less painful and that's really the only reason I need.

edit: Also would like to not that the original article seemed fairly pointless. It's not really saying anything of substance.


This. (or rather, self)

The answer to 'Why Python?' is a lot better than what you're going to get for Ruby, Scheme, or the continued use of Perl. At least PHP has its execution story going for it (immediate mode) even if the language sucks ass.

'Why Arc' doesn't even have a polite answer at all. There's a log in pg's eye, and he's here picking at motes.


For me, Python is the only language that addresses the human side of programming well. You just plain make fewer mistakes with Python, and it's way easier to reload code into your brain after not looking at it for a while. The readability and obvious syntax has vastly more far reaching effects than one thinks it will when first learning it. It's amazing how much more productive one is in a language that is easy to read, easy to type, and easy to figure out what the most likely way to do something is. I reach for pdb more than a manual because most of the time I can guess what an api will be, and if not, 5 seconds of introspection reveals it. Ruby is well designed for computers, but Python is better designed for us fallible humans who have to type into computers. ;-)


Further to this, as fallible humans, we usually get the design wrong on the first try. The truly multi-paradigm nature of python has for me made it a really great language for refactoring and iteratively arriving on a good design. You can write proto-types really fast, and turn them into more formal architectures very smoothly.


I think that Python "fixes" reliance on language features. Sure, Python has a lot of neat features compared to say C# or Java, but as a dynamic language it really isn't anything that great.

But Python is probably the best example in recent history of a language that made it big not because it was anything radically new or innovative, but because it has a great standard library and a solid, mature implementation.


Agreed. In many ways, Python is the most "boring" of the modern dynamic languages, in the sense that it trades exciting features and hip syntax for predictability and elegance. So it gets a lot of the productivity, conciseness, and power of other dynamic languages without nearly as much cognitive dissonance for people familiar with C or Java.


I was going to say that Python fixes in programming languages whatever Markdown fixes in other plain-text markup syntaxes. But thinking about it, you're right -- it fixes the tendency of other languages to invent special syntax to represent standard, frequently used concepts. Python follows the conventions you might use when sketching out an idea on a napkin, and takes each convention to its logical, parser-friendly conclusion.

There are few language features that would be hard to succinctly express in a line of pseudocode. ("If the implementation is hard to explain, it's a bad idea.")

Result: straightforward, algorithmic code looks like pseudocode, and any code that uses special language features really pops out -- if you see an at-sign or double-underscores, you know something Python-specific is happening.


Obligatory: http://norvig.com/python-lisp.html

Python to me is the new world where any immigrant has a niche for whatever he seeks.


SciPy+NumPy+MatplotLib == Matlab ($2k+) returns true for most applications

That's good enough for me to not bother with any other scripting language.


Sadly matlab still is much easier to use and understand for engineers, which is one of its, if not the, primary market(s).


I agree that numpy python programming is nowhere near matlab for ease of use.

I prefer using python for machine learning tho. I dislike the libraries written in matlab.

Is numpy+python faster than matlab?


To be honest I have no reason to conclude that one is faster than the other but I would hope that given its age and girth matlab is more optimized.

The main reason I say matlab is better for engineers is that its documentation is beyond amazing, if you think of something you need you search in the help browser and there is a good chance it is there with substantial information (something that is much harder with the math/science python libraries) also if you know a functions name you just type: help function and get plenty of information which helps when you forget how to use something and need a quick lookup.

I have done some things with scipy but nothing more than solving some odes and I must say even with all the pains of matlab with writing separate files to solve odes and other such things plus some syntax grievances it is still the easiest solution for me.


Since both (I assume) are calling the same BLAS and LAPACK libraries underneath the scripting niceness, it's likely they're very similar in speed.


Of course it depends what you're trying to do. I'm pretty sure that numpy/scipy have a lot more overhead than Matlab for everything that _isn't_ just a blas/lapack call, but I don't have the numbers to back it up.

I do know that I tried rewriting one of my C++ codes using scipy/numpy and it was about a hundred times slower for that particular task (which did happen to involve very large matrices, approaching the limits of memory).


From experience that kind of slowdown for pure numeric algorithms happens when your numpy/scipy code is structured in a way that it makes extra unnecessary copies.


Matlab also recently has gotten much better in its support for function approaches. You need those for e.g. numerical integration and solving differential equations.

The earlier solvers took strings with the name of a function whenever they needed a functional argument. Nowadays Matlab provides `function handles' to refer to a function without calling it. The syntax is @function_name, they need this special syntax, because just mentioning function_name itself in your code, calls your function without arguments.

Matlab even support proper closures with lexical scoping, now.


Show me proper Matlab data structures, I/O libraries, and string manipulation and I might actually care about language features...

I do agree with all of these advantages of using Matlab in an environment where my data is already cleaned and normalized; I just rarely find myself in that position.


Matlab has made great strides. They even have proper data structures now. String manipulation also got somewhat better, if I remember correctly. The problem is, that (like with C++) the standard string isn't the `right' string with all the advanced bits.

I do not know about I/O libraries. All my Matlab knowledge basically comes from helping out friends with Matlab problems, and reading the manual together with them.


As someone who spent a significant fraction of today trying to get scipy and numpy installed on one of his machines (and failed) I can totally see your point here.


We would love to improve your experience in installing SciPy and NumPy. I'd like to invite you to join the mailing list and raise these issues so we may address them.

The easiest way to install the suite of scientific computing Python packages on Windows may be PythonXY or Enthought EPD. Under Linux and OSX, users seem to have few problems.


Python is a Lisp where the interface to everything is a domain-specific language that visually resembles simple imperative programming.

If Python has fixed anything, it has been because of its roots as a teaching language, with a culture for treating the structure of the language as a tool. Blur the lines between syntax and semantics, and your only option is to create things that can be expressed in both realms at the same time.


Python is a Lisp - I do not understand this. Howso?


Garbage collection, syntax modification, runtime code evaluation.


> syntax modification

Hmm, have I missed something? What features are you talking about?


I guess you do not know very much about Python.


Do you mean decorators? How about metaclasses?


It isn't, and people who say so probably don't know Lisp very well.


It's not Common Lisp, or Scheme, but it's a "Lisp" in the sense that it is a dynamic language with properties in the spirit of the original LISPs, with the notable exception of not writing directly in the abstract syntax tree.

I wouldn't actually call it a Lisp on its own. It is a derivative, a less directly powerful form. "It's a Lisp where..." in the same way that a unicycle is "a bicycle where..." or something.


> I wouldn't actually call it a Lisp on its own. It is a derivative, a less directly powerful form.

But you could argue every language is a derivative of another, or another's functionality, or style, or...

To fairly call a language "a type of X" there honestly has to be a lot more in common with it.

> "It's a Lisp where..." in the same way that a unicycle is "a bicycle where..."

... it has wheels??!!

I'm sorry, it's not Lisp. It has several of Lisp's useful features, but it's likewise missing a large number of them; to the point that it's a real disservice to glibly compare it and conveniently ignores a lot of the power of Scheme, Common Lisp, and their true ancestors/siblings.


I didn't say "it's Lisp." I said it is a Lisp where and then qualified it heavily. To say I was stating anything else is to put words in my mouth.

If you intentionally misread the very simple analogy that was made in order to give yourself the opportunity to make an inflammatory reply, then there is not much else I can say to sway you.

However, the comparison was not glib. I'm not conveniently ignoring anything. Perl was compared to Lisp when it first appeared, but it is not anymore. People compare JavaScript (mistakenly) to Scheme all of the time, and it is not really Scheme at all. Nor is Python actually Scheme or Lisp. It is an imitation of some of the features of Lisp, but specialized to some other purpose.

If you were replying in hubris with the intent of quashing the unqualified newbie who doesn't know anything about Lisp, allow me to offer some details.

Things Python lacks compared to Scheme: Continuations, tail call optimization, optional typing annotations (like in Bigloo etc.), direct AST construction, explicit metaprogramming, hygienic macros, formal specification (indeed, Python is not a language that can be parsed), lambdas with seq (Python lambdas are expressions only), a dynamic-wind solution for generators, and more.

Things Python has in common with Scheme: readily accessible FFI, rebindable syntax (as well as during runtime), garbage collection, eval, implicit metaprogramming, yielding, standard library with lists + associative maps + bytestring manipulation, extreme late binding as desired, symbol manipulation, lexical (and dynamic) scoping.

Or would you prefer to keep flailing around in anger?


Perl was compared to Lisp when it first appeared, but it is not anymore.

Certainly it is; see the book Higher Order Perl, for example. If you've read SICP, HOP will seem familiar.


Lisp is defined by the fact that the fundamental data structure is the list, and that all of the code itself are also those lists.


If one writes Python using strictly list comprehension, then i guess python could-be-kind-of called lisp.


Putting on a wolf costume does not make me a wolf.


Python is a Lisp (with the notable exception of not writing directly in the AST) in the sense that my aunt is my uncle (with the notable exception of not having balls). (Reference: http://en.wiktionary.org/wiki/if_my_aunt_had_balls,_shed_be_...)


I think there are dozens of languages that would be considered lispy before python would.


Lisp is, and always will be, the no true Scotsman fallacy actualized as a programming language.

Clojure is curb stomping Lisps in applicability. I get lisp in general. I use Emacs to write Python. Lisp still can't get it done. And It is whatever people are doing this decade. Sure Lisps should be better, but it's always the fault of someone else that lisp hasn't taken over the world.


Python could be improved a bit, just remove the damn underscore from it.

Everything else is love.


To me as a Lisp user, Python breaks more than it fixes. Lexical scoping? Nope, can't have it. Code as data, data as code? Not really. Literals for data? Compilation to native code? Compiler/interpreter warnings? Warnings for name collisions when importing? Standard for the language? Nope.

And I don't really buy the argument that Python is simple and clean. It has multiple inheritance, metaclasses, operator overloading, decorators and whatnot. Also the type system is broken, a deriving class can define an overriding method that has incompatible signature, rendering isinstance powerless (yes, I know you probably shouldn't use isinstance much anyway, but dammit, it should at least mean something).


And I don't really buy the argument that Python is simple and clean.

Yes, but consider the competition. Python is a significant margin above average, but this says as much about the sorry state of computer languages in general as it says about Python.

Heck, English is considered an "easy to learn" language among human languages, and it's a mess!

Really the problem is with human beings.


(More specifically, English is said to be "easy to learn, hard to master" (because as you say, it's a mess).)


Python does have lexical scoping though. The only difference with languages like e.g. Scheme is that you cannot rebind variables in the enclosing scope.


You mean like this?

    (define x 3)
    (let ((x 38))
         (display x)
         (newline))
    38
Actually, you probably meant that this doesn't work:

    (define x 3)
    (begin (define x 38)
           (display x)
           (newline))
    38
    (display x) (newline)
    38 ; we want 3 here
EDIT: fix formatting


More like this:

  def f():
      x = 1
      def g():
          x = 2 # creates new local variable x
          # no way to assign new value to x in enclosing scope!


I'm probably naive for even asking, but why would you want to be able to change the value of x in the enclosing scope, unless you passed in a reference to it to g() (which doesn't exactly even work, as Str and numericals are immutable). If you had to change the value of X, make it a return value of G and assign that within the enclosing scope.

I view this as a benefit - less accidental stamping on variables/etc. I wouldn't consider myself A+ #1 programmer by any stretch though. This sort of thing seems like it would enable too many 'side effects' though.


Lispy languages like to use this construct for all kinds of purposes. See the appendix at the end of http://paulgraham.com/icad.html for examples.

You can do this in Python too, but it requires a bit more work. Python is asymmetrical here; you can see a variable in an enclosing scope, and if it's a mutable object you can change it, but you cannot reassign the name.


Python 3 lets you use the statement 'nonlocal varname' and it will grab it from the outer scope, as well.


Ah, yes. I should have mentioned that I was talking about Python 2.x.


I agree. I first learned to program in Python and then started learning about other languages with more options enabled. Coming from a Lisp to Python would have felt strange. Maybe worth it to use a nice library or program?


Wholeheartedly without trolling, but admittedly with some bitterness, and with much experience in Python, Perl, PHP, Java, C/++ and more, another thing that Python will fix for you is the problem of having a too fast processor on your deployment platform: Python effectively eliminates this problem in most cases, way better than most other languages will. There's always another side of every coin, and it shouldn't ever be ignored.


Bear in mind that this is only applicable if your code is very CPU-bound. If it's IO-bound as many applications are these days, then this is for all intents and purposes a non-issue.


It's been a non-issue for almost a decade!


This is a non-statement -- if the code is IO-bound, then of course CPU performance is not a problem (except for things like, say, power usage, but we'll ignore that). The "power" of Python is to make code that should be IO-bound CPU-bound.

Speaking as someone who loves Python and uses it all the time, but has spent a lot of time learning to love Cython in recent months. A nice feature of Cython (psychologically speaking, at least) that is missing in Python is the power to say that dammit, certain constants are constant, will never be changed, and can be inlined instead of having a hash table lookup every single time.


I think it's more accurate to say that it's a truism. Unfortunately, it's one that a lot of people forget.


> the problem of having a too fast processor on your deployment platform

The sarcasm here is unwarranted, as is basically your entire paragraph. Why not just say: Python is slow ?


Because then it would look as if she were off-topic.


Python has never; and probably never will claim to be the fastest language in the stable. The tradeoff made is processor time, versus developer time - one is cheap, one is not.

Should, and can Python be faster without sacrificing the speed of the programmer (including extension authors)? Yes, it can and will be, but never at the cost of productivity.


Should, and can Python be faster without sacrificing the speed of the programmer (including extension authors)? Yes, it can and will be, but never at the cost of productivity.

That this is a trade-off at all is a woefully outdated idea.


Ironic, because I'm only 30. It's not outdated at all - take for example, the GIL - sure, get rid of it, and put in granular locking. You've now actively harmed the lives of every C extension author and maintainer out there, and slowed down single threaded performance.

Sure; it's "easy" - but the cure can be worse than the disease for most of the python-using population. It's all a series of tradeoffs and compromises - in time, things like pypy and unladen swallow will change this (for python) but given both of those are pretty bleeding edge, I'd argue my initial point still stands.


Funny, but lots of other dynamic langs interface with C without such a badly designed GIL. The GIL actually proves my point. The fact that people will excuse such poor performance in a dynamic lang is a matter of misplaced expectation. This was a clever hack in the beginning, but proved to be a major design flaw going forward. A performance hit of over 3 orders of magnitude is not excusable for any language, "scripting" or otherwise.


Yes, it was a clever hack in the beginning - which is what counted. Given that Python's implementation (CPython, with a GIL) was started in December of 1989 (http://python-history.blogspot.com/2009/01/brief-timeline-of...) I'd say that it worked fabulously at the time, and pretty much until multicore/multiprocessor architectures really became the topic du-jour.

Think about that; CPython's internal are old - sure, they've changed and been cleaned up and fixed up here and there, but it's still old. Obviously if it was written today, it might be done differently knowing what we know now.

So, yeah - it is excusable, given that it meets the original design goals of making C extensions dirt simply to write (really, they are dirt simple) and making the common, single threaded/single processor use case fast "enough".

Given the hindsight everyone has now - yeah, the GIL as it exists today is grossly suboptimal, and I don't know of anyone of rational mind or body who doesn't want it to go the way of the dodo, or at least be replaced with a cleaner, simpler and faster implementation. The latter is in progress in Python 3 - the former is a lot more difficult despite a lot of hand waving from non-committers and armchair interpreter designers.

Python's performance can (and is, and will) be improved over time, but as I said originally, it was never advertised as "the fastest" or "the most concurrent" language, those two things have never been a core "feature" of the language.


I'd say that it worked fabulously at the time

Which is what I also implied. C extensions are simple to use for Visualworks Smalltalk, whose development goes back in direct lineage to 1989. Again, why is the GIL such a problem?


Can you expand on this, please?



Simple things are simple. Hard things are doable and still easy to read and maintain. Concise but not so much that it looks like line noise later. An application often has about as many characters as the pseudo-code used when designing it. The language syntax is so minimal and flexible that, unlike Ruby, you do not want to create a true DSL but rather plain old modules, functions and classes in order that you keep the readability & extensibility high by having a common language syntax.


Hmm. Python isn't a really big language, but it isn't as small as it used to be, not by far, and it never was as small or minimalistic as e.g. Scheme or Io.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: