Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Tom Anderson wrote: > So, if you're a pythonista who loves map and lambda, and disagrees with > Guido, what's your background? Functional or not? I avoid map sometimes, because I find its syntax less readable than list (and expression) comprehensions. But occasionally it is the most readable way to do something, and I wouldn't want to lose it. Lambda serves a very specific purpose: declaring small, in-place functions which are no bigger than a single expression. I do this often enough that I DO want special syntax for it. But I'll admit that I wish "lambda" were about 5 or 6 characters shorter and didn't have such an obscure name. I disagree (and I've mentioned it before) with Guido's plan to remove these eventually. I'm perfectly satisfied with the alternate plan to move the functions like map to a module (perhaps named "functional"). (That doesn't help with lambda, though since it requires syntactical support.) And my background is definitely NOT functional: I started with Basic, then learned Pascal well, then _lots_ of other languages (including Lisp) to an academic level. I've been using Java and Python heavily now for about 8 or 9 years. I _DO_ however feel quite comfortable using a functional approach *for certain problems*. -- Michael Chermside -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Steven D'Aprano writes: > Lambda is no more an obscure name than "function", "decorator", "closure", > "class", or "module". The first time you come across it, you don't know > what it means. Then you learn what it means, and then you know. I believe you've made two errors here. First of all, "lambda" is part of the Python language, while "function", "decorator", "closure", and "module" are not. The fact that some words which are NOT part of the Python language are obscure has no bearing whatsoever on "lambda". The obnubilation created by this comparison is an obscure word also, but, it isn't relevent to the Python language. The second error is that I believe most english speakers COULD provide a definition for the fairly common words "function", "class", and "decorator". The exact meaning of "class" might not be what they expect at first, but exposure to any object oriented language would make the concept quickly familiar. But "lambda" has a very clear meaning... it's a letter of the greek alphabet. The connection between that letter and anonymous functions is tenuous at best, and fails the test of making Python read like "executable pseudocode". -- Michael Chermside -- http://mail.python.org/mailman/listinfo/python-list
Re: Proposal: reducing self.x=x; self.y=y; self.z=z boilerplate code
Ralf W. Grosse-Kunstleve wrote: > I often find myself writing:: > > class grouping: > > def __init__(self, x, y, z): > self.x = x > self.y = y > self.z = z > # real code, finally > > This becomes a serious nuisance in complex applications with long > argument lists Yes... indeed it does. This is so common that there is a standard idiom for handling it: def __init__(self, x, y, z): self.__dict__.update(locals()) sometimes with modifications to avoid setting self.self. > Therefore I propose that Python includes > built-in support for reducing the ``self.x=x`` clutter. If all you were proposing was a built-in function to make this particular idiom clearer and more reliable, then I think I'd back such a feature because the need is SO common. However, the suggestion you actually make: > def __init__(self, .x, .y, .z): > # real code right here is far too broad and introduces new syntax unnecessarily. You yourself are using a helper function (although I belive it could be done more easily than you did it): > I am actually using a simple trick:: > > adopt_init_args(self, locals()) To which you raise the following objections: > - The solution doesn't come with Python -> everybody has to reinvent. Good point. Particularly since people won't think of all the special cases (eg: classes with __slots__ defined). > - People are reluctant to use the trick since scripts become > dependent on a non-standard feature. > - It is difficult to remember which ``import`` to use for > ``adopt_init_args`` (since everybody has a local version/variety). If the implementation is only 3-4 lines long (and a simpler implementation can be), then is can simply be included inline with every script that needs to use it. > - The ``adopt_init_args(self, locals())`` incantation is hard to > remember and difficult to explain to new-comers. A better name would help with this. The need for locals() is unavoidable. But for REAL beginners, I wouldn't even bother... writing out "self.x = x" is useful for beginners since it helps make it very clear and concrete to them just what is happening. > - Inside the ``__init__()`` method, the same object has two names, > e.g. ``x`` and ``self.x``. This lead to subtle bugs a few times > when I accidentally assigned to ``x`` instead of ``self.x`` or vice > versa in the wrong place (the bugs are typically introduced while > refactoring). Hmm... I've never had that problem, myself. > - In some cases the ``adopt_init_args()`` overhead was found to > introduce a significant performance penalty (in particular the > enhanced version discussed below). Again... a different code will help here. And if execution speed is REALLY a concern, then you can just write it out the long way! > - Remember where Python comes from: it goes back to a teaching > language, enabling mere mortals to embrace programming. > ``adopt_init_args(self, locals())`` definitely doesn't live up > to this heritage. No, but "self.x = x" does. It's only when you have lots of variables or very long names that this approach becomes unwieldy. > My minimal proposal is to add an enhanced version of ``adopt_init_args()`` > as a standard Python built-in function (actual name secondary!):: I'd alter the name and the implementation, but the basic idea seems sound to me. > However, there is another problem not mentioned before: > It is cumbersome to disable adoption of selected variables. The VERY simple, VERY straightforward, VERY common behavior of "store all the arguments as like-named attributes of self" is worth having a standard idiom (and *perhaps* a built-in). But odd special cases like skipping some arguments... that calls for writing the whole thing out. I'm firmly -1 on any proposal to support skipping arguments. > When ``__slots__`` are used (cool feature!) the boilerplate problem > becomes even worse:: > > class grouping: > > __slots__ = ["keep_this", "and_this", "but_this_again"] > > def __init__(self, keep_this, and_this, but_not_this, but_this_again): > self.keep_this = keep_this > self.and_this = and_this > self.but_this_again = but_this_again > # real code, finally > > Each variable name appears four times! ** NO! ** __slots__ is *NOT* to be used except for those times when you NEED the performance advantages (mostly memory use). The simple rule is that you should *NEVER* use __slots__ (if you are in a situation where you *do* need it, then you'll know enough to understand why this advice doesn't apply to you). There should NOT be any support for auto-setting __slots__ *anywhere* in the standard library, because it would make it FAR too tempting for people to mis-use __slots__. Besides, a metaclass would be a better solution, and it can be done today with no modifications to Python. . . . All in all, I th
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Up until a few years ago, I ran the computer science department at a high-school. I provided support for the English teachers who taught *all* students -- but they taught things like the use of a word processor or the internet, and never covered the meaning of "lambda". I taught a computer applications course which was taken by only small fraction of the students (<10%) but there I taught things like the use of photo-editing software, creating web sites, and the use of simple databases; I never covered the meaning of "lambda". I also taught the programming class (taken by only a dozen or so students per graduating class) -- students learned basic concepts like variables, looping, up through fancier bits like a couple different sorting algorithms. But I didn't cover the meaning of "lambda". And I also taught the "AP" computer course (taken by an average of just 4 students per year!), in which I explained things like object oriented programming and recursion and managed to get the students to the level where they could work together as a group to write a moderately complex program, like a simple video game. And I didn't teach the meaning of "lambda", nor was it covered by the "AP" exam, which is supposed to be equivalent to a single college-level course in computer programming. So I'd say that it's a pretty obscure name that most people wouldn't know. And besides, "def" isn't a "magic" word... it's an abreviation for "define"... I hope that any student who didn't understand a word as common as "define" wouldn't have graduated from our school. -- Michael Chermside -- http://mail.python.org/mailman/listinfo/python-list
Re: python simply not scaleable enough for google?
On Nov 11, 7:38 pm, Vincent Manis wrote: > 1. The statement `Python is slow' doesn't make any sense to me. > Python is a programming language; it is implementations that have > speed or lack thereof. [...] > 2. A skilled programmer could build an implementation that compiled > Python code into Common Lisp or Scheme code, and then used a > high-performance Common Lisp compiler... I think you have a fundamental misunderstanding of the reasons why Python is slow. Most of the slowness does NOT come from poor implementations: the CPython implementation is extremely well-optimized; the Jython and Iron Python implementations use best-in-the-world JIT runtimes. Most of the speed issues come from fundamental features of the LANGUAGE itself, mostly ways in which it is highly dynamic. In Python, a piece of code like this: len(x) needs to watch out for the following: * Perhaps x is a list OR * Perhaps x is a dict OR * Perhaps x is a user-defined type that declares a __len__ method OR * Perhaps a superclass of x declares __len__ OR * Perhaps we are running the built-in len() function OR * Perhaps there is a global variable 'len' which shadows the built-in OR * Perhaps there is a local variable 'len' which shadows the built-in OR * Perhaps someone has modified __builtins__ In Python it is possible for other code, outside your module to go in and modify or replace some methods from your module (a feature called "monkey-patching" which is SOMETIMES useful for certain kinds of testing). There are just so many things that can be dynamic (even if 99% of the time they are NOT dynamic) that there is very little that the compiler can assume. So whether you implement it in C, compile to CLR bytecode, or translate into Lisp, the computer is still going to have to to a whole bunch of lookups to make certain that there isn't some monkey business going on, rather than simply reading a single memory location that contains the length of the list. Brett Cannon's thesis is an example: he attempted desperate measures to perform some inferences that would allow performing these optimizations safely and, although a few of them could work in special cases, most of the hoped-for improvements were impossible because of the dynamic nature of the language. I have seen a number of attempts to address this, either by placing some restrictions on the dynamic nature of the code (but that would change the nature of the Python language) or by having some sort of a JIT optimize the common path where we don't monkey around. Unladen Swallow and PyPy are two such efforts that I find particularly promising. But it isn't NEARLY as simple as you make it out to be. -- Michael Chermside -- http://mail.python.org/mailman/listinfo/python-list