Re: [Python-Dev] concerns regarding callable() method
> I have seen in PEP 3100 that callable() function is planned to be > removed in Python 3000 with this replacement: "just call the object > and catch the exception???". For one, the object (if it is > callable) can raise exception itself, so you need to somehow to > differentiate between exception raised inside its __call__ and > exception raised if object is not callable to begin with. I seem to recall bringing up the same issue a while ago; at the time, the answer was that if you need it, you can write your own: def callable(x): return hasattr(x, '__call__') My own preference would be for such queries to be defined abstractly as a built-in part of the language, but apparently my preference is out of sync with the community in this particular respect. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Py2.6 ideas
> Maybe Raymond's proposed record type should have two versions: one > that's also a tuple, for compatibility, and one that's just a record. FWIW, ML unifies tuples and records by defining a tuple to be a record whose component names are all consecutive integers starting with 1. For example, in ML, the literal { name = "ark", state = "NJ" } represents a record with type { name: string, state: string }. The identifiers "name" and "state" are bound during compilation, ML being a statically typed language. In ML, one extracts a component named foo by applying a function named #foo. So, for example, the value of #state { name = "ark", state = "NJ" } is "NJ", and trying to evaluate #foo { name = "ark", state = "NJ" } results in a compilation error because of type-checking failure. Component names can be either identifiers or integers. So, for example, { name = "spells", 1 = "xyzzy", 2 = "plugh" } is a record of type {1: string, 2: string, name: string }. So here is the point. If the component names of a record are all positive integers with no gaps, the record is *also* a tuple. So, for example { 2 = "plugh", 1 = "xyzzy" } has exactly the same meaning--including the same type--as { "xyzzy", "plugh" } In both cases, the compiler normalizes the display, both of the value (i.e. it prints {"xyzzy", "plugh"} instead of { 2 = "plugh", 1 = "xyzzy" }, and it prints the type as string * string instead of (the equivalent) { 1: string, 2: string } So in ML, tuple types aren't really anything special -- they're just abbreviations for elements of a particular subset of record types. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] dict(keys, values)
> Unfortunately > >dict(keys=keys, values=values) == {keys: values} Ummm, no: dict(keys=keys, values=values) == {'keys': keys, 'values': values} ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] compex numbers (was Floor Division)
> If "real" and "imag" are themselves complex numbers, then normalizing > the result will move the imaginary portion of the "real" vector into > the imaginary part and vice versa. Not quite. >>> complex(1,1j) 0j >>> complex(0,1j) (-1+0j) So it moves the imaginary portion of the "imag" argument into the real part of the result with change of sign, on the basis that 1j*1j == -1. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 351 - do while
> This pattern: > > while entry_cond: > ... > and while not exit_cond: > ... > > has been suggested before, and I believe that at least one of the times it > was suggested, it had some support from Guido. Essentially, the "and > while not exit" is equivalent to an "if exit: break" that's more visible > due to not being indented. I like this suggestion. In fact it is possible that at one time I suggested something similar. It reminds me of something that Dijkstra suggested in his 1971 book "A Discipline of Programming." His ides looked somewhat like this: do condition 1 -> action 1 ... [] condition n -> action n od Here, the [] should be thought of as a delimiter; it was typeset as a tall narrow rectangle. The semantics are as follows: If all of the conditions are false, the statement does nothing. Otherwise, the implementation picks one of the true conditions, executes the corresponding action, and does it all again. There is no guarantee about which action is executed if more than one of the conditions is true. The general idea, then, is that each action should falsify its corresponding condition while bring the loop closer to termination; when all of the conditions are false, the loop is done. For example, he might write Euclid's algorithm this way: do x < y -> y := y mod x [] y < x -> x := x mod y od If we were to adopt "while ... and while" in Python, then Dijkstra's construct could be rendered this way: while x < y: y %= x or while y < x: x %= y I'm not suggesting this seriously as I don't have enough realistic use cases. Still, it's interesting to see that someone else has grappled with a similar problem. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 351 - do while
> (I don't think this has been suggested yet.) > > while , : > This usage makes me uneasy, not the least because I don't understand why the comma isn't creating a tuple. That is, why whould while x, y: be any different from while (x, y): ? My other concern is that is evaluated out of sequence. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
> So, if I understand correctly, in the presence of a global statement > search > just goes up the lexical chain looking for the first occurrence of the > variable to modify? > > x = 0 > def f(): > x = 1 > def g(): > global x > x = 2 > print x > g() > print x > f() > print x > > Today it prints > > 2 > 1 > 2 > > You're suggesting it will print > > 2 > 2 > 0 > > ? Sounds right to me. > Sounds reasonable to me. If we're talking py3k I'd chuck "global" as a > keyword though and replace it with something like "outer". I must say that I don't like "outer" any more than I like "global." The problem is that in both cases we are selecting the *inner*most definition that isn't in the current scope. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
> However I still don't believe "global" has the stretchiness in its > meaning that you claim it has. Have you ever heard a Python programmer > talking about closures use the word "global variable"? I guess the term I've heard most often is "free variable," but I wouldn't be surprised if I saw the term "global" used to describe a free variable. However, I should point out that Dijkstra used "global" in a similar way in his 1971 book "A Discipline of Programming." The program examples in that book are in a language he devised for the purpose; one of the language's features is that every variable used in every block must be explicitly declared, even if it is taken from a surrounding block. If I remember correctly, the terms he used for variables taken from a surrounding block and variables defined and used in the same block were "global" and "private," respectively. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Explicit Lexical Scoping (pre-PEP?)
> Borrowing from Perl, the keyword 'my' is used to declare an explicitly > scoped variable: > > def f1(): >my x = 1 >def f2(): > x = 2 # Does not create a new x > > In the above example, the statement 'my x = 1' declares that the scope > of the variable 'x' is the outer function f1. Any assignment to x will > modify the existing x, rather than creating a new definition. -1, for this reason: def f() x = 2 # Does this create a local variable? Today, the answer is yes. Under this proposal, you can't answer the question without inspecting the entire context in which f is defined. For that reason, I would much rather have the first assignment in a block say explicitly whether it is intended to create a local variable: def f1(): x = 1 def f2(): global x x = 2# Does not create a new x This might even be abbreviated: def f1(): x = 1 def f2(): global x = 2 # Equivalent to the last example above ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Lexical scoping in Python 3k
> Much though the Algol 60 tickles my nostalgia (it was my first > programming language!) I don't think that it's a particularly strong > argument. I like to think that we have better ways these days. Even if so, that's not the point I was trying to make. The point is that there is a programming technique that is widely used, works in many languages, and has been around for 45 years; and when you try to use it in Python, it fails. I believe that such failures, even if there are alternative ways of solving the problems that engender them, are barriers to learning that should be removed if it is possible to do so without substantial cost. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Lexical scoping in Python 3k
> I don't think "trivial" is the right word to use here, > since it implies something that's of so little importance > that it can be ignored. But the simple cases are precisely > the ones where this wart hurts the most, so we can't > ignore them. I'd like to inject an example that might help make this discussion more concrete. Consider the following function: def for_each(seq, f): for i in seq: f(i) I'm sure I've seen more than one instance of someone on comp.lang.python trying to do the equivalent of using a function such as this one to compute the sum of the elements of a sequence as follows: def sum(seq): result = 0 def accum(i): result += i for_each(seq, accum) return result and wonder why it doesn't work. Still odder, why it doesn't work and the following does: def sum(seq): result = [0] def accum(i): result[0] += i for_each(seq, accum) return result[0] Transforming the first definition of sum above into the second may be trivial, but only if you've encountered the technique before. Moreover, the first version of sum uses a technique that is more than 45 years old (!), as it was available to Algol 60 programmers. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] 2.5 and beyond
> Don't recall what that was, but creating a new scope on each iteration > sounds hard to explain in Python. I don't think it's particularly hard to explain. For example, one way to explain it is to say that for i in <>: body is equivalent to for <> in <>: local i = <> body This explanation doesn't need to rest on recursion. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Lexical scoping in Python 3k
> "Fully functional" lexical scopes, then? Fine-grained scopes? ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Lexical scoping in Python 3k
> What about doing something similar to how import was changed? > > .a = 5 # this scope (self might be too magical > ..a = 3 # up one scope > ...a # up three > > Of course, this looks ... perhaps a bit strange. Also, counting is a > bother. I'd rather see a simpler rule: = never defines a variable in a surrounding scope. If you want to affect the binding of such a variable, you have to define it explicitly in the scope in which you want it. Example: x = 42 def f(): x = 123 # rebinds x as defined above y = 123 # defines local variable f() print x # prints 123 print y # error -- y not defined Yes, I know that rule is too simplistic. But I think I'd still prefer it to the way things are now. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] 2.5 and beyond
> a = [] > for i in range(10): > a.append(lambda: i) > print [x() for x in a] > > [9, 9, 9, 9, 9, 9, 9, 9, 9, 9] Aha! -- Thank you for jogging my memory. You seem to be right -- the problem is not that Python is lexically scoped, but that when you define a variable with =, it leaks out into the surrounding function scope. Here's an example: If True: y = 123 print y It may be obvious that this should print 123, but that's only because = combines properties of assignment and definition. In particular, if we were to write y = 42 if True: y = 123 print y it would be very surprising if this example were to print anything but 123. Here is a corresponding fragment in C++: int y = 42; if (true) { y = 123; } std::cout << y << "\n"; The "int" in the first line means that the variable y is being defined. Its lack in the third line means that y refers to a variable defined in an outer scope. So both instances of y here refer to the same variable, as they do in Python. But because definition and assignment are separated in C++, we can also write int y = 42; if (true) { int y = 123; } std::cout << y << "\n"; and the fragment will print 42. In this example, there are two distinct variables, both named y. So the problem, as I see it, is indeed that in Python there are suites that look to me as if they should define scopes, but don't. Indeed, if I write if (foo): y = 123 I can't even determine by inspecting the program whether y is defined at all. I might argue that y is always defined, by virtue of appearing before = somewhere in this scope, but the compiler tells me "name 'y' is not defined" if I try it, so I guess that's the right way to treat it. So here's how I understand what Greg was saying. Suppose I write x = [] for i in range(10): x.append(lambda:i) print [f() for f in x] This example will print [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], which I think is wildly unintuitive. My intuition in this matter is partly formed by C++, but it is also formed by other languages going as far back as Algol 68. That intuition says that because the suite controlled by a "for" statement is executed any number of times, potentially including zero, it should be considered as its own scope, and any variables defined in that scope should stay there. In particular, the variable "i" should be defined in the scope of the "for", which implies that each time through the loop, the name "i" should be (re)bound to a different object. What surprises me even more is that if I try to define such a variable explicitly, it still doesn't work: x = [] for i in range(10): j = i x.append(lambda:j) print [f() for f in x] This example still prints [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]. If I understand the reason correctly, it is because even though j is defined only in the body of the loop, loop bodies are not scopes, so the variable's definition is hoisted out into the surrounding function scope. To convince myself of this behavior, I defined an extra function scope, the purpose of which is to localize j: x = [] for i in range(10): def foo(): j = i return lambda:j x.append(foo()) print [f() for f in x] Indeed, this example prints [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. The example also points up the fact that x.append(lambda:i) and def foo(): j = i return lambda:j x.append(foo()) behave differently, where my intuition (and, I suspect, many other people's as well) would be that they would be equivalent. Finally, I observe that this second example above is also equivalent to x.append(lambda i=i: i) which is what explains the fairly common idiom x = [] for i in range(10): x.append(lambda i=i:i) print [f() for f in x] So maybe what I meant when I asked for lexical scopes was two things: 1) Every indentation level should be a scope; 2) In general, variable definitions should not leak into surrounding scopes. I realize that (2) is too simplistic. Someone who writes if x < 0: y = -x else: y = x will expect y to be defined in the scope surrounding the "if" even if it was not already defined there. On the other hand, I think that the subtle pitfalls that come from allowing "for" variables to leak into the surrounding scopes are much harder to deal with and understand than would be the consequences of restricting their scopes as outlined above. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/
Re: [Python-Dev] 2.5 and beyond
> I read "a la Scheme" here as "actually nothing like Scheme, except I > want a non-tricky way to rebind a name from an enclosing scope within > an enclosed scope". Almost. What I really want is for it to be possible to determine the binding of every name by inspecting the source text of the program. Right now, it is often possible to do so, but sometimes it isn't. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] 2.5 and beyond
> That sounds like a bug, not a feature. It's frequently useful to have > forward references in function bodies to names that are not yet globally > bound, e.g. for classes, or mutually-recursive functions. The trouble is that you don't necessarily know in what scope they will be defined, so I think that forcing you to be explicit about it is useful. Can you show me an example of where you think it isn't? Incidentally, I think that lexical scoping would also deal with the problem that people often encounter in which they have to write things like "lambda x=x:" where one would think "lambda x:" would suffice. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] 2.5 and beyond
> That's not a very constructive proposal (especially since I don't know > Scheme). Perhaps you could elaborate on what needs to change? The fundamental principle is that the binding of every name is determined during compilation, not during execution. This property does not quite apply to Python at present. For example: x = 42 def f(): y = x x = 123 return y f() This example fails with "local variable 'x' referenced before assignment" because the compiler sees that f contains an assignment to x, so it makes x a local variable, and then when you try to assign x to y during execution, it fails. This behavior is consistent with the notion of lexical scoping. However, if I write def g(): return x x = 42 g() the result is 42. With lexical scoping, I believe it should be undefined. The reason is that when the compiler encounters the definition of g, variable x is not yet bound, and there is nothing in the body of g that would bind it. Therefore, g requires a binding to exist at the time it is compiled; because no such binding exists, this example would be an error (at compile time) under lexical scoping. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] 2.5 and beyond
> I think it should increment (i.e. rebind) g, for the same reason that > > g = [1] > def f(): > g[0] += 1 > f() > > rebinds g[0]. I saw messages out of sequence and did not realize that this would be a change in behavior from 2.4. Sigh. I hope Py3000 has lexical scoping a la Scheme... ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] 2.5 and beyond
> The question is, what behaviour is preferable for this code: > > g = 1 > def f(): > g += 1 > > f() > > Should this raise an UnboundLocalError or should it increment g? I think it should increment (i.e. rebind) g, for the same reason that g = [1] def f(): g[0] += 1 f() rebinds g[0]. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Any reason that any()/all() do not takea predicateargument?
> > How about this? > > > > if any(x==5 for x in seq): > > Aren't all of these equivalent to: > > if 5 in seq: > ... Of course. However, the original example was pretty clearly intended to be an illustrative instance of a more general problem. Rewriting the example as any(x==5 for x in seq) preserves the generality; rewriting it as 5 in seq doesn't. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Any reason that any()/all() do not take a predicateargument?
> sorry if this came up before, but I tried searching the archives and > found nothing. It would be really nice if new builtin truth functions > in 2.5 took a predicate argument(defaults to bool), so one could > write, for example: > > seq = [1,2,3,4,5] > if any(seq, lambda x: x==5): > ... > > which is clearly more readable than > > reduce(seq, lambda x,y: x or y==5, False) How about this? if any(x==5 for x in seq): ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] "as" mania
> Function arguments are not covered by this trick, but > > def bar(z): > (x,y) = z > > probably isn't too much overhead... It's not the machine overhead, it's the intellectual overhead. I know there are some who will disagree with me, but I would find it easier to read def foo(origin as (x1, y1), corner as (x2, y2)): than to read def foo(origin, corner): (x1, y1) = origin (x2, y2) = corner It's not a big deal, but it is not completely negligible either. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] "as" mania
> Thinking over it, this is too much a difference between the with-"as" and > my "as", so I'm abandoning this idea. My "as" would just have been a > shortcut to avoid writing longish expressions that have to be checked for > true-ness and then tinkered with. ML has a similar feature, which you may consider as an argument either for or against it depending on your taste. The point is that ML lets you write "patterns" that decompose data structures, and the "as" usage lets you talk about the whole data structure and the decomposed one at the same time. For example, in ML, :: works like "cons" in Lisp, so that x::y is a list with a first element of x and a tail of y, which must be a list. In other words, [3, 4, 5] is equivalent to (3::4::5::nil) in ML. Now consider the following: fun merge(nil, y) = y | merge(x, nil) = x | merge (x as xh::ht, y as yh::yt) = if xh < yh then xh::merge(xt, y) else xt::merge(x, yt) Without the "as" clause, we would have had to write fun merge(nil, y) = y | merge(x, nil) = x | merge(x, y) = let val xh::xt = x val yh::yt = y in if xh < yh then xh::merge(xt, y) else xt::merge(x, yt) end which is somewhat longer and harder to follow. As it turns out, Python has similar ways of decomposing data structures: (x, y) = foo or def bar((x, y)): # etc. and I have sometimes wished I could write z as (x, y) = foo or def bar(z as (x, y)): # etc. However, it's not real high on my list of priorities, and I suspect that many Pythonists consider these usages to be a frill anyway. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] _length_cue()
> I'm worried about the name. There are now exactly two names that behave > like a special method without having the double-underscores around it. > The first name is 'next', which is kind of fine because it's for > iterator classes only and it's documented. But now, consider: the > CPython implementation can unexpectedly invoke a method on a > user-defined iterator class, even though this method's name is not > '__*__' and not documented as special! That's new and that's bad. Might I suggest that at least you consider using "hint" instead of "cue"? I'm pretty sure that "hint" has been in use for some time, and always to mean a value that can't be assumed to be correct but that improves performance if it is. For example, algorithms that insert values in balanced trees sometimes take hint arguments that suggest where the algorithm should start searching for the insertion point. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Octal literals
> I definately agree with the 0c664 octal literal. Seems rather more > intuitive. I still prefer 8r664. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Octal literals
> Apart from making 0640 a syntax error (which I think is wrong too), > could this be solved by *requiring* the argument to be a string? (Or > some other data type, but that's probably overkill.) That solves the problem only in that particular context. I would think that if it is deemed undesirable for a leading 0 to imply octal, then it would be best to decide on a different syntax for octal literals and use that syntax consistently everywhere. I am personally partial to allowing an optional radix (in decimal) followed by the letter r at the beginning of a literal, so 19, 8r23, and 16r13 would all represent the same value. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Octal literals
> Possibly os.chmod and os.umask could be extended to take a string > argument so we could write chmod(path, "0640"). -1. Would you really want chmod(path, 0640) and chmod(path, "0640") to have different meanings? ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] yield back-and-forth?
> The discussion about PEP 343 reminds me of the following. Bram Cohen > pointed out in private email that, before PEP 342, there wasn't a big > need for a shortcut to pass control to a "sub-generator" because the > following for-loop works well enough: > def main_generator(): > ... > for value in sub_generator(): > yield value > but now that yield can return a value, that value might have to be > passed into sub_generator(), not to mention of exceptions. I'm sure > there's a way to write that (although I haven't found the time to > figure it out) but I expect it to be cumbersome and subtle. It looks to me like continuations are starting to rear their heads... ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Small any/all enhancement
> Of course I already knew all the alternatives using map and the generator > expression, but I felt like mine was clearer for a reader, this is > probably true but not enough to justify the change. If there is to be any enhancement, I think I would prefer it to be an enhancement to map, so that map's second and subsequent arguments can be sequences or iterables, and its result is an iterable if any of its arguments is an iterable. Unfortunately, that would be an incompatible change :-( ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Coroutines, generators, function calling
> so the new syntax would > not be useful, unless it was something that provided access to the index > item as a variable, like: > > yield foo(i) for i in x > > which barely saves you anything (a colon, a newline, and an indent). Not even that, because you can omit the newline and indent: for i in x: yield foo(i) There's a bigger difference between for i in x: yield i and yield from x Moreover, I can imagine optimization opportunities for "yield from" that would not make sense in the context of comprehensions. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Coroutines, generators, function calling
> We yield values from inside for loops all over the place, but the > yielded value is very rarely just the index value (only 1 of 14 yields) > , but something calculated from the index value, so the new syntax would > not be useful, unless it was something that provided access to the index > item as a variable, like: > > yield foo(i) for i in x > > which barely saves you anything (a colon, a newline, and an indent). > (hey wait, isn't that a generator comprehension? Here's a use case: def preorder(tree): if tree: yield tree yield from preorder(tree.left) yield from preorder(tree.right) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Coroutines, generators, function calling
> Sure, that would work. Or even this, if the scheduler would > automatically recognize generator objects being yielded and so would run > the the nested coroutine until finish: This idea has been discussed before. I think the problem with recognizing generators as the subject of "yield" statements is that then you can't yield a generator even if you want to. The best syntax I can think of without adding a new keyword looks like this: yield from x which would be equivalent to for i in x: yield i Note that this equivalence would imply that x can be any iterable, not just a generator. For example: yield from ['Hello', 'world'] would be equivalent to yield 'Hello' yield 'world' ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 updated
> PEP 343 has been updated on python.org. > Highlights of the changes: >- changed the name of the PEP to be simply "The 'with' Statement" Do you mean PEP 346, perchance? PEP 343 is something else entirely. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] C.E.R. Thoughts
> Congragulations heartily given. I missed the ternary op in c... Way to > go! clean and easy and now i can do: > if ((sys.argv[1] =='debug') if len(sys.argv) > 1 else False): > pass > and check variables IF AND ONLY if they exist, in a single line! Umm... Is this a joke? ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Visibility scope for "for/while/if" statements
> Interestingly enough, not all C++ compilers (Microsoft) hid variables > created in for loops > (http://www.devx.com/cplus/10MinuteSolution/28908/0/page/2). That's because the C++ spec changed during standardization, when the standards committee realized the original idea was a mistake. One of the convincing cases: if (x) for (int i = 0; i != 10; ++i) { } Is I in scope after the if statement? If so, what value does it have if x is false? If not, then apparently the subject of an "if" statement is a scope...so why can't I write this? if (x) int i = 42; and have i go out of scope? ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Adding a conditional expression in Py3.0
> My problem with this syntax is that it can be hard to read: > > return if self.arg is None then default else self.arg > > looks worryingly like > > return NAME NAME.NAME NAME NAME NAME NAME NAME NAME.NAME > > to me. Interesting. What about return if self.arg is None: default else: self.arg ? ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] "and" and "or" operators in Py3.0
> In C, C++, C#, Java, and JavaScript, what do you get when you print the > result of 3 || 10? In C and C++, you get 1. (in c++ the result is actually true, not 1, but true prints as 1 by default for backward compatibility) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] removing nested tuple function parameters
> The only practical reason to like this feature is sparing the need of > finding an otherwise useless name for the formal argument. Another > reason, but not practical at all, is that the concept conveys some > elegance and originality (each programming language should ideally have > a few of these) and is enforced in other places in Python, like in the > `for' statement -- where I find implied unpacking very, very useful. One other reason: It is possible to imagine using the feature to catch some type errors at the point of call, rather than having to get into the function itself before detecting them. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] removing nested tuple function parameters
> I agree that we shouldn't mess with them in 2.x. Yet I think they are > a candidate for being dropped from Py3K. While every feature is used > by *someone* (as the feedback to Brett's query clearly shows) this one > has several things against it. For every user who is fond of them > there are probably ten who have never even heard of it. It's purely > syntactic sugar (the only place where it's not trivial to replace is > in a lambda). I've encountered quite a few people who had a hard time > reading code that uses it. I personally prefer reading code that > doesn't use this feature; for one thing, when this is used, you can't > refer to a parameter by name. I don't know whether this qualifies as an argument for or against the feature, but ML has a nice way of referring to such a parameter by name: fun f(x as (y, z)) = (* ... *) This defines f as a function with an argument that is a 2-element tuple. The name x is bound to the argument, and the names y and z are bound to the two components of the argument. This example is syntactic sugar for fun f x = let val (y, z) = x in (* ... *) end but it I find the sugared version easier and more natural to write and understand. If you don't know ML, the unsugared version might be easier to follow if I indent it Pythonically: fun f x = let val (y, z) = x in (* ... *) end The idea is that the stuff between "in" and "end" is executed in the scope of the bindings between "let" and "in", after which those bindings are discarded. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 342: simple example, closure alternative
> A closure based accumulator (using Scheme): > > (define (accum n) > (lambda (incr) >(set! n (+ n incr)) >n)) > (define s (accum 0)) > (s 1) ; -> 1 == 0+1 > (s 5) ; -> 6 == 1+5 > > So I thought the generator version might look like: > > def accum(n): > while 1: > incr = (yield n) or 0 > n += incr Maybe I'm missing something but this example seems needlessly tricky to me. How about doing it this way? def accum(n): acc = [n] def f(incr): acc[0] += incr return acc[0] return f Here, the [0] turns "read-only" access into write access to a list element. The list itself isn't written; only its element is. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Wishlist: dowhile
> > I believe that Algol 68 loops looked like the following (in somewhat > > more Python-like terms): > > > > [for [from ] [step ] to ] > > [while ] > > do od > As far as I remember, it was: > do > > while > > od > It might be that this could be preceded by a 'for' clause, but memory > fails me there. To be completely sure, I dug out my copy of the "Informal Introduction to Algol 68" by Lindsey and van der Meulen. This book is the official Algol 68 tutorial book. It describes the "loop clause" as follows: for some int identifier, which is hereby declared from some meek int unit by some other meek int unit to a third meek int unit while a meek bool enquiry-clause do a void serial-clause od where any of these keywords and its sequel can be omitted, except for "do" or "od". Here, the term "meek" refers to how aggressively the compiler should try to convert the result to int; it specifies, for example, that if after "from" you write the name of a procedure without arguments, that procedure will be called instead of using the procedure itself as a starting point (which would be nonsensical). ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Wishlist: dowhile
> > With PEP 315, a do-while loop would look like: > > > >do: > > > >while : > >pass > > But then, I'm reasonably happy with the 'break out of an infinite > > loop' approach, so *shrug*. > From Programming Languages 101 I remember this construct in Algol 68. > It was then claimed to be *the* universal loop construct. If that is > true __and__ it is easy to implement, I'd say +INF for PEP 315. I believe that Algol 68 loops looked like the following (in somewhat more Python-like terms): [for [from ] [step ] to ] [while ] do od where either "for" or "while" had to be present. Note that in Algol 68, the value of a "suite" (which I think they called a "serial clause") is the value of the last expression in it. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - next steps
> > But I cannot do this: > > > > def f(x as (a, b)): > > # ... > > which is what I was suggesting. > Yeah, I knew that. How important is that to you? I would really have liked it for a program I was working on at one time that had lots of small methods that passed around values of forms such as (a,(b,c)). Each method would pick one or more of the components out of its compound value and then would sometimes pass the entire value down to the next level. Of course I could do it this way: def f(x): (a,(b,c)) = x # ... but in this particular application, "as" would have offered significant extra convenience. I understand that this is not a real big deal, which is why I haven't written up a PEP :-) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 - next steps
> The issue is: if we allow VAR to be a > comma-separated list of variables now, that cuts off the extension to > (a) in the future; so the PEP would have to be amended to state that > VAR must be a single variable or a list of variables IN PARENTHESES. > Thoughts? I am not sure how relevant this is, but the syntax "x as (a, b)" sure looks to me like (a, b) is a tuple. Of course, I'm biased by ML, which has a feature that I wish Python had: fun f(x as (a, b)) = ... This says that f's argument must be a 2-element tuple. It binds x to the argument and also binds a and b to the argument's components. Of course the program could be written this way: fun f(x) = let val (a, b) = x in ... end but the "as" syntax is more succinct, direct, and convenient. If such a feature were implemented in Python, I would imagine it to allow usages such as x as (a, b) = (3, 4) which would be equivalent to x = (a, b) = (3, 4) Of course, this usage shows that the syntax is unnecessary in this context, but what I care about is def f(x as (a, b)): # ... which has the advantage over the alternative def f(x): (a, b) = x # ... that if you call f with the wrong arguments, you get a clearer diagnostic message. It's kind of an edge case, and I am not seriously pushing for its adoption, but I do think it worth pointing out that when I see "x as (a, b)", that's what it immediately brings to mind. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
RE: [Python-Dev] Re: anonymous blocks
> that we are having this discussion at all seems a signal that the > semantics are likely too subtle. I feel like we're quietly, delicately tiptoeing toward continuations... ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
RE: [Python-Dev] defmacro
> This doesn't feel right to me. By that argument, people would want > to "improve" > > (mapcar (lambda (x) (car x)) list-of-lists) > > to > > (mapcar list-of-lists (x) (car x)) > > Have you ever heard someone complain about that lambda, though? Wel Shouldn't you have written (mapcar car list-of-lists) or am I missing something painfully obvious? ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
RE: [Python-Dev] Re: anonymous blocks
> Mixing both suggestions: > > from as : > > > That resembles an import statement which some > may consider good (syntax/keyword reuse) or > very bad (confusion?, value focus). I have just noticed that this whole notion is fairly similar to the "local" statement in ML, the syntax for which looks like this: local in end The idea is that the first declarations, whatever they are, are processed without putting their names into the surrounding scope, then the second declarations are processed *with* putting their names into the surrounding scope. For example: local fun add(x:int, y:int) = x+y in fun succ(x) = add(x, 1) end This defines succ in the surrounding scope, but not add. So in Python terms, I think this would be local: in: or, for example: local: = value in: blah blah blah ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
RE: [Python-Dev] Python 2.4 | 7.3 The for statement
> for_stmt ::= "for" target_list "in" expression_list > [ "and" expression ] ":" > suite ["else" ":" suite] It can't work. The expression_list could be just a variable, as could the expression, in which case you get "for" target_list "in" variable "and" variable ":" and, of course variable "and" variable is already an expression. So it's ambiguous. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
RE: [Python-Dev] Lambda & deferred evaluation (was: Adding any() andall())
> >>Lambda will be more difficult. Eric Raymond adapted an anti-gun control > >>slogan and said "you can pry lambda out of my cold dead hands." A bunch > >>of folks will sorely miss the ability to create anonymous functions on > >>the fly. When lambda is used for deferred argument evaluation (a la PEP > >>312), the def syntax is a crummy substitute. > > Yeah, I'm with you here. As warty as lambda is, it just is so damn > > convenient some times. I've recently been using it as a companion to > > property(), providing concise definitions of read-only attributes. I'm with you on lambda: I've found a few places where losing it would be a major inconvenience. One example is in a library I wrote to implement the Snobol4 algorithm for recursive-descent pattern matching. Using that algorithm relies heavily on the ability to specify subexpressions for "deferred evaluation" -- their values must not be computed until they are actually needed. For example, here is a mini-specification for arithmetic expressions in Snobol4: id = any(letters) span(letters digits) primary = id | '(' *expr ')' factor = primary arbno(any("*/") primary) expr = factor arbno(any("+-") factor) This should be fairly straightforward once you realize that "arbno" is like a regular-expression *, blank is used for concatenation, and | (meaning "or") binds less tightly than blank. The whole definition depends on *expr, which is a request for deferred evaluation of expr. In other words, it refers to the value of expr when encountered during matching, rather than the (null) value it has when the assignment to primary is evaluated. Through appropriate use of overloading, I have been able to translate this code into the following Python: id = any(letters) + span(letters + digits) primary = id | '(' + defer(lambda: expr) + ')' factor = primary + arbno(any("*/") + primary) expr = factor + arbno(any("+-") + factor) I do not want to have to rewrite this code as: def defer_expr: return expr id = any(letters) + span(letters + digits) primary = id | '(' + defer(defer_expr) + ')' factor = primary + arbno(any("*/") + primary) expr = factor + arbno(any("+-") + factor) because I do not want to have to make up a new name, and because in practice, I've seen patterns in which there are many deferred evaluations, not just one as in this example. In other words, I want deferred evaluation to remain a conceptually inexpensive operation, and lambda is the only way of doing this. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
RE: [Python-Dev] Let's get rid of unbound methods
> duck typing? That's the Australian pronunciation of "duct taping". ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
RE: [Python-Dev] Trouble installing 2.4
Follow-up: When I install Python as Administrator, all is well. In that case (but not when installing it as me), it asks whether I want to install it for all users or for myself only. I then install pywin32 and it works. So it may be that a caveat is in order to people who do not install 2.4 as Administrator. ___ Python-Dev mailing list [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] Trouble installing 2.4
I'm using Windows XP SP2. Uninstalled 2.3, installed 2.4 (running as me, not as administrator). No problems so far. Tried installing pywin32-203.win32-py2.4.exe When I try to install it as me, it gets as far as "ready to install." When I click Next, it says Can't load Python for pre-install script and quits, even though earlier it said it had found Python 2.4 in the registry. When I try to install it as Administrator, it quits immediately, saying that it couldn't locate a Python 2.4 installation. My hypothesis: When I install 2.4 as me, it puts it in my user registry, not the system-wide registry, and then pywin32 can't find it. I'm going to unstall and try again as Administrator. ___ Python-Dev mailing list [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com