Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Jan 3, 3:38 am, alex23 wuwe...@gmail.com wrote: On Dec 27 2011, 8:01 pm, Eelco hoogendoorn.ee...@gmail.com wrote: But I consider it a reasonable change for a 'python 4', or whatever the next major version change will be called. You do realise there were 8 years between 2 3? You might be waiting for quite some time. Yes, I realize this discussion is quite theoretical in nature. Some of the more 'emotionally engaged' participants might do well to keep that in mind as well. Conversely, you could pitch in behind Rick Johnson's Python 4000 fork, I sure it's progressing nicely given how long Rick has been talking it up. Would you be so kind as to leave your personal feuds at the door? Writing a code-conversion tool to convert from *args to args::tuple would be quite easy indeed. You might want to ask people maintaining libraries in both 2.x 3.x via 2to3 just how well that's working out for them. If the impact of changes was trivially obvious, the programming landscape would look very different indeed. Of course if a conversion tool falters on even a single construct, automated conversion is not going to be reliable, and thats going to be a pain. But whatever python 4 will be like, its not going to be backwards compatible by definition; and at least I dont think this proposed change will contribute to the trouble of conversion between the two. It is really quite a superficial syntax tweak. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 27 2011, 8:01 pm, Eelco hoogendoorn.ee...@gmail.com wrote: But I consider it a reasonable change for a 'python 4', or whatever the next major version change will be called. You do realise there were 8 years between 2 3? You might be waiting for quite some time. Conversely, you could pitch in behind Rick Johnson's Python 4000 fork, I sure it's progressing nicely given how long Rick has been talking it up. Writing a code-conversion tool to convert from *args to args::tuple would be quite easy indeed. You might want to ask people maintaining libraries in both 2.x 3.x via 2to3 just how well that's working out for them. If the impact of changes was trivially obvious, the programming landscape would look very different indeed. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Jan 2, 8:38 pm, alex23 wuwe...@gmail.com wrote: Conversely, you could pitch in behind Rick Johnson's Python 4000 fork, I sure it's progressing nicely given how long Rick has been talking it up. It's NOT a fork Alex. It IS in fact the next logical step in Python's future evolution. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Jan 3, 3:39 pm, Rick Johnson rantingrickjohn...@gmail.com wrote: It's NOT a fork Alex. It IS in fact the next logical step in Python's future evolution. Link to the repo please, or STFU. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 28, 11:29 pm, Lie Ryan lie.1...@gmail.com wrote: On 12/28/2011 11:08 PM, Eelco wrote: I personally feel any performance benefits are but a plus; they are not the motivating factor for this idea. I simply like the added verbosity and explicitness, thats the bottom line. Any performance benefits are a plus, I agree, as long as it doesn't make my language looks like Perl. Now get off my lawn! Im no perl expert, but it says on the wikipedia page a common criticism is its overuse of otherwise meaningless special characters; and I would agree; I puked a little in my mouth looking at the code samples. I would argue that the use of single special characters to signal a relatively complex and uncommon construct is exactly what I am trying to avoid with this proposal. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 29, 2:23 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Thu, 29 Dec 2011 03:55:14 -0800, Eelco wrote: I would argue that the use of single special characters to signal a relatively complex and uncommon construct is exactly what I am trying to avoid with this proposal. This would be the proposal to change the existing head, *tail = sequence to your proposed: head, tail:: = ::sequence (when happy with the default list for tail), or head, tail::tuple = ::sequence to avoid an explicit call to tail = tuple(tail) after the unpacking. Either way, with or without an explicit type declaration on the left hand side, you are increasing the number of punctuation characters from one to four. If your aim is to minimize the number of punctuation characters, you're doing it wrong. -- Steven The goal is not to minimize the number of (special) characters to type. To goal is to minimize the number of special characters which are hard to interpret at a glance. I would prefer : over ::, but both are a single special character construct. Adding those characters once more on the rhs is similarly, not an increase in the number of concepts employed; merely a more explicit form of the same construct. And besides, I dont much like 'head, tail:: = ::sequence'. I threw that out there to appease the terseness advocates, but to me it largely defeats the purpose, because indeed it is hardly any different from the original. I like the explicit mentioning of the collection type to be constructed; that is what really brings it more towards 'for line in file' explicit obviousness to my mind. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Thu, 29 Dec 2011 03:55:14 -0800, Eelco wrote: I would argue that the use of single special characters to signal a relatively complex and uncommon construct is exactly what I am trying to avoid with this proposal. This would be the proposal to change the existing head, *tail = sequence to your proposed: head, tail:: = ::sequence (when happy with the default list for tail), or head, tail::tuple = ::sequence to avoid an explicit call to tail = tuple(tail) after the unpacking. Either way, with or without an explicit type declaration on the left hand side, you are increasing the number of punctuation characters from one to four. If your aim is to minimize the number of punctuation characters, you're doing it wrong. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 12/30/2011 12:23 AM, Steven D'Aprano wrote: On Thu, 29 Dec 2011 03:55:14 -0800, Eelco wrote: I would argue that the use of single special characters to signal a relatively complex and uncommon construct is exactly what I am trying to avoid with this proposal. This would be the proposal to change the existing head, *tail = sequence to your proposed: head, tail:: = ::sequence (when happy with the default list for tail), or head, tail::tuple = ::sequence to avoid an explicit call to tail = tuple(tail) after the unpacking. Either way, with or without an explicit type declaration on the left hand side, you are increasing the number of punctuation characters from one to four. If your aim is to minimize the number of punctuation characters, you're doing it wrong. Another drawback of it is that it looks misleadingly similar to C++ namespace notation. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Fri, Dec 30, 2011 at 10:24 AM, Lie Ryan lie.1...@gmail.com wrote: Another drawback of it is that it looks misleadingly similar to C++ namespace notation. Granted, but I don't see that as a drawback. The current notation is just as similar to C's pointer-dereference notation, but that hasn't led people to think that tail holds a pointer to the location where something should be stored. This would be a serious concern with notations that are common across many languages (eg x*y to mean multiplication, which isn't strictly what mathematics uses), but with language-specific notations, especially such brief ones, it's understood that there'll be duplication. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 27, 11:57 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Mon, 26 Dec 2011 13:41:34 -0800, Eelco wrote: On Dec 25, 6:05 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sun, 25 Dec 2011 07:38:17 -0800, Eelco wrote: [...] How is 'head, *tail = sequence' or semantically entirely equivalently, 'head, tail::list = sequence' any different then? Of course after interpretation/compilation, what it boils down to is that we are constructing a list and binding it to the identifier tail, but that is not how it is formulated in python as a language I'm afraid it is. Here's the definition of assignment in Python 3: http://docs.python.org/py3k/reference/simple_stmts.html#assignment- statements Que? You have claimed that constructing a list and binding it to the identifier is not how iterator unpacking is formulated in Python the language. But that is wrong. That *is* how iterator unpacking is formulated in Python the language. The reference manual goes into detail on how assignment is defined in Python. You should read it. 'head, *tail = sequence' Is how one currently unpacks a head and tail in idiomatic python This is semantically equivalent to 'head = sequence[0]' 'tail = list(sequence[1:])' There's a reason this feature is called *iterable* unpacking: it operates on any iterable object, not just indexable sequences. 'head, *tail = sequence' is not just semantically equivalent to, but *actually is* implemented as something very close to: temp = iter(sequence) head = next(temp) tail = list(temp) del temp Extended iterable unpacking, as in 'head, *middle, tail = sequence' is a little more complex, but otherwise the same: it operates using the iterator protocol, not indexing. I recommend you read the PEP, if you haven't already done so. http://www.python.org/dev/peps/pep-3132/ But these forms are linguistically different, in too many different ways to mention. How about mentioning even one way? Because I have no idea what differences you are referring to, or why you think they are important. The one spans two lines; the other one. Need I go on? We dont have something of the form 'tail = list_tail(sequence)'. I'm afraid we do. See the definition of assignment again. Que? Again, you make a claim about Python which is contradicted by the documented behaviour of the language. You claim that we DON'T have something of the form 'tail = list_tail(sequence)', but that is *exactly* what we DO have: extracting the tail from an iterator. Obviously there is no built-in function list_tail but we get the same effect by just using list() on an iterator after advancing past the first item. My claim is that the two semantically identical formulations above do not have isomorphic linguistic form. As far as I can make sense of your words, you seem to be disputing this claim, but its a claim as much worth debating as that the sun rises in the east. Isomorphic linguistic form? Are you referring to the idea from linguistics that there are analogies between the structure of phonic and semantic units? E.g. that the structures (phoneme, syllable, word) and (sememe, onomateme, sentence) are analogous. I don't see why this is relevant, or which units you are referring to -- the human-language description of what Python does, high-level Python language features, Python byte-code, or machine code. Not that it matters, but it is unlikely that any of those are isomorphic in the linguistic sense, and I am not making any general claim that they are. If not, I have no idea what you are getting at, except possibly trying to hide behind obfuscation. I wasnt too worried about obfuscation, since I think there is little left to lose on that front. Let me make a last-ditch effort to explain though: When python reads your code, it parses it into a symbolic graph representation. The two snippets under consideration do not parse into the same graph, in the same way that insignificant whitespace or arbitrary identifier names do, for instance. Hence, not linguistically isomorphic. The very function of a programming language is to transform this representation of the code into semantically identical but different code; (machine code, eventually). You fail to grok the difference between semantic equivalence and linguistic equivalence. Yes, there can be a semantic equivalence between iterable unpacking and a syntax of the form tail_list(sequence). And python does indeed probably apply a transformation of this kind under the hood (though we couldnt care less what it does exactly). AND IT PERFORMS THAT TRANSFORMATION USING THE TYPE CONSTRAINT GIVEN. Another example: the C code 'float x = 3', how would you interpret that? Is it 'not a type constraint on x', because eventually your C compiler turns it into machine code that doesnt leave a trace of that type constraint anyway? No, its a type
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 28, 2:11 am, Rick Johnson rantingrickjohn...@gmail.com wrote: On Dec 27, 5:10 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sun, 25 Dec 2011 07:47:20 -0800, Eelco wrote: Your original use-case, where you want to change the type of tail from a list to something else, is simply solved by one extra line of code: head, *tail = sequence tail = tuple(tail) i wonder if we could make this proposal a bit more Pythonic? Hmm... head, tuple(tail) = sequence ...YEP! That has been considered; it was my first thought too, but this requires one to break the symmetry between collection packing and unpacking. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 28, 8:08 am, Chris Angelico ros...@gmail.com wrote: On Wed, Dec 28, 2011 at 5:25 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Wed, 28 Dec 2011 15:06:37 +1100, Chris Angelico wrote: ... suppose you have a huge set/frozenset using tuples as the keys, and one of your operations is to shorten all keys by removing their first elements. Current Python roughly doubles the cost of this operation, since you can't choose what type the tail is made into. The First Rule of Program Optimization: - Don't do it. The Second Rule of Program Optimization (for experts only): - Don't do it yet. Building syntax to optimize imagined problems is rarely a good idea. The difference between 2 seconds processing your huge set and 4 seconds processing it is unlikely to be significant unless you have dozens of such huge sets and less than a minute to process them all. And your idea of huge is probably not that big... it makes me laugh when people ask how to optimize code because my actual data has HUNDREDS of items!. Whoop-de-doo. Come back when you have a hundred million items, then I'll take your question seriously. (All references to you and your are generic, and not aimed at Chris personally. Stupid English language.) And what you're seeing there is the _best possible_ situation I could think of, the strongest possible justification for new syntax. Granted, that may say more about me and my imagination than about the problem, but the challenge is open: Come up with something that actually needs this. ChrisA I personally feel any performance benefits are but a plus; they are not the motivating factor for this idea. I simply like the added verbosity and explicitness, thats the bottom line. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 28, 12:07 am, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Mon, 26 Dec 2011 13:51:50 -0800, Eelco wrote: [...] If your point is that parens are used more often than packing/unpacking, that's almost certainly true, since function calls (including method invocations) are so prevalent in pretty much any code. But what does that prove? That proves the original point of contention: that the below* is suboptimal language design, Well duh. This is where the referee should interrupt you for snipping someones citation right before a 'but' I was mocking the idea that the meaning of * is context-dependent is a bad thing by pointing out that we accept context-dependent meaning for round brackets () without any difficulties. Of course it is suboptimal language design -- it couldn't fail to be. Context-dependency is not necessarily a bad thing. You know, so you dont end up simply restating my point while trying to make it seem like you disagree. not because terseness always trumps verbosity, but because commonly-used constructs (such as parenthesis or round brackets or whatever you wish to call them) Parentheses are not a construct. They are symbols (punctuation marks) which are applied to at least three different constructs: grouping, function calls, class inheritance lists. Parenthesis encompass a class of constructs. Happy now? are more deserving of the limited space in both the ascii table and your reflexive memory, than uncommonly used ones. Right. And since sequence packing and unpacking is a common idiom, it deserves to be given punctuation. That's my opinion. Its a valid opinion. But if we are going to be quantitative about terms such as 'common', you know that there will be at least an order of magnitude difference between these constructs in commonality, if not two. Thats what makes your example a poor one. If you could verbosify a construct of the same commonality and arrive at equally absurd code, you would have a point. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 12/28/2011 11:08 PM, Eelco wrote: I personally feel any performance benefits are but a plus; they are not the motivating factor for this idea. I simply like the added verbosity and explicitness, thats the bottom line. Any performance benefits are a plus, I agree, as long as it doesn't make my language looks like Perl. Now get off my lawn! -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 27, 1:52 am, Chris Angelico ros...@gmail.com wrote: On Tue, Dec 27, 2011 at 10:44 AM, Eelco hoogendoorn.ee...@gmail.com wrote: extended collection unpacking, as in 'head,*tail=sequence', is quite a rare construct indeed, and here I very strongly feel a more explicit syntax is preferrable. You may be right, but... ... if collection packing/unpacking would be presented as a more general construct from the start, 'head,tail::tuple=sequence' would be hard to miss. ... it doesn't really justify a _change_. When a language is in its infancy and the only code written in it is on the designers' own computers, these sorts of debates can be tipped by relatively small differences - is it more readable, is it quick enough to type, etc. But once a language reaches a level of maturity, changes need to overwhelm the but it's a change hurdle - breaking existing code is majorly dangerous, and keeping two distinct ways of doing something means you get the worst of both worlds. We can argue till the cows come home as to which way would be better, _had Python started with it_. I don't think there's anything like enough difference to justify the breakage/duplication. That I agree with; I think it is a questionable idea to introduce this in a new python 3 version. But I consider it a reasonable change for a 'python 4', or whatever the next major version change will be called. Writing a code-conversion tool to convert from *args to args::tuple would be quite easy indeed. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Mon, 26 Dec 2011 13:41:34 -0800, Eelco wrote: On Dec 25, 6:05 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sun, 25 Dec 2011 07:38:17 -0800, Eelco wrote: [...] How is 'head, *tail = sequence' or semantically entirely equivalently, 'head, tail::list = sequence' any different then? Of course after interpretation/compilation, what it boils down to is that we are constructing a list and binding it to the identifier tail, but that is not how it is formulated in python as a language I'm afraid it is. Here's the definition of assignment in Python 3: http://docs.python.org/py3k/reference/simple_stmts.html#assignment- statements Que? You have claimed that constructing a list and binding it to the identifier is not how iterator unpacking is formulated in Python the language. But that is wrong. That *is* how iterator unpacking is formulated in Python the language. The reference manual goes into detail on how assignment is defined in Python. You should read it. 'head, *tail = sequence' Is how one currently unpacks a head and tail in idiomatic python This is semantically equivalent to 'head = sequence[0]' 'tail = list(sequence[1:])' There's a reason this feature is called *iterable* unpacking: it operates on any iterable object, not just indexable sequences. 'head, *tail = sequence' is not just semantically equivalent to, but *actually is* implemented as something very close to: temp = iter(sequence) head = next(temp) tail = list(temp) del temp Extended iterable unpacking, as in 'head, *middle, tail = sequence' is a little more complex, but otherwise the same: it operates using the iterator protocol, not indexing. I recommend you read the PEP, if you haven't already done so. http://www.python.org/dev/peps/pep-3132/ But these forms are linguistically different, in too many different ways to mention. How about mentioning even one way? Because I have no idea what differences you are referring to, or why you think they are important. We dont have something of the form 'tail = list_tail(sequence)'. I'm afraid we do. See the definition of assignment again. Que? Again, you make a claim about Python which is contradicted by the documented behaviour of the language. You claim that we DON'T have something of the form 'tail = list_tail(sequence)', but that is *exactly* what we DO have: extracting the tail from an iterator. Obviously there is no built-in function list_tail but we get the same effect by just using list() on an iterator after advancing past the first item. My claim is that the two semantically identical formulations above do not have isomorphic linguistic form. As far as I can make sense of your words, you seem to be disputing this claim, but its a claim as much worth debating as that the sun rises in the east. Isomorphic linguistic form? Are you referring to the idea from linguistics that there are analogies between the structure of phonic and semantic units? E.g. that the structures (phoneme, syllable, word) and (sememe, onomateme, sentence) are analogous. I don't see why this is relevant, or which units you are referring to -- the human-language description of what Python does, high-level Python language features, Python byte-code, or machine code. Not that it matters, but it is unlikely that any of those are isomorphic in the linguistic sense, and I am not making any general claim that they are. If not, I have no idea what you are getting at, except possibly trying to hide behind obfuscation. Rather, we annotate the identifier 'tail' with an attribute that unquestionably destinates it to become a list*. It is no longer that 'tail' will just take anything that pops out of the expression on the right hand side; Of course it will. Python is a dynamically typed language. It doesn't suddenly develop static types to ensure that 'tail' becomes a list; 'tail' is bound to a list because that's what the assignment statement provides. How python accomplishes any of this under the hood is entirely immaterial. The form is that of a compile-time type constraint, regardless of whether the BDFL ever thought about it in these terms. Compile-time type constraints only have meaning in statically-typed languages. Otherwise, you are applying an analogy that simply doesn't fit, like claiming that the motion of paper airplanes and birds are equivalent just because in English we use the word fly to describe them both. The differences between what Python actually does and compile-time type- constraints are greater than the similarities. Similarities: (1) In both cases, 'tail' ends up as a list. Differences: (1) Compiler enforces the constraint that the identifier 'tail' is always associated with a list and will prevent any attempt to associate 'tail' with some value that is not a list. Python does nothing like this: the identifier 'tail' has no type restrictions at all, and can be
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Mon, 26 Dec 2011 13:51:50 -0800, Eelco wrote: [...] If your point is that parens are used more often than packing/unpacking, that's almost certainly true, since function calls (including method invocations) are so prevalent in pretty much any code. But what does that prove? That proves the original point of contention: that the below* is suboptimal language design, Well duh. I was mocking the idea that the meaning of * is context-dependent is a bad thing by pointing out that we accept context-dependent meaning for round brackets () without any difficulties. Of course it is suboptimal language design -- it couldn't fail to be. Context-dependency is not necessarily a bad thing. not because terseness always trumps verbosity, but because commonly-used constructs (such as parenthesis or round brackets or whatever you wish to call them) Parentheses are not a construct. They are symbols (punctuation marks) which are applied to at least three different constructs: grouping, function calls, class inheritance lists. are more deserving of the limited space in both the ascii table and your reflexive memory, than uncommonly used ones. Right. And since sequence packing and unpacking is a common idiom, it deserves to be given punctuation. That's my opinion. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sun, 25 Dec 2011 07:47:20 -0800, Eelco wrote: Explicit and implicit are not well-defined terms, We can at least agree on that. but I would say that at the moment the signal is implicit, in the sense that one cannot see what is going on by considering the rhs in isolation. That is a ridiculous argument. If you ignore half the statement, of course you can't tell what is going on. Normally in python, an assignment just binds the rhs to the identifiers on the lhs, but in case of collection (un)packing, this rule that holds almost all of the time is broken, and the assignment statement implies a far more complicated construct, with a far more subtle meaning, and non-constant time complexity. Python assignment in general is not constant time. If the left hand side is a single identifier (a name, a dotted attribute, a subscription or slice, etc.) then the assignment is arguably constant time (hand-waving away complications like attribute access, hash table collisions, descriptors, etc.); but if the left hand side is a list of targets, e.g.: a, b, c = sequence then the assignment is O(N). Python has to walk the sequence (actually, any iterator) and assign each of N items to N identifiers, hence O(N) not O(1). The trivial case of a single value on the left hand side: x = 1 is just the degenerate case for N=1. Thats not a terrible thing, but a little extra explicitness there would not hurt, I think it will. It makes the assignment more verbose to no benefit. and like I argued many times before, it is a nice unification with the situation where the unpacking can not be implicit, like inside a function call rather than assignment. That's one opinion; but there's no need for any extra explicitness since the definition of assignment in Python already explicitly includes iterable unpacking. How much explicitness do you need? n = len(::sequence) Now you are just discrediting yourself in terms of having any idea what you are talking about. ::sequence is redundant and unnecessary whether it is inside a function call to len or on the right hand side of an assignment. In both cases, it adds nothing to the code except noise. Your proposal is surreal. You started off this conversation arguing that the existing idiom for extended iterator unpacking, e.g. head, *tail = sequence is too hard to understand because it uses punctuation, and have ended up recommending that we replace it with: head, tail:: = ::sequence instead (in the generic case where you don't want to use a different type for tail). Your original use-case, where you want to change the type of tail from a list to something else, is simply solved by one extra line of code: head, *tail = sequence tail = tuple(tail) You have written thousands of words to save one line in an idiom which you claim is very uncommon. Perhaps your understanding of pythonic is not as good as you imagine. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 27, 5:10 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sun, 25 Dec 2011 07:47:20 -0800, Eelco wrote: Your original use-case, where you want to change the type of tail from a list to something else, is simply solved by one extra line of code: head, *tail = sequence tail = tuple(tail) i wonder if we could make this proposal a bit more Pythonic? Hmm... head, tuple(tail) = sequence ...YEP! -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Wed, Dec 28, 2011 at 10:10 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Your original use-case, where you want to change the type of tail from a list to something else, is simply solved by one extra line of code: head, *tail = sequence tail = tuple(tail) That achieves the goal of having tail as a different type, but it does have the additional cost of constructing and then discarding a temporary list. I know this is contrived, but suppose you have a huge set/frozenset using tuples as the keys, and one of your operations is to shorten all keys by removing their first elements. Current Python roughly doubles the cost of this operation, since you can't choose what type the tail is made into. But if that's what you're trying to do, it's probably best to slice instead of unpacking. Fortunately, the Zen of Python one obvious way to do it doesn't stop there being other ways that work too. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Wed, 28 Dec 2011 15:06:37 +1100, Chris Angelico wrote: On Wed, Dec 28, 2011 at 10:10 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Your original use-case, where you want to change the type of tail from a list to something else, is simply solved by one extra line of code: head, *tail = sequence tail = tuple(tail) That achieves the goal of having tail as a different type, but it does have the additional cost of constructing and then discarding a temporary list. I know this is contrived, but suppose you have a huge set/frozenset using tuples as the keys, and one of your operations is to shorten all keys by removing their first elements. Current Python roughly doubles the cost of this operation, since you can't choose what type the tail is made into. The First Rule of Program Optimization: - Don't do it. The Second Rule of Program Optimization (for experts only): - Don't do it yet. Building syntax to optimize imagined problems is rarely a good idea. The difference between 2 seconds processing your huge set and 4 seconds processing it is unlikely to be significant unless you have dozens of such huge sets and less than a minute to process them all. And your idea of huge is probably not that big... it makes me laugh when people ask how to optimize code because my actual data has HUNDREDS of items!. Whoop-de-doo. Come back when you have a hundred million items, then I'll take your question seriously. (All references to you and your are generic, and not aimed at Chris personally. Stupid English language.) But if that's what you're trying to do, it's probably best to slice instead of unpacking. Assuming the iterable is a sequence. Fortunately, most iterable constructors accept iterators directly, so for the cost of an extra line (three instead of two), you can handle data structures as big as will fit into memory: # I want to keep both the old and the new set it = iter(huge_set_of_tuples) head = next(it) # actually an arbitrary item tail = set(x[1:] for x in it) # and everything else If you don't need both the old and the new: head = huge_set_of_tuples.pop() tail = set() while huge_set_of_tuples: tail.add(huge_set_of_tuples.pop()[1:]) assert huge_set_of_tuples == set([]) If you rely on language features, who knows how efficient the compiler will be? head, tail::tuple = ::sequence may create a temporary list before building the tuple anyway. And why not? That's what this *must* do: head, second, middle::tuple, second_from_last, last = ::iterator because tuples are immutable and can't be grown or shrunk, so why assume the language designers special cased the first form above? Fortunately, the Zen of Python one obvious way to do it doesn't stop there being other ways that work too. Exactly. It is astonishing how many people think that if there isn't a built-in language feature, with special syntax, to do something, there's a problem that needs to be solved. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Wed, Dec 28, 2011 at 5:25 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Wed, 28 Dec 2011 15:06:37 +1100, Chris Angelico wrote: ... suppose you have a huge set/frozenset using tuples as the keys, and one of your operations is to shorten all keys by removing their first elements. Current Python roughly doubles the cost of this operation, since you can't choose what type the tail is made into. The First Rule of Program Optimization: - Don't do it. The Second Rule of Program Optimization (for experts only): - Don't do it yet. Building syntax to optimize imagined problems is rarely a good idea. The difference between 2 seconds processing your huge set and 4 seconds processing it is unlikely to be significant unless you have dozens of such huge sets and less than a minute to process them all. And your idea of huge is probably not that big... it makes me laugh when people ask how to optimize code because my actual data has HUNDREDS of items!. Whoop-de-doo. Come back when you have a hundred million items, then I'll take your question seriously. (All references to you and your are generic, and not aimed at Chris personally. Stupid English language.) And what you're seeing there is the _best possible_ situation I could think of, the strongest possible justification for new syntax. Granted, that may say more about me and my imagination than about the problem, but the challenge is open: Come up with something that actually needs this. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 5:15 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sun, 25 Dec 2011 06:55:28 -0800, Eelco wrote: Anyway, braces are used at least an order of magnitude more than collection packing/ unpacking in typical code. That's a wild and unjustified claim. Here's a quick and dirty test, using the standard library as an example of typical idiomatic code: [steve@orac ~]$ cd /usr/lib/python2.6 [steve@orac python2.6]$ grep [*]args *.py | wc -l 270 [steve@orac python2.6]$ grep { *.py | wc -l 550 Doesn't look like a factor of 10 difference to me. Now try it without changing the subject from round braces to everything but round braces. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 5:23 pm, Chris Angelico ros...@gmail.com wrote: On Mon, Dec 26, 2011 at 2:38 AM, Eelco hoogendoorn.ee...@gmail.com wrote: Until that time, im going to ask you to take 'type constraint' by its literal meaning; a coercion of the type of a symbol, rather than whatever particular meaning it has acquired for you (it might help if you explained that). Im not sure if it was you that brought that up, but let me reiterate that I dont mean a 'type cast', which is a runtime concept. A 'type constraint' is purely a linguistic construct that will be 'compiled out') The dictionary definition of constraint is a limitation or restriction, and you're right that it can be compiled out. In fact, that is probably the best definition. Assuming everything is written correctly, you should be able to eliminate all constraints and the code will still function correctly*; but having the constrains means that certain illegal operations will throw errors. Here's two examples of tuple unpacking, one with a type constraint, the other without: a, b = ('hello', [1,2,3] ) a, b::list = ('hello', [1,2,3] ) The constraint on the second line means that, if the second element is not a list, the interpreter should throw an error. It does NOT mean to completely change the meaning of the statement to _make_ the last argument into a list. That is not the job of a constraint. Thank you for providing clarification on what a 'type constraint' means to you. That clears things up a bit. What you are talking about goes by the name of a 'dynamic type CHECK'; some kind of syntactic sugar for something like 'assert(type(obj)==sometype)'. Like a 'type cast', this is also a runtime concept. How you manage to confuse that with what I am talking about, given that ive stated many times I am not talking about a runtime construct but a compile-time construct, is quite beyond me. (not to mention that ive quite explicitly stated what I mean by 'type constraint' many times now). By contrast, here is the first google hit for 'type constraint'. http://msdn.microsoft.com/en-us/library/d5x73970.aspx Note that this is a different application of the concept of a type constraint, but nonetheless, the concept is as I stated it: a constraint to the type of a symbol to modify its compile-time semantics. To cite from its first paragraph: ...you can apply restrictions to the kinds of types ... by using a type that is not allowed by a constraint, the result is a COMPILE-TIME ERROR (emphasis mine) -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Tue, Dec 27, 2011 at 7:39 AM, Eelco hoogendoorn.ee...@gmail.com wrote: Now try it without changing the subject from round braces to everything but round braces. Around here, the term braces means the curly ones - { and } - that delimit blocks of code in C, and dictionaries/sets in Python. Brackets may be what you're looking for, if you mean all of ()[]{}. Or if you just mean (), they're called parentheses. If your point is that parens are used more often than packing/unpacking, that's almost certainly true, since function calls (including method invocations) are so prevalent in pretty much any code. But what does that prove? ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Tue, Dec 27, 2011 at 7:58 AM, Eelco hoogendoorn.ee...@gmail.com wrote: What you are talking about goes by the name of a 'dynamic type CHECK'; some kind of syntactic sugar for something like 'assert(type(obj)==sometype)'. Like a 'type cast', this is also a runtime concept... By contrast, here is the first google hit for 'type constraint'. http://msdn.microsoft.com/en-us/library/d5x73970.aspx ...you can apply restrictions to the kinds of types ... by using a type that is not allowed by a constraint, the result is a COMPILE-TIME ERROR (emphasis mine) A constraint can be applied at compile time or at run time. It'd be valid to apply them at edit time, if you so chose - your editor could refuse to save your file until you fix the problem. Doesn't mean a thing. Python, by its nature, cannot do compile-time type checking. Under no circumstances, however, does this justify the use of the term constraint to mean utterly different semantics of the same code. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 6:05 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sun, 25 Dec 2011 07:38:17 -0800, Eelco wrote: On Dec 25, 2:12 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sat, 24 Dec 2011 06:39:39 -0800, Eelco wrote: On Dec 20, 4:30 am, alex23 wuwe...@gmail.com wrote: On Dec 19, 8:15 pm, Eelco hoogendoorn.ee...@gmail.com wrote: What does that have to do with collection packing/unpacking? It's mocking your insistance that collection unpacking is a type constraint. This is really going to be the last time I waste any words on this: If only that were true, but after sending this post, you immediately followed up with FIVE more posts on this subject in less than half an hour. Did I waste any more words on collection packing and type constraints? No, I did not. (though I am about to, and am willing to do so for every question that seems genuinely aimed at engaging me on the matter) Did I intend to say that I was going to let a single troll shut down my entire topic? No, I did not. Ah, well whatever you *intended* wasn't clear from your comment. At least not clear to *me*. Always glad to help. Yes, indeed it would be abuse of language to call this a type constraint, since the fact that y is a list is indeed an outcome of whatever happens to pop out at the right hand side. One could redefine the identifier list to return any kind of object. So far, we agree on this. Good. How is 'head, *tail = sequence' or semantically entirely equivalently, 'head, tail::list = sequence' any different then? Of course after interpretation/compilation, what it boils down to is that we are constructing a list and binding it to the identifier tail, but that is not how it is formulated in python as a language I'm afraid it is. Here's the definition of assignment in Python 3:http://docs.python.org/py3k/reference/simple_stmts.html#assignment- statements Que? 'head, *tail = sequence' Is how one currently unpacks a head and tail in idiomatic python This is semantically equivalent to 'head = sequence[0]' 'tail = list(sequence[1:])' But these forms are linguistically different, in too many different ways to mention. We dont have something of the form 'tail = list_tail(sequence)'. I'm afraid we do. See the definition of assignment again. Que? My claim is that the two semantically identical formulations above do not have isomorphic linguistic form. As far as I can make sense of your words, you seem to be disputing this claim, but its a claim as much worth debating as that the sun rises in the east. Rather, we annotate the identifier 'tail' with an attribute that unquestionably destinates it to become a list*. It is no longer that 'tail' will just take anything that pops out of the expression on the right hand side; Of course it will. Python is a dynamically typed language. It doesn't suddenly develop static types to ensure that 'tail' becomes a list; 'tail' is bound to a list because that's what the assignment statement provides. How python accomplishes any of this under the hood is entirely immaterial. The form is that of a compile-time type constraint, regardless of whether the BDFL ever thought about it in these terms. rather, the semantics of what will go on at right hand side is coerced by the constraint placed on 'tail'. But it isn't a constraint placed on 'tail'. It is a consequence of the definition of assignment in Python 3. 'tail' becomes bound to a list because that is what the assignment statement is defined to do in that circumstance, not because the identifier (symbol) 'tail' is constrained to only accept lists. 'tail' may not even exist before hand, so talking about constraints on 'tail' is an abuse of language, AS YOU AGREED ABOVE. 'tail' is (re)declared on the spot as a brand-new identifier (type constraint included); whether it exists before has no significance whatsoever, since python allows rebinding of identifiers. *(I call that a 'type constraint', because that is what it literally is; No. It is literally a name binding of a dynamically typed, unconstrained name to an object which happens to be a list. Let me take a step back and reflect on the form of the argument we are having. I claim the object in front of us is a 'cube'. You deny this claim, by countering that it is 'just a particular configuration of atoms'. 'look at the definition!', you say; 'its just a list of coordinates, no mention of cubes whatsoever.'. 'Look at the definition of a cube', I counter. 'This particular list of coordinates happens to fit the definition, whether the BDFT intended to or not'. You are correct, in the sense that I do not disagree that it is a particular configuration of atoms. But if you had a better understanding of cubes, youd realize it meets the definition; the fact that people might not make a habit of pausing at this fact (there is generally speaking
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 26, 10:01 pm, Chris Angelico ros...@gmail.com wrote: On Tue, Dec 27, 2011 at 7:39 AM, Eelco hoogendoorn.ee...@gmail.com wrote: Now try it without changing the subject from round braces to everything but round braces. Around here, the term braces means the curly ones - { and } - that delimit blocks of code in C, and dictionaries/sets in Python. Brackets may be what you're looking for, if you mean all of ()[]{}. Or if you just mean (), they're called parentheses. If your point is that parens are used more often than packing/unpacking, that's almost certainly true, since function calls (including method invocations) are so prevalent in pretty much any code. But what does that prove? That proves the original point of contention: that the below* is suboptimal language design, not because terseness always trumps verbosity, but because commonly-used constructs (such as parenthesis or round brackets or whatever you wish to call them) are more deserving of the limited space in both the ascii table and your reflexive memory, than uncommonly used ones. *original mock code by steve: class MyClass superclasslist A, B C: def method argumentlist self, x, y: t = tuple 1, 2 tuple 3, 4 endtuple endtuple return group x + y endgroup * group x - y endgroup -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 26, 10:05 pm, Chris Angelico ros...@gmail.com wrote: On Tue, Dec 27, 2011 at 7:58 AM, Eelco hoogendoorn.ee...@gmail.com wrote: What you are talking about goes by the name of a 'dynamic type CHECK'; some kind of syntactic sugar for something like 'assert(type(obj)==sometype)'. Like a 'type cast', this is also a runtime concept... By contrast, here is the first google hit for 'type constraint'. http://msdn.microsoft.com/en-us/library/d5x73970.aspx ...you can apply restrictions to the kinds of types ... by using a type that is not allowed by a constraint, the result is a COMPILE-TIME ERROR (emphasis mine) A constraint can be applied at compile time or at run time. It'd be valid to apply them at edit time, if you so chose - your editor could refuse to save your file until you fix the problem. Doesn't mean a thing. A constraint in the sense that I have explained many times now, can in no way, shape or form be applied at run time. Youd have better luck applying a consternation to a squirrel. Perhaps you meant 'type check' again? But then again, that makes no sense whatsoever at compile- time... Im starting to doubt if there is any sense to be found here at all. Anyway, ill take your further silence on the matter as a 'sorry I derailed your thread with my confusion of terminology' Python, by its nature, cannot do compile-time type checking. Python can do whatever its designers have put into it. In this case, that includes the emission of different code based on a (type) annotation at the point of declaration of an identifier (only in the particular circumstance of collection unpacking though, as far as I am aware). Under no circumstances, however, does this justify the use of the term constraint to mean utterly different semantics of the same code. Thank you for your theory on justice. Im sure its fascinating, but until you get around to actually explaining it, im going to have to be conservative and stick with the jargon in common use though, sorry. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Tue, Dec 27, 2011 at 8:51 AM, Eelco hoogendoorn.ee...@gmail.com wrote: That proves the original point of contention: that [Steve's demo code] is suboptimal language design, not because terseness always trumps verbosity, but because commonly-used constructs (such as parenthesis or round brackets or whatever you wish to call them) are more deserving of the limited space in both the ascii table and your reflexive memory, than uncommonly used ones. In Magic: The Gathering RD, they have a term (the article reporting which I can't actually find at the moment) called spread complexity or fan complexity - the idea being that as you fan out a booster pack, you see a certain amount of complexity in front of you. The designers can afford to put more complex cards in as rares than they can as commons, because you see ten commons for every rare - so a common factors ten times as much as a rare in spread complexity. (Mark Rosewater, my apologies if I'm misremembering here!) The same applies here. When you cast your eye over a program, you're going to see certain syntactic elements a lot. Assignment, arithmetic, blocks of code (ie indent/dedent), and function calls are all extremely common; lambdas, the use of decorators, and exception handling are somewhat uncommon; and metaclasses, the writing of decorators, and reloading of modules are all quite rare. The elements that occur frequently should be: a) Readable and grokkable; b) Easily typed on a regular keyboard - no using ASCII character 126 to mean negation, tyvm! c) Make sense. Rarer elements (and I'm not talking about xenon and plutonium here) are allowed to have long names, obscure syntax, or even be shoved away in odd modules (the way module reloading is in Python 3). If 0.1% of your code is suddenly twice as large as it used to be, will you notice? But if a new syntax adds even 5% to the mindspace requirement of basic assignment, your code will majorly suffer. In summary: Terseness trumps verbosity primarily for common operations, and only when doing so does not violate rules a and c above. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Tue, Dec 27, 2011 at 9:12 AM, Eelco hoogendoorn.ee...@gmail.com wrote: On Dec 26, 10:05 pm, Chris Angelico ros...@gmail.com wrote: A constraint can be applied at compile time or at run time. It'd be valid to apply them at edit time, if you so chose - your editor could refuse to save your file until you fix the problem. Doesn't mean a thing. A constraint in the sense that I have explained many times now, can in no way, shape or form be applied at run time. Youd have better luck applying a consternation to a squirrel. Perhaps you meant 'type check' again? But then again, that makes no sense whatsoever at compile- time... Im starting to doubt if there is any sense to be found here at all. A constraint failure causes an error at the time it's discovered. 1) Your editor pops up a message the instant you type something with such an error, and forces you to correct it before going on. 2) Your compiler refuses to produce byte-code for the module. 3) When the line of code is executed, an exception is thrown. All of these are valid ways of handling a constraint. Here is a Python example of a type constraint: def foo(arg): if not isinstance(arg,list): raise This won't work. If you call it with something that's not a list, you get an error. Call it with a list, and execution continues normally. That's a constraint. Of course, it might not be a _type_ constraint: def foo(arg): if arg5: raise This won't work either. # and yes, that's oddly truer in Python 3 (Aside: In Pike, I can actually put that into a type constraint (declare the argument to be int(5..) for instance). This, however, is not germane to the conversation.) Anyway, ill take your further silence on the matter as a 'sorry I derailed your thread with my confusion of terminology' Like Mary Poppins, I never apologize for derailing threads :) Python, by its nature, cannot do compile-time type checking. Python can do whatever its designers have put into it. In this case, that includes the emission of different code based on a (type) annotation at the point of declaration of an identifier (only in the particular circumstance of collection unpacking though, as far as I am aware). Of course, but how can Python, without a completely different structure, do compile-time checking of object types? Everything can be monkey-patched at run-time. Anything could be affected by any function call. It's impossible to say for certain, at compile time, what data type anything will have. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 26, 11:27 pm, Chris Angelico ros...@gmail.com wrote: On Tue, Dec 27, 2011 at 8:51 AM, Eelco hoogendoorn.ee...@gmail.com wrote: That proves the original point of contention: that [Steve's demo code] is suboptimal language design, not because terseness always trumps verbosity, but because commonly-used constructs (such as parenthesis or round brackets or whatever you wish to call them) are more deserving of the limited space in both the ascii table and your reflexive memory, than uncommonly used ones. In Magic: The Gathering RD, they have a term (the article reporting which I can't actually find at the moment) called spread complexity or fan complexity - the idea being that as you fan out a booster pack, you see a certain amount of complexity in front of you. The designers can afford to put more complex cards in as rares than they can as commons, because you see ten commons for every rare - so a common factors ten times as much as a rare in spread complexity. (Mark Rosewater, my apologies if I'm misremembering here!) The same applies here. When you cast your eye over a program, you're going to see certain syntactic elements a lot. Assignment, arithmetic, blocks of code (ie indent/dedent), and function calls are all extremely common; lambdas, the use of decorators, and exception handling are somewhat uncommon; and metaclasses, the writing of decorators, and reloading of modules are all quite rare. The elements that occur frequently should be: a) Readable and grokkable; b) Easily typed on a regular keyboard - no using ASCII character 126 to mean negation, tyvm! c) Make sense. Rarer elements (and I'm not talking about xenon and plutonium here) are allowed to have long names, obscure syntax, or even be shoved away in odd modules (the way module reloading is in Python 3). If 0.1% of your code is suddenly twice as large as it used to be, will you notice? But if a new syntax adds even 5% to the mindspace requirement of basic assignment, your code will majorly suffer. In summary: Terseness trumps verbosity primarily for common operations, and only when doing so does not violate rules a and c above. ChrisA Good to see there is something we agree upon completely. Not that I mean to say the question as to how verbose a syntax is appropriate for collection (un)packing is settled; one could reasonably argue they find tail::tuple too verbose. But parenthesis are not a terribly good example to compare to, since they are infact so much more used they are clearly in another category. *args and **kwargs are debateable in the appropriateness of their terseness (but I personally like to err on the side of verbosity), but extended collection unpacking, as in 'head,*tail=sequence', is quite a rare construct indeed, and here I very strongly feel a more explicit syntax is preferrable. That is, as a seasoned python 2 user, I wouldnt have been willing to gamble on what this does when id come across it for the first time in python 3. Could as well be a completely new use of the asterisk. But if collection packing/unpacking would be presented as a more general construct from the start, 'head,tail::tuple=sequence' would be hard to miss. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Tue, Dec 27, 2011 at 10:44 AM, Eelco hoogendoorn.ee...@gmail.com wrote: extended collection unpacking, as in 'head,*tail=sequence', is quite a rare construct indeed, and here I very strongly feel a more explicit syntax is preferrable. You may be right, but... ... if collection packing/unpacking would be presented as a more general construct from the start, 'head,tail::tuple=sequence' would be hard to miss. ... it doesn't really justify a _change_. When a language is in its infancy and the only code written in it is on the designers' own computers, these sorts of debates can be tipped by relatively small differences - is it more readable, is it quick enough to type, etc. But once a language reaches a level of maturity, changes need to overwhelm the but it's a change hurdle - breaking existing code is majorly dangerous, and keeping two distinct ways of doing something means you get the worst of both worlds. We can argue till the cows come home as to which way would be better, _had Python started with it_. I don't think there's anything like enough difference to justify the breakage/duplication. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sat, 24 Dec 2011 06:54:07 -0800, Eelco wrote: Context dependence is not something to be avoided at all costs, but all else being equal, less is certainly more. The general concept of grouping thing together which parenthesis is an extremely pervasive one in programming, and thus deserves its own set of context-dependent rules. Packing and unpacking collections is far, far more rare, Not in Python, where it is a very common idiom. and thus a form that requires you to write more but remember less is certainly relatively favorable. Not in Python, where iteration is a fundamental idiom and packing/ unpacking is a basic syntax construct precisely because the designer of the language expects it to be common and encourages its use. There are built-in functions designed to be used with unpacking operations, e.g. enumerate and zip: for i, obj in enumerate(sequence): ... for a, b in zip(obj, range(100)): ... -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sat, 24 Dec 2011 06:45:01 -0800, Eelco wrote: Can you give an example of a construct in python where two whitespace delimited identifiers are legal? Not apart from the trivial case of two identifiers separated by newlines. What's your point? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sat, 24 Dec 2011 06:39:39 -0800, Eelco wrote: On Dec 20, 4:30 am, alex23 wuwe...@gmail.com wrote: On Dec 19, 8:15 pm, Eelco hoogendoorn.ee...@gmail.com wrote: What does that have to do with collection packing/unpacking? It's mocking your insistance that collection unpacking is a type constraint. This is really going to be the last time I waste any words on this: If only that were true, but after sending this post, you immediately followed up with FIVE more posts on this subject in less than half an hour. The sentence 'collection unpacking is a type constraint' is entirely nonsensical. How true. Given that you have now acknowledged this fact, can you please stop insisting that collection unpacking is a type constraint? A type constraint is a linguistical construct that can be applied in many ways; typically, to narrow down the semantics of use of the symbol to which the type constraint is applied. Traceback (most recent call last): RuntimeError: maximum recursion depth exceeded In case of python, collection PACKING (not unpacking) is signaled by a construct that can be viewed as a type constraint. Only by doing sufficient violence to the concept of type constraint that it could mean *anything*. Earlier, I insisted that a constraint is a rule that applies to input, not output. I haven't seen anyone, including yourself, dispute that. Normally we would say that in the statement: y = list(x) there is a constraint on x, namely that it is some sort of iterable object (otherwise an exception will be raised), but it would be an abuse of language to say that there is a type constraint on y. y ends up being a list, true, but that isn't a constraint on y, it is an outcome. In normal usage, constraint refers to pre-conditions, not post- conditions. There are no pre-conditions on y in the above. It may not even exist. Contrast it with this example: y += list(x) where there are constraints on y: it must exist, and it must be a list, or something which can be added to a list. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sat, 24 Dec 2011 06:47:21 -0800, Eelco wrote: I would like to be able to write something like: a, middle::tuple, b = ::sequence Where I would like the extra :: before the sequence to explicitly signal collection unpacking on the rhs, to maintain the symmetry with collection unpacking within a function call. The :: on the right-hand side is redundant, because the left-hand side already explicitly signals collection unpacking of the RHS. Requiring :: on the RHS above is as unnecessary as it would be here: n = len(::sequence) -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 2:01 am, Rick Johnson rantingrickjohn...@gmail.com wrote: On Dec 24, 6:24 pm, alex23 wuwe...@gmail.com wrote: That you're a condescending douchebag with nothing of value to contribute? Crystal. Take it from me Eelco. Once Alex drops into your thread and starts name calling, it's over my friend. Yes, he has quite worn out my patience; whats over is our (attempts at) two sided communication, but I hope to continue the constructive lines of argument in this thread. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 1:45 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sat, 24 Dec 2011 06:54:07 -0800, Eelco wrote: Context dependence is not something to be avoided at all costs, but all else being equal, less is certainly more. The general concept of grouping thing together which parenthesis is an extremely pervasive one in programming, and thus deserves its own set of context-dependent rules. Packing and unpacking collections is far, far more rare, Not in Python, where it is a very common idiom. I know we are talking about python; it was me that put that in the title, after all. I know python makes more use of this than some languages (and less than others; I wouldnt suggest such a verbose syntax for a functional language for instance). Anyway, braces are used at least an order of magnitude more than collection packing/ unpacking in typical code. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 2011 2:55 PM, Eelco hoogendoorn.ee...@gmail.com wrote: On Dec 25, 2:01 am, Rick Johnson rantingrickjohn...@gmail.com wrote: On Dec 24, 6:24 pm, alex23 wuwe...@gmail.com wrote: That you're a condescending douchebag with nothing of value to contribute? Crystal. Take it from me Eelco. Once Alex drops into your thread and starts name calling, it's over my friend. Yes, he has quite worn out my patience; whats over is our (attempts at) two sided communication, but I hope to continue the constructive lines of argument in this thread. The real kiss of death is when you find yourself on the same side of the argument as ranting Rick. -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 2:12 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sat, 24 Dec 2011 06:39:39 -0800, Eelco wrote: On Dec 20, 4:30 am, alex23 wuwe...@gmail.com wrote: On Dec 19, 8:15 pm, Eelco hoogendoorn.ee...@gmail.com wrote: What does that have to do with collection packing/unpacking? It's mocking your insistance that collection unpacking is a type constraint. This is really going to be the last time I waste any words on this: If only that were true, but after sending this post, you immediately followed up with FIVE more posts on this subject in less than half an hour. Did I waste any more words on collection packing and type constraints? No, I did not. (though I am about to, and am willing to do so for every question that seems genuinely aimed at engaging me on the matter) Did I intend to say that I was going to let a single troll shut down my entire topic? No, I did not. In case of python, collection PACKING (not unpacking) is signaled by a construct that can be viewed as a type constraint. Only by doing sufficient violence to the concept of type constraint that it could mean *anything*. Earlier, I insisted that a constraint is a rule that applies to input, not output. I haven't seen anyone, including yourself, dispute that. Normally we would say that in the statement: y = list(x) there is a constraint on x, namely that it is some sort of iterable object (otherwise an exception will be raised), but it would be an abuse of language to say that there is a type constraint on y. y ends up being a list, true, but that isn't a constraint on y, it is an outcome. In normal usage, constraint refers to pre-conditions, not post- conditions. There are no pre-conditions on y in the above. It may not even exist. Contrast it with this example: y += list(x) where there are constraints on y: it must exist, and it must be a list, or something which can be added to a list. Yes, indeed it would be abuse of language to call this a type constraint, since the fact that y is a list is indeed an outcome of whatever happens to pop out at the right hand side. One could redefine the identifier list to return any kind of object. How is 'head, *tail = sequence' or semantically entirely equivalently, 'head, tail::list = sequence' any different then? Of course after interpretation/compilation, what it boils down to is that we are constructing a list and binding it to the identifier tail, but that is not how it is formulated in python as a language (all talk of types is meaningless after compilation; machine code is untyped). We dont have something of the form 'tail = list_tail(sequence)'. Rather, we annotate the identifier 'tail' with an attribute that unquestionably destinates it to become a list*. It is no longer that 'tail' will just take anything that pops out of the expression on the right hand side; rather, the semantics of what will go on at right hand side is coerced by the constraint placed on 'tail'. But again, if you dont wish to view this as a type constraint, I wont lose any sleep over that. In that case this line of argument was simply never directed at you. It was directed at people who would reasonably argue that 'tail::tuple is a type constraint and thats unpythonic / type constraints have been considered and rejected'. If you dont think it looks like a type constraint: fine. The simpler argument is that whatever it is, its just a more verbose and flexible variant of a construct that python already has. *(I call that a 'type constraint', because that is what it literally is; if you can make a case that this term has acquired a different meaning in practice, and that there is another term in common use for this kind of construct; please enlighten me. Until that time, im going to ask you to take 'type constraint' by its literal meaning; a coercion of the type of a symbol, rather than whatever particular meaning it has acquired for you (it might help if you explained that). Im not sure if it was you that brought that up, but let me reiterate that I dont mean a 'type cast', which is a runtime concept. A 'type constraint' is purely a linguistic construct that will be 'compiled out') -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 1:50 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sat, 24 Dec 2011 06:45:01 -0800, Eelco wrote: Can you give an example of a construct in python where two whitespace delimited identifiers are legal? Not apart from the trivial case of two identifiers separated by newlines. What's your point? My point is as I originally stated it: that this construct, of two identifiers seperated by non-newline whitespace, as in 'list tail' does not occur anywhere else in python, so introducing that syntax, while i suppose technically possible, would be a break with existing expectations. Normally speaking, if two identifiers interact, they are explicitly 'joined' by an infixed operator of some sort, as in 3*4, rather than * 3 4. That seems a sensible rule to me, and I see no compelling reason to depart from it. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 2:13 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sat, 24 Dec 2011 06:47:21 -0800, Eelco wrote: I would like to be able to write something like: a, middle::tuple, b = ::sequence Where I would like the extra :: before the sequence to explicitly signal collection unpacking on the rhs, to maintain the symmetry with collection unpacking within a function call. The :: on the right-hand side is redundant, because the left-hand side already explicitly signals collection unpacking of the RHS. Requiring :: on the RHS above is as unnecessary as it would be here: Yes, it is redundant; hence the word 'extra' in my post. Explicit and implicit are not well-defined terms, but I would say that at the moment the signal is implicit, in the sense that one cannot see what is going on by considering the rhs in isolation. Normally in python, an assignment just binds the rhs to the identifiers on the lhs, but in case of collection (un)packing, this rule that holds almost all of the time is broken, and the assignment statement implies a far more complicated construct, with a far more subtle meaning, and non-constant time complexity. Thats not a terrible thing, but a little extra explicitness there would not hurt, and like I argued many times before, it is a nice unification with the situation where the unpacking can not be implicit, like inside a function call rather than assignment. n = len(::sequence) Now you are just discrediting yourself in terms of having any idea what you are talking about. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sun, 25 Dec 2011 06:55:28 -0800, Eelco wrote: Anyway, braces are used at least an order of magnitude more than collection packing/ unpacking in typical code. That's a wild and unjustified claim. Here's a quick and dirty test, using the standard library as an example of typical idiomatic code: [steve@orac ~]$ cd /usr/lib/python2.6 [steve@orac python2.6]$ grep [*]args *.py | wc -l 270 [steve@orac python2.6]$ grep { *.py | wc -l 550 Doesn't look like a factor of 10 difference to me. And from one of my projects: [steve@orac src]$ grep [*]args *.py | wc -l 267 [steve@orac src]$ grep { *.py | wc -l 8 -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Mon, Dec 26, 2011 at 2:38 AM, Eelco hoogendoorn.ee...@gmail.com wrote: Until that time, im going to ask you to take 'type constraint' by its literal meaning; a coercion of the type of a symbol, rather than whatever particular meaning it has acquired for you (it might help if you explained that). Im not sure if it was you that brought that up, but let me reiterate that I dont mean a 'type cast', which is a runtime concept. A 'type constraint' is purely a linguistic construct that will be 'compiled out') The dictionary definition of constraint is a limitation or restriction, and you're right that it can be compiled out. In fact, that is probably the best definition. Assuming everything is written correctly, you should be able to eliminate all constraints and the code will still function correctly*; but having the constrains means that certain illegal operations will throw errors. Here's two examples of tuple unpacking, one with a type constraint, the other without: a, b = ('hello', [1,2,3] ) a, b::list = ('hello', [1,2,3] ) The constraint on the second line means that, if the second element is not a list, the interpreter should throw an error. It does NOT mean to completely change the meaning of the statement to _make_ the last argument into a list. That is not the job of a constraint. ChrisA * In databasing, it's not uncommon to have code depend on error responses for correct operation; for instance, one implementation of UPSERT is to attempt an INSERT, and if it fails due to a unique key constraint, do the UPDATE instead. The same is also done in Python - eg using an exception to terminate a loop - but in the context of this discussion, assume that errors indicate errors. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sun, 25 Dec 2011 07:38:17 -0800, Eelco wrote: On Dec 25, 2:12 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sat, 24 Dec 2011 06:39:39 -0800, Eelco wrote: On Dec 20, 4:30 am, alex23 wuwe...@gmail.com wrote: On Dec 19, 8:15 pm, Eelco hoogendoorn.ee...@gmail.com wrote: What does that have to do with collection packing/unpacking? It's mocking your insistance that collection unpacking is a type constraint. This is really going to be the last time I waste any words on this: If only that were true, but after sending this post, you immediately followed up with FIVE more posts on this subject in less than half an hour. Did I waste any more words on collection packing and type constraints? No, I did not. (though I am about to, and am willing to do so for every question that seems genuinely aimed at engaging me on the matter) Did I intend to say that I was going to let a single troll shut down my entire topic? No, I did not. Ah, well whatever you *intended* wasn't clear from your comment. At least not clear to *me*. [...] Yes, indeed it would be abuse of language to call this a type constraint, since the fact that y is a list is indeed an outcome of whatever happens to pop out at the right hand side. One could redefine the identifier list to return any kind of object. So far, we agree on this. How is 'head, *tail = sequence' or semantically entirely equivalently, 'head, tail::list = sequence' any different then? Of course after interpretation/compilation, what it boils down to is that we are constructing a list and binding it to the identifier tail, but that is not how it is formulated in python as a language I'm afraid it is. Here's the definition of assignment in Python 3: http://docs.python.org/py3k/reference/simple_stmts.html#assignment- statements (all talk of types is meaningless after compilation; machine code is untyped). What does machine code have to do with Python? We dont have something of the form 'tail = list_tail(sequence)'. I'm afraid we do. See the definition of assignment again. Rather, we annotate the identifier 'tail' with an attribute that unquestionably destinates it to become a list*. It is no longer that 'tail' will just take anything that pops out of the expression on the right hand side; Of course it will. Python is a dynamically typed language. It doesn't suddenly develop static types to ensure that 'tail' becomes a list; 'tail' is bound to a list because that's what the assignment statement provides. rather, the semantics of what will go on at right hand side is coerced by the constraint placed on 'tail'. But it isn't a constraint placed on 'tail'. It is a consequence of the definition of assignment in Python 3. 'tail' becomes bound to a list because that is what the assignment statement is defined to do in that circumstance, not because the identifier (symbol) 'tail' is constrained to only accept lists. 'tail' may not even exist before hand, so talking about constraints on 'tail' is an abuse of language, AS YOU AGREED ABOVE. [...] *(I call that a 'type constraint', because that is what it literally is; No. It is literally a name binding of a dynamically typed, unconstrained name to an object which happens to be a list. if you can make a case that this term has acquired a different meaning in practice, and that there is another term in common use for this kind of construct; please enlighten me. Until that time, im going to ask you to take 'type constraint' by its literal meaning; a coercion of the type of a symbol, But THERE IS NO COERCION OF THE TYPE OF THE SYMBOL. I am sorry for shouting, but you seem oblivious to the simple fact that Python is not statically typed, and the symbol 'tail' is NOT coerced to a specific type. 'tail' may not even exist before the assignment is made; if it does exist, it could be *any type at all* -- and after the assignment takes place, there are no restrictions on subsequent assignments. 'head, *tail = sequence' is no more a type constraint than 'x = 1' is. Whatever the virtues of your proposal, you are doing it incalculable harm by your insistence on this incorrect model of Python's behaviour. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 20, 4:30 am, alex23 wuwe...@gmail.com wrote: On Dec 19, 8:15 pm, Eelco hoogendoorn.ee...@gmail.com wrote: What does that have to do with collection packing/unpacking? It's mocking your insistance that collection unpacking is a type constraint. This is really going to be the last time I waste any words on this: The sentence 'collection unpacking is a type constraint' is entirely nonsensical. A type constraint is a linguistical construct that can be applied in many ways; typically, to narrow down the semantics of use of the symbol to which the type constraint is applied. In case of python, collection PACKING (not unpacking) is signaled by a construct that can be viewed as a type constraint. But if you dont want to fortify your view of the syntax by looking at what it is actually going on, ill repeat again; lets keep things simple, and not analyze it in detail. So here it is again, in terms every 5 year old can understand. Id like to do the exact same thing python is already doing. Except with a few more, and different symbols, to enable one to express a few different variants of behavior. Clear enough? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 21, 4:48 pm, Neal Becker ndbeck...@gmail.com wrote: Clarification: where can packing/unpacking syntax be used? It would be great if it were valid essentially anywhere (not limited to parameter passing). What about constructs like: a, @tuple tail, b = sequence? This has come up many times in the thread, including in my OP. More closely unifying collection packing/unpacking is part of my goal, so indeed, I would like to be able to write something like: a, middle::tuple, b = ::sequence Where I would like the extra :: before the sequence to explicitly signal collection unpacking on the rhs, to maintain the symmetry with collection unpacking within a function call. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 20, 4:35 am, alex23 wuwe...@gmail.com wrote: Eelco hoogendoorn.ee...@gmail.com wrote: Having two seperate symbols seperated by whitespace, as in @list args strikes me as a terrible break of normal python lexical rules. You mean like 'is not'? And the upcoming 'yield from'? Im not sure why, but this feels like something entirely different to me. I suppose because these are compositions of keywords. Can you give an example of a whitespaced composition of identifiers being a valid construct anywhere else in Python? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 20, 6:47 am, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Mon, 19 Dec 2011 19:35:20 -0800, alex23 wrote: Eelco hoogendoorn.ee...@gmail.com wrote: Having two seperate symbols seperated by whitespace, as in @list args strikes me as a terrible break of normal python lexical rules. You mean like 'is not'? And the upcoming 'yield from'? Also not in. Space-delimited tokens are hardly rare in Python, e.g.: import module as name for x in sequence if flag elif condition while condition with obj del name Nevertheless, I think the suggested syntax @list args is awful. -- Steven Can you give an example of a construct in python where two whitespace delimited identifiers are legal? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 22, 2:12 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Thu, 22 Dec 2011 06:49:16 -0500, Neal Becker wrote: I agree with the OP that the current syntax is confusing. The issue is, the meaning of * is context-dependent. Here you are complaining about an operator being confusing because it is context-dependent, in a post where you strip all context except the subject line and expect us to still understand what you're talking about. There's a lesson there, I'm sure. * is context dependent. You know what else is context dependent? Well, most things. But in particular, parentheses. Clearly they must be confusing too. So how about we say: class MyClass superclasslist A, B C: def method argumentlist self, x, y: t = tuple 1, 2 tuple 3, 4 endtuple endtuple return group x + y endgroup * group x - y endgroup Much less confusing! -- Steven Context dependence is not something to be avoided at all costs, but all else being equal, less is certainly more. The general concept of grouping thing together which parenthesis is an extremely pervasive one in programming, and thus deserves its own set of context-dependent rules. Packing and unpacking collections is far, far more rare, and thus a form that requires you to write more but remember less is certainly relatively favorable. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sun, Dec 25, 2011 at 1:47 AM, Eelco hoogendoorn.ee...@gmail.com wrote: a, middle::tuple, b = ::sequence Then it ought to be ::(a, middle::tuple, b) = ::sequence or something, because you're doing the same thing on both sides. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sun, Dec 25, 2011 at 1:45 AM, Eelco hoogendoorn.ee...@gmail.com wrote: Can you give an example of a construct in python where two whitespace delimited identifiers are legal? What do you mean? Two identifiers, separated only by whitespace and no keyword or operator? def foo(): asdf qwer Perfectly legal, two statements that probably don't do anything useful though. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 24, 3:57 pm, Chris Angelico ros...@gmail.com wrote: On Sun, Dec 25, 2011 at 1:47 AM, Eelco hoogendoorn.ee...@gmail.com wrote: a, middle::tuple, b = ::sequence Then it ought to be ::(a, middle::tuple, b) = ::sequence or something, because you're doing the same thing on both sides. ChrisA Thats a fair point; something to think about. It all depends on how you define the rules of course; im trying to stay as close as possible to the original python rules, where the (un)packing of comma-seperated identifiers is implicit. Probably best to keep it that way, from the looks of it :). -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 24, 4:01 pm, Chris Angelico ros...@gmail.com wrote: On Sun, Dec 25, 2011 at 1:45 AM, Eelco hoogendoorn.ee...@gmail.com wrote: Can you give an example of a construct in python where two whitespace delimited identifiers are legal? What do you mean? Two identifiers, separated only by whitespace and no keyword or operator? def foo(): asdf qwer Perfectly legal, two statements that probably don't do anything useful though. ChrisA Thats not a fair point, but more nitpicking. Yes, I should have been more precise: in python, 'whitespace' is not a single beast like in most languages, but newlines have a special meaning. I was obviously not talking about those. Want to try again? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sun, Dec 25, 2011 at 4:23 AM, Eelco hoogendoorn.ee...@gmail.com wrote: Thats not a fair point, but more nitpicking. Yes, I should have been more precise: in python, 'whitespace' is not a single beast like in most languages, but newlines have a special meaning. I was obviously not talking about those. Want to try again? In that case I can't think of any, but at least now you've clarified the question (by not denying the rest of it). It was somewhat ambiguous. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 25, 12:39 am, Eelco hoogendoorn.ee...@gmail.com wrote: This is really going to be the last time I waste any words on this Oh hey, don't feel you actually have to justify the bullshit you're talking for my sake. In case of python, collection PACKING (not unpacking) is signaled by a construct that can be viewed as a type constraint. _But no one does view it that way because it isn't_. No more so than [] taking a string separated list of arguments and return a list is a type constraint. _That's it's behaviour_. We have a language construct that returns a tuple, because in the context of what tuples are in Python, that makes sense. There are _plenty_ of such constructs. You have still yet to show what adding all of this ridiculous shit to a function signature provides that coercing the resulting tuple to your own type doesn't. So here it is again, in terms every 5 year old can understand. Id like to do the exact same thing python is already doing. Except with a few more, and different symbols, to enable one to express a few different variants of behavior. Clear enough? That you're a condescending douchebag with nothing of value to contribute? Crystal. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 24, 6:24 pm, alex23 wuwe...@gmail.com wrote: That you're a condescending douchebag with nothing of value to contribute? Crystal. Take it from me Eelco. Once Alex drops into your thread and starts name calling, it's over my friend. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
I agree with the OP that the current syntax is confusing. The issue is, the meaning of * is context-dependent. Why not this: Func (*args) == Func (unpack (args)) def Func (*args) == Func (pack (args)) That seems very clear IMO -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Thu, 22 Dec 2011 06:49:16 -0500, Neal Becker wrote: I agree with the OP that the current syntax is confusing. The issue is, the meaning of * is context-dependent. Here you are complaining about an operator being confusing because it is context-dependent, in a post where you strip all context except the subject line and expect us to still understand what you're talking about. There's a lesson there, I'm sure. * is context dependent. You know what else is context dependent? Well, most things. But in particular, parentheses. Clearly they must be confusing too. So how about we say: class MyClass superclasslist A, B C: def method argumentlist self, x, y: t = tuple 1, 2 tuple 3, 4 endtuple endtuple return group x + y endgroup * group x - y endgroup Much less confusing! -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Fri, Dec 23, 2011 at 12:12 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: class MyClass superclasslist A, B C: def method argumentlist self, x, y: t = tuple 1, 2 tuple 3, 4 endtuple endtuple return group x + y endgroup * group x - y endgroup Much less confusing! A definite improvement. However, I fear that the numerals 1, 2, etc are far too vague. In some contexts, the abuttal of two such numerals results in a larger number by a factor of 10, while in others, the factor is 8, or 16, or 2. This must not be. We need an unambiguous representation of integers. Also, I think we should adopt an existing standard [1]. This is generally a good idea. class MyClass superclasslist A, B C: def method argumentlist self, x, y: t = tuple summer's day, proud pony tuple sum of honest purse and fellow, large proud town endtuple endtuple return product of group sum of x and y endgroup and group difference between x and y endgroup You will find this a vast improvement. ChrisA [1] http://shakespearelang.sourceforge.net/report/shakespeare/shakespeare.html#SECTION00045000 or http://tinyurl.com/6sycv -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 22/12/11 14:12:57, Steven D'Aprano wrote: On Thu, 22 Dec 2011 06:49:16 -0500, Neal Becker wrote: I agree with the OP that the current syntax is confusing. The issue is, the meaning of * is context-dependent. Here you are complaining about an operator being confusing because it is context-dependent, in a post where you strip all context except the subject line and expect us to still understand what you're talking about. There's a lesson there, I'm sure. * is context dependent. You know what else is context dependent? Well, most things. But in particular, parentheses. Clearly they must be confusing too. So how about we say: class MyClass superclasslist A, B C: def method argumentlist self, x, y: t = tuple 1, 2 tuple 3, 4 endtuple endtuple return group x + y endgroup * group x - y endgroup Much less confusing! How about: class name=MyClass superclasses=A, B, C def name=method arguments=self, x, y let target=t tuple te1/te te2/te tetuplete3/tete4/te/tuple/te /tuple /let return multiply addvarx/varvarx/var/add subtractvarx/varvarx/var/subtract /multiply /return /def /class More more readable! And it's a standard! :-) -- HansM -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Fri, Dec 23, 2011 at 1:13 AM, Hans Mulder han...@xs4all.nl wrote: How about: class name=MyClass superclasses=A, B, C ... /class More more readable! And it's a standard! Unfortunately it's not Pythonic, because indentation is insignificant. We need to adopt a more appropriate form. Eliminate all the /spam tags and use indentation to mark the ends of elements. ChrisA PS. Brilliant, sir, brilliant! I take off my cap to you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
Chris Angelico wrote: On Fri, Dec 23, 2011 at 1:13 AM, Hans Mulder han...@xs4all.nl wrote: How about: class name=MyClass superclasses=A, B, C ... /class More more readable! And it's a standard! Unfortunately it's not Pythonic, because indentation is insignificant. Easy-peasy: def name=method arguments=self, x, y indent/indentlet target=t Mel. We need to adopt a more appropriate form. Eliminate all the /spam tags and use indentation to mark the ends of elements. ChrisA PS. Brilliant, sir, brilliant! I take off my cap to you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
Clarification: where can packing/unpacking syntax be used? It would be great if it were valid essentially anywhere (not limited to parameter passing). What about constructs like: a, @tuple tail, b = sequence? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
Neal Becker wrote: Clarification: where can packing/unpacking syntax be used? It would be great if it were valid essentially anywhere (not limited to parameter passing). What about constructs like: a, @tuple tail, b = sequence? You mean like Python 3's: a, *middle, b = sequence ? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 21 December 2011 15:48, Neal Becker ndbeck...@gmail.com wrote: Clarification: where can packing/unpacking syntax be used? It would be great if it were valid essentially anywhere (not limited to parameter passing). What about constructs like: a, @tuple tail, b = sequence? a, *b, c = range(10) a, b, c (0, [1, 2, 3, 4, 5, 6, 7, 8], 9) It's just a proposed syntax change, effectively, so yes. However, http://bugs.python.org/issue2292 covers the ones we don't have (that we should :P). This discussion doesn't cover that. -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
20.12.11 07:47, Steven D'Aprano написав(ла): Space-delimited tokens are hardly rare in Python, e.g.: import module as name for x in sequence if flag elif condition while condition with obj del name return to_be or not to_be if this is question else None -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Mon, 19 Dec 2011 19:38:52 -0800, alex23 wrote: On Dec 20, 7:57 am, Andrew Berg bahamutzero8...@gmail.com wrote: But what about the example he gave about being logged into a customer's machine with only ed available? I suppose such fools would not be worthy of your business. Do you mean directly editing the source code on a production machine? Because that's pretty much the only scenario I can come up with where that's plausible. If I was doing that, _I_ wouldn't be worth doing business with. So you only have ssh ed: at the very least you should be making changes against your local copy, TESTING THEM, and then copypaste directly onto the remote box. Come on guys, you're treating a throw-away example *way* too seriously. If we're going to hypothesis a customer so insane to only have ed installed on their system[1], chances are they've specified some crazy rule like You May Not Copy Our Precious, Precious Source Code Onto Another Machine Because That's Copyright Theft. Or whatever. Spend 15 minutes on The Daily WTF and you'll see war stories far more crazy than that. The point I was making is that in the real world, sometimes you don't have the luxury of using the right tool for the job, but have to make do with whatever you have. Languages shouldn't depend on advanced editor features or special keyboards -- that way leads to ColorForth and APL. [1] Possibly because ed is the standard Unix editor. http://www.gnu.org/fun/jokes/ed.msg.html -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 20 December 2011 20:51, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Languages shouldn't depend on advanced editor features or special keyboards -- that way leads to ColorForth and APL. True, but dependency on a tool is not the same as being crafted to work best on the tool that 99.9% of programmers use. It's not like it's an ide-*only *feature we were discussing. It's just an observation that this feature* works well with syntax highlighting. *That's a good thing.* * * *What feature are we discussing anyway? I can't remember... Oh! It's actually that vargs will be a highlighted keyword! Well, someone using ed will obviously have to stop using python on the basis that vargs isn't highlighted, then, which makes it a bad idea. *No*, what makes it a bad idea is the concept itself. As I've said, the 1/10,000 using ed have bigger problems. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 19, 3:23 am, alex23 wuwe...@gmail.com wrote: Evan Driscoll edrisc...@wisc.edu wrote: My problem with it is that it in some sense is forcing me to make a decision I don't care about. Yes, what we have now is less flexible, but I have *never* said man, I wish this *args parameter were a list instead of a tuple. And if you _did_, then one of the first lines in your function would be: args = list(args) Which is obvious to everyone, doesn't modify existing behaviour, doesn't force everyone without a fetish for change to add unnecessary cruft to their function signature... Its obvious you end up with a list (assuming args is an iterable); knowing what args was to begin with suffers from the same problems. Except, OMG, list() is RETURNING A LIST, which is an OBVIOUS type constraint. I propose that: args = @set list(args) Will coerce args into a list and then give me a set in return. ? What does that have to do with collection packing/unpacking? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 19, 1:59 am, Rick Johnson rantingrickjohn...@gmail.com wrote: On Dec 17, 11:33 pm, Evan Driscoll edrisc...@wisc.edu wrote: On 12/17/2011 22:52, buck wrote: Try these on for size. head, @tuple tail = sequence def foo(@list args, @dict kwargs): pass foo(@args, @kwargs) For backward compatibility, we could say that the unary * is identical to @list and unary ** is identical to @dict. I like this idea much more than the original one. +1. I will second that! Eelco has the CORRECT idea, but the WRONG syntax! Thanks, your opinion is noted. Personally im impartial between identifier::collectiontype and identifier@collectiontype, but that order is something I think is rather important. Having two seperate symbols seperated by whitespace, as in @list args strikes me as a terrible break of normal python lexical rules. Plus, identifier@collectiontype as a collection-type annotation would be consistent with the existing general function annotation syntax. Many non-C-family languages postfix the type declaration. Also, we want to use the same symbol for collection unpacking as we use for collection packing. Saying foo(@argslist) really does look a tad much like a decorator, even though it can be unambigiously distinguished from it by context. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
Evan Driscoll edrisc...@wisc.edu wrote: I'm not an expert on Google's syntax, but if you search for python, optionally with function, isn't that the same as just searching for python since it will return hits either with or without function? Chris Angelico's interpretation is correct: I did four searches, python function star, python function asterisk, python star, and python asterisk. Using www.google.com: python function star: first hit is: http://farmdev.com/thoughts/24/what- does-the-def-star-variable-or-def-asterisk-parameter-syntax-do-in-python-/ python function asterisk: first hit is: http://www.technovelty.org/code/python/asterisk.html python asterisk: the first hit I get is http://www.technovelty.org/code/python/asterisk.html python star is the only useless one of those giving me two hits for star pathfinding algorithms, one about the BNF used in Python's documentation, and a Daily Mail article about John Cleese and Eric Idle. -- Duncan Booth http://kupuguy.blogspot.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 12/18/2011 8:16 PM, Rick Johnson wrote: On Dec 18, 7:26 pm, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: Not everybody uses editors more advanced than Notepad. And they have no excuse for NOT using a better one. Well, except for a foolish consistency that is! But what about the example he gave about being logged into a customer's machine with only ed available? I suppose such fools would not be worthy of your business. -- CPython 3.2.2 | Windows NT 6.1.7601.17640 | Thunderbird 7.0 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
In article mailman.3827.1324331890.27778.python-l...@python.org, Andrew Berg bahamutzero8...@gmail.com wrote: But what about the example he gave about being logged into a customer's machine with only ed available? I suppose such fools would not be worthy of your business. The customer is always right. Especially when the support contract is big enough to make or break your quarter. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 20 December 2011 00:30, Roy Smith r...@panix.com wrote: In article mailman.3827.1324331890.27778.python-l...@python.org, Andrew Berg bahamutzero8...@gmail.com wrote: But what about the example he gave about being logged into a customer's machine with only ed available? I suppose such fools would not be worthy of your business. The customer is always right. Especially when the support contract is big enough to make or break your quarter. -- http://mail.python.org/mailman/listinfo/python-list This whole conversation is ridiculous. Do we really want a syntax that's worse just to satisfy the 1/10,000 cases* where someone will be using ed or notepad? Correct Answer: no. * Probably less, as I use vim many_times_a_day * many_days_a_year - and even less if we consider that no-one'll be doing as much coding in an hour of ed as in an hour of better_editor -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
Sorry, I wasn't meaning to imply support for the syntax proposal. Just reacting to the (seemingly unrelated) comment that a customer with foolish access policies would not be worthy of your business. Only because I've been in the situation of having to provide remote support to major customers with similar absurd policies :-) On Dec 19, 2011, at 8:10 PM, Joshua Landau wrote: On 20 December 2011 00:30, Roy Smith r...@panix.com wrote: In article mailman.3827.1324331890.27778.python-l...@python.org, Andrew Berg bahamutzero8...@gmail.com wrote: But what about the example he gave about being logged into a customer's machine with only ed available? I suppose such fools would not be worthy of your business. The customer is always right. Especially when the support contract is big enough to make or break your quarter. -- http://mail.python.org/mailman/listinfo/python-list This whole conversation is ridiculous. Do we really want a syntax that's worse just to satisfy the 1/10,000 cases* where someone will be using ed or notepad? Correct Answer: no. * Probably less, as I use vim many_times_a_day * many_days_a_year - and even less if we consider that no-one'll be doing as much coding in an hour of ed as in an hour of better_editor -- Roy Smith r...@panix.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 20 December 2011 01:18, Roy Smith r...@panix.com wrote: Sorry, I wasn't meaning to imply support for the syntax proposal. Just reacting to the (seemingly unrelated) comment that a customer with foolish access policies would not be worthy of your business. Only because I've been in the situation of having to provide remote support to major customers with similar absurd policies :-) Nononono! I wasn't referring to you! I was referring to the whole topic. You just happened to be that last person to say something. Sorry about that, I should have been clearer... On Dec 19, 2011, at 8:10 PM, Joshua Landau wrote: On 20 December 2011 00:30, Roy Smith r...@panix.com wrote: In article mailman.3827.1324331890.27778.python-l...@python.org, Andrew Berg bahamutzero8...@gmail.com wrote: But what about the example he gave about being logged into a customer's machine with only ed available? I suppose such fools would not be worthy of your business. The customer is always right. Especially when the support contract is big enough to make or break your quarter. -- http://mail.python.org/mailman/listinfo/python-list This whole conversation is ridiculous. Do we really want a syntax that's worse just to satisfy the 1/10,000 cases* where someone will be using ed or notepad? Correct Answer: no. * Probably less, as I use vim many_times_a_day * many_days_a_year - and even less if we consider that no-one'll be doing as much coding in an hour of ed as in an hour of better_editor -- Roy Smith r...@panix.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 12/19/2011 7:18 PM, Roy Smith wrote: Sorry, I wasn't meaning to imply support for the syntax proposal. Just reacting to the (seemingly unrelated) comment that a customer with foolish access policies would not be worthy of your business. It was directed at Rick, and by your, I was referring to him specifically, as that is the kind of attitude I might expect him to show. -- CPython 3.2.2 | Windows NT 6.1.7601.17640 | Thunderbird 7.0 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 19, 8:15 pm, Eelco hoogendoorn.ee...@gmail.com wrote: What does that have to do with collection packing/unpacking? It's mocking your insistance that collection unpacking is a type constraint. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
Eelco hoogendoorn.ee...@gmail.com wrote: Having two seperate symbols seperated by whitespace, as in @list args strikes me as a terrible break of normal python lexical rules. You mean like 'is not'? And the upcoming 'yield from'? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 20, 7:57 am, Andrew Berg bahamutzero8...@gmail.com wrote: But what about the example he gave about being logged into a customer's machine with only ed available? I suppose such fools would not be worthy of your business. Do you mean directly editing the source code on a production machine? Because that's pretty much the only scenario I can come up with where that's plausible. If I was doing that, _I_ wouldn't be worth doing business with. So you only have ssh ed: at the very least you should be making changes against your local copy, TESTING THEM, and then copypaste directly onto the remote box. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 19, 2:35 pm, Chris Angelico ros...@gmail.com wrote: Point to note: list,set = set,list # Request a death sentence from the next maintainer is perfectly legal code. Now, what does your args= line do? ChrisA Why are you directing this at my mocking of the OPs idea when the same issue is present in his proposal? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 12/19/2011 9:38 PM, alex23 wrote: Do you mean directly editing the source code on a production machine? Because that's pretty much the only scenario I can come up with where that's plausible. You'd have to ask Steven D'Aprano; it was his scenario. -- CPython 3.2.2 | Windows NT 6.1.7601.17640 | Thunderbird 7.0 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Tue, Dec 20, 2011 at 2:31 PM, alex23 wuwe...@gmail.com wrote: On Dec 19, 2:35 pm, Chris Angelico ros...@gmail.com wrote: Point to note: list,set = set,list # Request a death sentence from the next maintainer is perfectly legal code. Now, what does your args= line do? ChrisA Why are you directing this at my mocking of the OPs idea when the same issue is present in his proposal? Because it was after reading your post that I saw reason to write that, and it tied in better with your post than any other. No other reason. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Mon, 19 Dec 2011 19:35:20 -0800, alex23 wrote: Eelco hoogendoorn.ee...@gmail.com wrote: Having two seperate symbols seperated by whitespace, as in @list args strikes me as a terrible break of normal python lexical rules. You mean like 'is not'? And the upcoming 'yield from'? Also not in. Space-delimited tokens are hardly rare in Python, e.g.: import module as name for x in sequence if flag elif condition while condition with obj del name Nevertheless, I think the suggested syntax @list args is awful. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Nevertheless, I think the suggested syntax @list args is awful. Yep, and it's the least awful part of the entire proposal. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sat, 17 Dec 2011 23:33:27 -0600, Evan Driscoll wrote: This would suggest perhaps some keywords might be called for instead of operators. The barrier to new keywords in Python is very high. Not going to happen for something that already has perfectly good syntax already familiar to Python and Ruby programmers. Might else well try to get C and Java to stop using ... (ellipses). In the grand scheme of things the argument packing and unpacking are not *all* that common, so I don't think the syntactic burden would be immense. The burden is that you complicate the compiler and reduce the pool of useful names available to the programmer. To be useful, the keywords need to be short, meaningful and memorable -- which means they're already used in code, which you will break needlessly. With operators that otherwise would be illegal, the programmer doesn't need to learn about varargs until they need to. With keywords, the programmer needs to learn you can't use varargs or kwargs as variable names practically from day 1. But then you could also say def foo(varargs(list) l, kwargs(dict) d) So you're not just adding keywords, you're adding new syntax: something which looks like a function call, but isn't a function call. Another feature which the programmer has to learn just to be able to read Python source code -- and one which almost certainly is going to clash with function annotations as people start using them. I'm going to pose the same question to you I have already posed to Eelco: in your proposal, what happens if the caller has shadowed the list built- in? Does argument l become a built-in list, or does it become whatever type list is currently bound to? Some more questions: Can varargs accepted arbitrary callables, or only a fixed set of known types? How does this differ from what can be done with annotations? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sun, Dec 18, 2011 at 6:31 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: My normal first place to look for something is Wikipedia. Enjoy it before SOPA kills it. http://en.wikipedia.org/wiki/Asterisk#Programming_languages I would never expect to find this sort of thing in the article on the asterisk; maybe I'd look on the language's article, but more likely I would be looking for info on the language's own web site. On Sat, 17 Dec 2011 23:33:27 -0600, Evan Driscoll wrote: In the first pages of the four searches matching python (function)? (star | asterisk), Your search looks overly complicated to me. I understand this to mean that he did four searches: * python star * python function star * python asterisk * python function asterisk Never underestimate the power of Python's introspection tools, especially the two simplest ones: print and type. Often you will learn more in 10 minutes experimentation than in an hour googling. +1 QOTW. I refer to this as IIDPIO debugging (Eyed Pio) - If In Doubt, Print It Out. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sat, 17 Dec 2011 21:03:01 -0600, Evan Driscoll wrote: Something like ML or Haskell, which does not even allow integer to double promotions, is very strong typing. Something like Java, which allows some arithmetic conversion and also automatic stringification (a la 1 + 1) is somewhere in the middle of the spectrum. Personally I'd put Python even weaker on account of things such as '[1,2]*2' and '1 True' being allowed, They are not examples of weak typing. The first is an example of operator overloading, the second is a side-effect of a compromise made for backwards compatibility. If the first example were written: [1, 2].repeat(2) I expect you'd be perfectly happy with it as an unexceptional example of a list method: it takes an integer count, and returns a new list consisting of the elements of the original list repeated twice. If it were written: [1, 2].__mul__(2) you'd probably raise an eyebrow at the ugliness of the method name, but you would be okay with the concept. Well, that's exactly what it is in Python: the list __mul__ method performs sequence multiplication (repeating the contents), which overloads the * operator. No automatic type conversions needed, so not an example of weak typing. As for comparisons between ints and True or False, that's not weak typing either, because True and False *are* ints: bool is a subclass of int. This was done purely for historical reasons: originally Python didn't have a bool type, and you used 0 and 1 by convention for boolean values. When it was decided to add a bool type, the least disruptive way to do this was to define it as a subclass of int. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
In article mailman.3787.1324197792.27778.python-l...@python.org, Chris Angelico ros...@gmail.com wrote: Never underestimate the power of Python's introspection tools, especially the two simplest ones: print and type. Often you will learn more in 10 minutes experimentation than in an hour googling. +1 QOTW. I refer to this as IIDPIO debugging (Eyed Pio) - If In Doubt, Print It Out. I always knew it by the name Ask the computer. As in, WTF is foo? Let's ask the computer!. In addition to print and type, I'm a big fan of dir(). Often, I know an object has a method to do what I want, but I can't remember the name. For example, the other day, I was using a set (which I don't use very often). I needed the method to remove an item from the set. Faster than finding the right place in the docs, I just fired up an interpreter and typed dir(set()) at it. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Mon, Dec 19, 2011 at 12:58 AM, Roy Smith r...@panix.com wrote: In addition to print and type, I'm a big fan of dir(). Often, I know an object has a method to do what I want, but I can't remember the name. For example, the other day, I was using a set (which I don't use very often). I needed the method to remove an item from the set. Faster than finding the right place in the docs, I just fired up an interpreter and typed dir(set()) at it. That's excellent when all you need is the name. I usually have IDLE running (all the time - which sometimes produces oddities after I experiment with monkey-patching some module or other, and then oddly enough, things don't work properly!!), and will snap off help(foo) for any foo. Unfortunately help() is at times unhelpful, and even at its best it's very spammy. There's no one best solution; the successful programmer will usually have a large toolset at his disposal. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 18, 1:59 am, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sat, 17 Dec 2011 06:38:22 -0800, Eelco wrote: Type constraints: In case the asterisk is not used to signal unpacking, but rather to signal packing, its semantics is essentially that of a type constraint. Type constraint normally refers to type restrictions on *input*: it is a restriction on what types are accepted. When it refers to output, it is not normally a restriction, therefore constraint is inappropriate. Instead it is normally described as a coercion, cast or conversion. Automatic type conversions are the opposite of a constraint: it is a loosening of restrictions. I don't have to use a list, I can use any sequence or iterator. Casts or conversions are a runtime concept; im talking about declarations. That seems to be the source of your confusion. In iterator unpacking, it is the *output* which is a list, not a restriction on input: in the statement: head, *tail = sequence tail may not exist before the assignment, and so describing this as a constraint on the type of tail is completely inappropriate. Yes, the variable tail is being (re)declared here. Thats exactly why I call it a type constraint. Im not sure what the CS books have to say on the matter, I guess this use of the term entered my lexicon through the C# developer team. Either way, you seem to be the only one who does not grok my intended meaning, so I suggest you try reading it again. The statement: head, tail = sequence Signifies regular unpacking. However, if we add an asterisk, as in: head, *tail = sequence We demand that tail not be just any python object, but rather a list. We don't demand anything, any more than when we say: for x in range(1, 100): we demand that x is not just any python object, but rather an int. Rather, we accept what we're given: in case of range and the for loop, we are given an int. In the case of extended tuple unpacking, we are given a list. for x in range is syntactic sugar for a series of assignments to x; x is an unconstrained variable that will indeed take anything it gets; the semantics of what comes after 'x' does in no way depend on x itself. head, tail = l and head, *tail = l mean something completely different, and the only difference is a constraint placed on tail, which forces the semantics to be different; the righthand side, or what is to be assigned, is identical. Of course one can just regard it as syntactic sugar for head, tail = unpackheadandtailaslist(l); but the syntactic sugar achieves that same end through a type constraint on tail. Really. You are jumping to conclusions about implementation details which aren't supported by the visible behaviour. What evidence do you have that iterator unpacking creates a tuple first and then converts it to a list? You are jumping to conclusions about my opinion which aren't supported by my visible behaviour. What evidence do you have that I ever even said any such thing? The aim of this PEP, is that this type-constraint syntax is expanded upon. We should be careful here to distinguish with providing optional type constraints throughout python as a whole; this is not our aim. Iterator unpacking is no more about type constraints than is len(). Because you wish to keep nitpicking about my usage of the term 'type constraint' (even though you have not introduced an alternative term yourself), or because you actually disagree with the content of my message? -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 18, 5:52 am, buck workithar...@gmail.com wrote: I like the spirit of this. Let's look at your examples. Glad to see an actual on-topic reply; thanks. Examples of use: head, tail::tuple = ::sequence def foo(args::list, kwargs::dict): pass foo(::args, ::kwargs) My initial reaction was nonono!, but this is simply because of the ugliness. The double-colon is very visually busy. I would have preferred the single colon, but its taken. But exactly this syntax is used in other languages (for what that is worth...) I find that your second example is inconsistent with the others. If we say that the variable-name is always on the right-hand-side, we get: def foo(list::args, dict::kwargs): pass This nicely mirrors other languages (such as in your C# example: float foo) as well as the old python behavior (prefixing variables with */** to modify the assignment). The link in my OP has the BDFL discussing type constraints; he also prefers identifier:type. Many modern languages have something similar. How is my second example inconsistent? As for the separator, let's examine the available ascii punctuation. Excluding valid variable characters, whitespace, and operators, we have: ! -- ok. -- can't use this. Would look like a string. # -- no. Would looks like a comment. $ -- ok. ' -- no. Would look like a string. ( -- no. Would look like a function. ) -- no. Would look like ... bad syntax. , -- no. Would indicate a separate item in the variable list. . -- no. Would look like an attribute. : -- ok, maybe. Seems confusing in a colon-terminated statement. ; -- no, just no. ? -- ok. @ -- ok. [ -- no. Would look like indexing. ] -- no. ` -- no. Would look like a string? { -- too strange} -- too strange ~ -- ok. That leaves these. Which one looks least strange? float ! x = 1 float $ x = 1 float ? x = 1 float @ x = 1 The last one looks decorator-ish, but maybe that's proper. The implementation of this would be quite decorator-like: take the normal value of x, pass it through the indicated function, assign that value back to x. I dont think thats too proper an analogy. The type constraint does not just coerce the content that is bound to the variable, it influences the semantics of the whole statement; so insofar there is a suggested relation with decorators, id rather not have it. Try these on for size. head, @tuple tail = sequence def foo(@list args, @dict kwargs): pass foo(@args, @kwargs) For backward compatibility, we could say that the unary * is identical to @list and unary ** is identical to @dict. Yes, maximum backwards compatibility would be great. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 18, 6:33 am, Evan Driscoll edrisc...@wisc.edu wrote: On 12/17/2011 22:52, buck wrote: Try these on for size. head, @tuple tail = sequence def foo(@list args, @dict kwargs): pass foo(@args, @kwargs) For backward compatibility, we could say that the unary * is identical to @list and unary ** is identical to @dict. I like this idea much more than the original one. In addition to the arguments buck puts forth, which I find compelling, I have one more: you go to great length to say this isn't really type checking in any sense (which is true)... but then you go forth and pick a syntax that looks almost exactly like how you name types in many languages! (In fact, except for the fact that it's inline, the 'object :: type' syntax is *exactly* how you name types in Haskell.) No, its not type *checking*, its type *declaration*. I tried to go to great lengths to point that out, but it appears I did not do a very good job :). Type declaration is exactly what I want, and insofar this syntax has already found adoptation elsewhere, ill consider that a plus. I have a bigger objection with the general idea, however.It seems very strange that you should have to specify types to use it. If the */** syntax were removed, that would make the proposed syntax very very unusual for Python. I could be missing something, but I can think of any other place where you have to name a type except where the type is an integral part of what you're trying to do. (I would not say that choosing between tuples and lists are an integral part of dealing with vararg functions.) If */** were to stick around, I could see 99% of users continuing to use them. And then what has the new syntax achieved? Good point; technically the askeriskes could be kept for backwards compatibility, but that would break 'there should only be one way to do it'. Indeed it would be unusual for python to have to explicitly name a type, but implicitly ** does very much the same. Its just a cryptic way of saying 'dict please'. You can fix this if you don't require the types and just allow the user to say def foo(@args) and foo(@args). Except... that's starting to look pretty familiar... (Not to mention if you just omit the type from the examples above you need another way to distinguish between args and kwargs.) Yes, one could opt for a syntax where the collection type is optional and a sensible default is chosen, But to me that would largely defeat the point; I very much like the added verbosity and explicitness. args- tuple and kwargs-dict; that just has a much better ring to it than star-star-kwargs, or whatever other cryptic symbol you use. I have one more suggestion. I do have one more thing to point out, which is that currently the Python vararg syntax is very difficult to Google for. In the first pages of the four searches matching python (function)? (star | asterisk), there was just one relevant hit on python.org which wasn't a bug report. I certainly remember having a small amount of difficulty figuring out what the heck * and ** did the first time I encountered them. This would suggest perhaps some keywords might be called for instead of operators. In the grand scheme of things the argument packing and unpacking are not *all* that common, so I don't think the syntactic burden would be immense. The bigger issue, of course, would be picking good words. This also helps with the issue above. Let's say we'll use 'varargs' and 'kwargs', though the latter too well-ingrained in code to steal. (I don't want to get too much into the debate over *what* word to choose. Also these don't match the 'head, *tail = l' syntax very well.) Then we could say: def foo(varargs l, kwargs d): bar(varargs l, kwargs d) and varargs would be equivalent to * and kwargs would be equivalent to **. But then you could also say def foo(varargs(list) l, kwargs(dict) d) I agree; I had the same experience. But according to others our opinion is wrong, and we should just become better at using google. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
I'm just going to throw myself in the conversation obtusely.I felt we needed some real code. These are literally the first two samples I had on hand. !!! OUT OF CONTEXT REAL CODE ALERT !!! ### formatter = formatter.format(**color).replace((,{).replace(),}) print(\n\n.join(formatter.format(**d) for d in db)) # vs # formatter = formatter.format(::(), ::color).replace((,{).replace(),}) print(\n\n.join(formatter.format(::(), ::d) for d in db)) # What do we do for format(**kwargs)? # With the current guess of mine, I'm thinking what does ::() do? and why are there two double-colons?. # Aside from that it looks not much different/worse. # and # def checkLoad(self, *args, **kwargs): if getattr(self, x) == None: getattr(self, loadx)() if fakeself: return function(getattr(self, x), *args, **kwargs) else: return function(self, *args, **kwargs) return checkLoad # vs # def checkLoad(self, tuple::args, dict::kwargs): if getattr(self, x) == None: getattr(self, loadx)() if fakeself: return function(getattr(self, x), ::args, ::kwargs) else: return function(self, ::args, ::kwargs) return checkLoad # It looks much the same, but how does it benefit me? # *args is very distinct from **kwargs in my opinion. tuple/dict doesn't have that. # That said, the second works better with my syntax highlighter (although pylint then swears at me). # Before I actually put the syntax in context I hated this. Now I just really dislike it. There is one big thing bugging me: How do I do: foo(**kwargs)? My solution was to use foo(::(), ::kwargs), but it's obviously not a great alternative. There is another, smaller one. Wrapper functions often just want to pass values straight through them. They don't care that it's a tuple. They don't care that it's a dict. They're just going to throw it across. Without def foo(::args) syntax, that's just a waste of a lookup. With def foo(::args) syntax you lose the discrimination of args and kwargs, resulting in the same problem above. Finally, it's uglier when without. I do have one suggestion: foo(*args, **kwargs): pass foo(tuple(*) args, dict(**) kwargs): pass foo(dict(**) kwargs): pass foo(*, bar=spam): pass # this is illegal because unbound catchalls don't catch anything, as they do today foo(tuple(*), bar=spam): pass I'll leave you to guess how it works. If you can't it's obviously not obvious enough. Advantages: * means a catchall, as it should. * is distinct from **. With syntax highlighting, it's pretty obvious what is going on. It's backwards compatible (the main reason it's not tuple(*):args). *My main problem is: use case? I've had none at all.* If only 1% of users want it, it's not right to make the 99% change. Saving *one line and 50 microseconds* per hundred uses of (*/**) is not a valid argument.And don't make us all change all our code just to satisfy that. The only argument you can make is readability, but (*/**) is more explicit than a lookup, just because it's not dependant on position (args/kwargs argument) and it's always a real tuple and dict. def tuple(): 1/0 -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Sun, 18 Dec 2011 06:13:37 -0800, Eelco wrote: Casts or conversions are a runtime concept; im talking about declarations. That seems to be the source of your confusion. Everything in Python happens at runtime, apart from compilation of source code into byte code. Python doesn't have declarations. Even class and def are statements which happen at runtime, not declarations which happen at compile time. Your proposal will be no different: if it happens, it will happen at runtime. [...] I guess this use of the term entered my lexicon through the C# developer team. Either way, you seem to be the only one who does not grok my intended meaning, so I suggest you try reading it again. I grok your *intended* meaning. I also grok that you are using the wrong words to explain your intended meaning. head, *tail = iterable is not a declaration in Python. It is not a type conversion, or a constraint, or a cast. It is an iterator unpacking operation. It is syntactic sugar for something similar to this: tmp = iter(iterable) head = next(tmp) tail = [] try: while True: tail.append(next(tmp)) except StopIteration: pass del tmp The only constraint is on the *input* to the operation: the right hand side object must obey the iterator protocol. The only conversion (if we want to call it such) is that an iterator object is created by the right hand side object. [...] head, tail = l and head, *tail = l mean something completely different, They are both iterator unpacking, and therefore by definition not completely different. The first one is syntactic sugar for something like this: tmp = iter(iterable) head = next(tmp) tail = next(tmp) if tmp is not empty: raise exception del tmp and the second as shown earlier. Clearly they are quite similar: the only difference is that in the first case, the right hand side must have exactly two items, while in the second case, the right hand side can have an arbitrary number of items. and the only difference is a constraint placed on tail, which forces the semantics to be different; the righthand side, or what is to be assigned, is identical. Of course one can just regard it as syntactic sugar for head, tail = unpackheadandtailaslist(l); but the syntactic sugar achieves that same end through a type constraint on tail. Really. All the words are in English, but I have no understanding of what you are trying to say here. What is unpackheadandtailaslist and how does it differ from actual unpacking in Python? You are jumping to conclusions about implementation details which aren't supported by the visible behaviour. What evidence do you have that iterator unpacking creates a tuple first and then converts it to a list? You are jumping to conclusions about my opinion which aren't supported by my visible behaviour. What evidence do you have that I ever even said any such thing? My evidence was your actual words, quoted in my post, which you deleted in your response. Here they are again: [quote] This changes the semantics from normal unpacking, to unpacking and then repacking all but the head into a list. [end quote] In context, this changes... refers to extended iterator unpacking in the form head, *tail contrasted with head, tail =..., and that it generates a list. It may very well be that I have misunderstood you. If you do not intend the meaning that extended tuple unpacking first unpacks to a tuple and then re-packs to a list, then please explain what you did mean. The aim of this PEP, is that this type-constraint syntax is expanded upon. We should be careful here to distinguish with providing optional type constraints throughout python as a whole; this is not our aim. Iterator unpacking is no more about type constraints than is len(). Because you wish to keep nitpicking about my usage of the term 'type constraint' (even though you have not introduced an alternative term yourself), or because you actually disagree with the content of my message? I don't think much about your proposal. I think it is unnecessary, based on a profound misunderstanding of how Python actually operates, badly explained using inappropriate terms, and the syntax you propose is ugly. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 18 dec, 18:03, Steven D'Aprano steve +comp.lang.pyt...@pearwood.info wrote: On Sun, 18 Dec 2011 06:13:37 -0800, Eelco wrote: Casts or conversions are a runtime concept; im talking about declarations. That seems to be the source of your confusion. Everything in Python happens at runtime, apart from compilation of source code into byte code. Python doesn't have declarations. Even class and def are statements which happen at runtime, not declarations which happen at compile time. Of course it will have runtime effects; and compile/interpret-time effects too. You said as much yourself: 'Everything in Python happens at runtime, apart from compilation of source'. Python *does* have declarations. Even though they may not be called such in the documentation (dunno, havnt checked) the current use of * and ** when not signifying collectiong UNpacking, is an annotation to the declaration of the symbol that comes after it. In this case, a constraint-on / specification-of the type of the object that the variable symbol may bind; a list or tuple, depending on the context. Your proposal will be no different: if it happens, it will happen at runtime. At least something we agree upon; all im proposing is an alternative syntax for something thats already there. Lets be pragmatic and agree to disagree on what it is that is already there, or what it ought to be called. Because frankly, this has detracted enough already from what it is I do want to discuss. [snipped staements of the obvious] and the second as shown earlier. Clearly they are quite similar: the only difference is that in the first case, the right hand side must have exactly two items, while in the second case, the right hand side can have an arbitrary number of items. Oh great, you found another semantic hair to split. Yes, they are quite similar. Nonetheless, any python implementation that would confuse the two behaviors would be considered badly bugged. and the only difference is a constraint placed on tail, which forces the semantics to be different; the righthand side, or what is to be assigned, is identical. Of course one can just regard it as syntactic sugar for head, tail = unpackheadandtailaslist(l); but the syntactic sugar achieves that same end through a type constraint on tail. Really. All the words are in English, but I have no understanding of what you are trying to say here. What is unpackheadandtailaslist and how does it differ from actual unpacking in Python? I have the impression you are not even trying then. Google 'syntactic sugar'. It means 'semantically identical way of putting things', in short. That tells you everything you need to know about unpackheadandtailaslist: nothing. You are jumping to conclusions about implementation details which aren't supported by the visible behaviour. What evidence do you have that iterator unpacking creates a tuple first and then converts it to a list? You are jumping to conclusions about my opinion which aren't supported by my visible behaviour. What evidence do you have that I ever even said any such thing? My evidence was your actual words, quoted in my post, which you deleted in your response. Here they are again: [quote] This changes the semantics from normal unpacking, to unpacking and then repacking all but the head into a list. [end quote] In context, this changes... refers to extended iterator unpacking in the form head, *tail contrasted with head, tail =..., and that it generates a list. It may very well be that I have misunderstood you. If you do not intend the meaning that extended tuple unpacking first unpacks to a tuple and then re-packs to a list, then please explain what you did mean. Again, where did I say it first unpacks to a tuple? As far as im aware that only happens in the context of a function call. The aim of this PEP, is that this type-constraint syntax is expanded upon. We should be careful here to distinguish with providing optional type constraints throughout python as a whole; this is not our aim. Iterator unpacking is no more about type constraints than is len(). Because you wish to keep nitpicking about my usage of the term 'type constraint' (even though you have not introduced an alternative term yourself), or because you actually disagree with the content of my message? I don't think much about your proposal. I think it is unnecessary, based on a profound misunderstanding of how Python actually operates, badly explained using inappropriate terms, and the syntax you propose is ugly. Which is not an aswer to the question I posed; just an expression of frustration. Its mutual. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 12/18/2011 2:36, Steven D'Aprano wrote: The barrier to new keywords in Python is very high. Not going to happen for something that already has perfectly good syntax already familiar to Python and Ruby programmers. Might else well try to get C and Java to stop using ... (ellipses). I agree to some extent; I did say my suggestion was somewhat an effort in brainstorming. (Though I would point out that, if you accept the premise of this PEP suggestion, perfectly good only sort of applies.) The burden is that you complicate the compiler and reduce the pool of useful names available to the programmer. To be useful, the keywords need to be short, meaningful and memorable -- which means they're already used in code, which you will break needlessly. OTOH, it wouldn't be the first time it was done. For instance, 'with'. With operators that otherwise would be illegal, the programmer doesn't need to learn about varargs until they need to. With keywords, the programmer needs to learn you can't use varargs or kwargs as variable names practically from day 1. Yes, but it's not exactly a hard lesson. I can't think of any time where you'd have ambiguous syntax, so misuse could always produce a good error message. And keyword highlighting is something that basically all editors can do well... so unless you're opposed to using an editor more advanced than Notepad, you'll type in varargs, it'll turn purple or whatever, and you'll go oh that's a keyword. So you're not just adding keywords, you're adding new syntax: something which looks like a function call, but isn't a function call. Well, almost by definition these proposals consider adding syntax. I'm going to pose the same question to you I have already posed to Eelco: in your proposal, what happens if the caller has shadowed the list built- in? Does argument l become a built-in list, or does it become whatever type list is currently bound to? Some more questions: Can varargs accepted arbitrary callables, or only a fixed set of known types? How does this differ from what can be done with annotations? These are questions I don't feel I can answer very well. I was giving my thoughts on what I would do or consider doing with the proposal assuming the fundamental idea is sound. Whether it should be accepted at all is a matter for someone else. :-) Evan signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On 12/18/2011 1:31, Steven D'Aprano wrote: And rebutted. Modesty[1] prevents me from quoting myself, but here are some links to searches: http://duckduckgo.com/?q=python+asterisk http://duckduckgo.com/?q=python+* OK, so if you search using the right search engine, you *might* get a link to the Python docs. (As I pointed out in a reply to myself before, you *do* get relevant hits with my Google searches as well, but virtually nothing to the relevant Python documentation.) My thinking is borne out; I asked a friend who didn't know what it did to find out, and he went to Google with the search python 'starred argument', which he said led to moderately helpful results, but again none from the actual Python docs. My normal first place to look for something is Wikipedia. Enjoy it before SOPA kills it. http://en.wikipedia.org/wiki/Asterisk#Programming_languages I might think to look at the Wikipedia article for *Python* (which, by the way, doesn't help); looking at the wikipedia page for *asterisk* wouldn't even enter my mind. Your search looks overly complicated to me. I'm not an expert on Google's syntax, but if you search for python, optionally with function, isn't that the same as just searching for python since it will return hits either with or without function? Chris Angelico's interpretation is correct: I did four searches, python function star, python function asterisk, python star, and python asterisk. Evan signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list