Re: What happened tp scipy.stsci?
On Jan 23, 6:54 pm, Wanderer wrote: > Back in scipy 0.7 there was a package called stsci that had function > scipy.stsci.image.median that created a median image from a stack of > images. The stsci package is dropped in v0.8. Has this functionality > been moved to a different package? > > Thanks > > Apologies if this is a double post. I had problems with google groups. Perhaps that package has been merged with scipy.ndimage? Either way, if I understand correctly, what you are trying to do could be done with numpy.median(imagestack, axis=stackaxis), no? -- http://mail.python.org/mailman/listinfo/python-list
Re: What happened tp scipy.stsci?
On Jan 27, 12:04 am, Wanderer wrote: > On Jan 26, 2:56 pm, Wanderer wrote: > > > On Jan 25, 1:12 pm, Wanderer wrote: > > > > I found it it is in the stsci package. > > > > On Jan 24, 11:36 am, Eelco wrote: > > > > > Either way, if I understand correctly, what you are trying to do could > > > > be done with numpy.median(imagestack, axis=stackaxis), no? > > > > Yes, I guess so. I didn't realize numpy.median had an axis option. > > > Thanks. That's one less import. > > > Actually numpy.median doesn't work. numpy.median does not accept axis > > greater than 2. > > numpy.median does work. I had to use dstack to create my stacks. Exactly what _stack function to use always confuses me as well :). I prefer to use numpy.concatenate(axis=2), which does exactly the same as dstack, but is much less confusing to me. Especially useful in keeping hstack and vstack apart. 'horizontal' and 'vertical', what does that even mean? One could look it up or try to think about it; but in my opinion its much simpler to directly deal in terms of axis numbers. -- http://mail.python.org/mailman/listinfo/python-list
Re: Numeric root-finding in Python
On Feb 12, 7:41 am, Steven D'Aprano wrote: > This is only peripherally a Python problem, but in case anyone has any > good ideas I'm going to ask it. > > I have a routine to calculate an approximation of Lambert's W function, > and then apply a root-finding technique to improve the approximation. > This mostly works well, but sometimes the root-finder gets stuck in a > cycle. > > Here's my function: > > import math > def improve(x, w, exp=math.exp): > """Use Halley's method to improve an estimate of W(x) given > an initial estimate w. > """ > try: > for i in range(36): # Max number of iterations. > ew = exp(w) > a = w*ew - x > b = ew*(w + 1) > err = -a/b # Estimate of the error in the current w. > if abs(err) <= 1e-16: > break > print '%d: w= %r err= %r' % (i, w, err) > # Make a better estimate. > c = (w + 2)*a/(2*w + 2) > delta = a/(b - c) > w -= delta > else: > raise RuntimeError('calculation failed to converge', err) > except ZeroDivisionError: > assert w == -1 > return w > > Here's an example where improve() converges very quickly: > > py> improve(-0.36, -1.222769842388856) > 0: w= -1.222769842388856 err= -2.9158979924038895e-07 > 1: w= -1.2227701339785069 err= 8.4638038491998997e-16 > -1.222770133978506 > > That's what I expect: convergence in only a few iterations. > > Here's an example where it gets stuck in a cycle, bouncing back and forth > between two values: > > py> improve(-0.36787344117144249, -1.0057222396915309) > 0: w= -1.0057222396915309 err= 2.6521238905750239e-14 > 1: w= -1.0057222396915044 err= -2.6521238905872001e-14 > 2: w= -1.0057222396915309 err= 2.6521238905750239e-14 > 3: w= -1.0057222396915044 err= -2.6521238905872001e-14 > 4: w= -1.0057222396915309 err= 2.6521238905750239e-14 > 5: w= -1.0057222396915044 err= -2.6521238905872001e-14 > [...] > 32: w= -1.0057222396915309 err= 2.6521238905750239e-14 > 33: w= -1.0057222396915044 err= -2.6521238905872001e-14 > 34: w= -1.0057222396915309 err= 2.6521238905750239e-14 > 35: w= -1.0057222396915044 err= -2.6521238905872001e-14 > Traceback (most recent call last): > File "", line 1, in > File "", line 19, in improve > RuntimeError: ('calculation failed to converge', -2.6521238905872001e-14) > > (The correct value for w is approximately -1.00572223991.) > > I know that Newton's method is subject to cycles, but I haven't found any > discussion about Halley's method and cycles, nor do I know what the best > approach for breaking them would be. None of the papers on calculating > the Lambert W function that I have found mentions this. > > Does anyone have any advice for solving this? > > -- > Steven Looks like floating point issues to me, rather than something intrinsic to the iterative algorithm. Surely there is not complex chaotic behavior to be found in this fairly smooth function in a +/- 1e-14 window. Otoh, there is a lot of floating point significant bit loss issues to be suspected in the kind of operations you are performing (exp(x) + something, always a tricky one). I would start by asking: How accurate is good enough? If its not good enough, play around the the ordering of your operations, try solving a transformed problem less sensitive to loss of significance; and begin by trying different numeric types to see if the problem is sensitive thereto to begin with. -- http://mail.python.org/mailman/listinfo/python-list
Re: functions which take functions
On Apr 10, 3:36 am, Kiuhnm wrote: > On 4/10/2012 14:29, Ulrich Eckhardt wrote: > > > Am 09.04.2012 20:57, schrieb Kiuhnm: > >> Do you have some real or realistic (but easy and self-contained) > >> examples when you had to define a (multi-statement) function and pass it > >> to another function? > > > Take a look at decorators, they not only take non-trivial functions but > > also return them. That said, I wonder what your intention behind this > > question is... > > > :) > > That won't do. A good example is when you pass a function to re.sub, for > instance. > > Kiuhnm Wont do for what? Seems like a perfect example of function-passing to me. If you have such a precise notion of what it is you are looking for, why even ask? -- http://mail.python.org/mailman/listinfo/python-list
Re: numpy (matrix solver) - python vs. matlab
There is linalg.pinv, which computes a pseudoinverse based on SVD that works on all matrices, regardless of the rank of the matrix. It merely approximates A*A.I = I as well as A permits though, rather than being a true inverse, which may not exist. Anyway, there are no general answers for this kind of thing. In all non-textbook problems I can think of, the properties of your matrix are highly constrained by the problem you are working on; which additional tests are required to check for corner cases thus depends on the problem. Often, if you have found an elegant solution to your problem, no such corner cases exist. In that case, MATLAB is just wasting your time with its automated checks. -- http://mail.python.org/mailman/listinfo/python-list
Re: Help needed with nested parsing of file into objects
> thank you both for your replies. Unfortunately it is a pre-existing > file format imposed by an external system that I can't > change. Thank you for the code snippet. Hi Richard, Despite the fact that it is a preexisting format, it is very close indeed to valid YAML code. Writing your own whitespace-aware parser can be a bit of a pain, but since YAML does this for you, I would argue the cleanest solution would be to bootstrap that functionality, rather than roll your own solution, or to resort to hard to maintain regex voodoo. Here is my solution. As a bonus, it directly constructs a custom object hierarchy (obviously you would want to expand on this, but the essentials are there). One caveat: at the moment, the conversion to YAML relies on the appparent convention that instances never directly contain other instances, and lists never directly contain lists. This means all instances are list entries and get a '-' appended, and this just works. If this is not a general rule, youd have to keep track of an enclosing scope stack an emit dashes based on that. Anyway, the idea is there, and I believe it to be one worth looking at. import yaml class A(yaml.YAMLObject): yaml_tag = u'!A' def __init__(self, **kwargs): self.__dict__.update(kwargs) def __repr__(self): return 'A' + str(self.__dict__) class B(yaml.YAMLObject): yaml_tag = u'!B' def __init__(self, **kwargs): self.__dict__.update(kwargs) def __repr__(self): return 'B' + str(self.__dict__) class C(yaml.YAMLObject): yaml_tag = u'!C' def __init__(self, **kwargs): self.__dict__.update(kwargs) def __repr__(self): return 'C' + str(self.__dict__) class TestArray(yaml.YAMLObject): yaml_tag = u'!TestArray' def __init__(self, **kwargs): self.__dict__.update(kwargs) def __repr__(self): return 'TestArray' + str(self.__dict__) class myList(yaml.YAMLObject): yaml_tag = u'!myList' def __init__(self, **kwargs): self.__dict__.update(kwargs) def __repr__(self): return 'myList' + str(self.__dict__) data = \ """ An instance of TestArray a=a b=b c=c List of 2 A elements: Instance of A element a=1 b=2 c=3 Instance of A element d=1 e=2 f=3 List of 1 B elements Instance of B element a=1 b=2 c=3 List of 2 C elements Instance of C element a=1 b=2 c=3 Instance of C element a=1 b=2 c=3 An instance of TestArray a=1 b=2 c=3 """.strip() #remove trailing whitespace and seemingly erronous colon in line 5 lines = [' '+line.rstrip().rstrip(':') for line in data.split('\n')] def transform(lines): """transform text line by line""" for line in lines: #regular mapping lines if line.find('=') > 0: yield line.replace('=', ': ') #instance lines p = line.find('nstance of') if p > 0: s = p + 11 e = line[s:].find(' ') if e == -1: e = len(line[s:]) tag = line[s:s+e] whitespace= line.partition(line.lstrip())[0] yield whitespace[:-2]+' -'+ ' !'+tag #list lines p = line.find('List of') if p > 0: whitespace= line.partition(line.lstrip())[0] yield whitespace[:-2]+' '+ 'myList:' ##transformed = (transform( lines)) ##for i,t in enumerate(transformed): ##print '{:>3}{}'.format(i,t) transformed = '\n'.join(transform( lines)) print transformed res = yaml.load(transformed) print res print yaml.dump(res) -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
> The modulus is not the result but one of the arguments: when numbers x > and y are congruent modulo n (stated in terms of the modulo operation: > x mod n = y mod n), the modulus is n. A word for x mod n is remainder. > > I agree about the obscurity of using the percent sign as the operator. > > A quick google suggests that your use of 'modulus' is now popular > among programmers. Past experience in mathematics newsgroups tells me > that some mathematicians do not accept the existence of any remainder > operator at all. Honest. (I see them but I cannot understand them.) You are correct; the thing it computes is the remainder, not the modulus. Nonetheless, 'x modulus y' is how it is put in natural language, but I suppose math.remainder would be my preferred place to put this. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
By the way... Is there any particular reason why some of my replies do not show up on groups.google, and some of them do not show up on mail.python.org? Sorry to annoy people with reposting, but im going to be forced to do some of that until this is cleared up -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
> No more, or less, explicit than the difference between "==" and "is". == may be taken to mean identity comparison; 'equals' can only mean one thing. Of course 'formally' these symbols are well defined, but so is brainf*ck > Modulo is hardly an obscure operation. "What's the remainder...?" is a > simple question that people learn about in primary school. So is 'how much wood would a woodchucker chuck if a woodchucker could chuck wood?'. But how often does that concept turn up in your code? > And you can blame C for the use of % instead of mod or modulo. I didnt know one of Python's design goals was backwards compatibility with C. > I can't imagine what sort of Python code you have seen that you consider > 90% attribute access "typical". I've just run the Python tokenizer over > my startup.py file, and I get these results: Yes, that was a hyperbole; but quite an often used construct, is it not? > If you can supply any function at all, what happens if I write this: You cannot; only constructors modelling a sequence or a dict, and only in that order. Is that rule clear enough? > I believe that your proposal leads to an over-generalisation "call > arbitrary functions when handling parameter lists". I hope the above clears that up. It is as much about calling functions as ** is about raising kwargs to the power of. > I don't believe you > need this added complication. If you want to your var args as a list, > call list(args) inside your function. We dont strictly 'need' any language construct. Real men use assembler, right? > > head, tuple(tail) = iterable > In Python 3, that is spelled: > head, *tail = iterable > tail = tuple(tail) Yes, I know. How is that not a lot more verbose and worse than what I have proposed in all possible ways? > head, tail = somestring[0], somestring[1:] Well yes, splendid; we can do that with lists too since the dawn of Python. What you are saying here in effect is that you think the head/tail syntax is superfluous; that youd rather see it eliminated than generalized. > head, tail = next(mygenerator), mygenerator Which again of course works, but is yet again of entirely different form than any of the above solutions, while conceptually doing the same thing. Certainly, there is room for improved elegance here? -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
> > I personally quite like them, but I would like them to be more general. > > It already is. The *target can be anywhere in the sequence. Im not sure if this is a genuine understanding, or trollish obtuseness. Yes, the target can be anywhere in the sequence. And yes, the resulting list can contain objects of any type, so its very flexible in that regard too. But to relate it to the topic of this thread: no, the syntax does not allow one to select the type of the resulting sequence. It always constructs a list. Yes, we can cast the list to be whatever we want on the next line, but the question is whether this language design can be improved upon. The choice of a list feels arbitrary, adding another line to cast it to something else would be even more verbose, and whats more, there would be serious performance implications if one should seek to apply this pattern to a deque/linkedlist; it would make taking off the head/tail of the list from a constant to a linear operation. That is: >>> head, deque(tail) = somedeque Is better in every way I can think of (readability, consistence, performance) than: >>> head, *tail = somedeque >>> tail = deque(tail) -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
> They recognize modular arithmetic but for some reason insist that > there is no such _binary operation_. But as I said, I don't understand > their concern. (Except the related concern about some programming > languages, not Python, where the remainder does not behave well with > respect to division.) They might not be willing to define it, but as soon as we programmers do, well, we did. Having studied the contemporary philosophy of mathematics, their concern is probably that in their minds, mathematics is whatever some dead guy said it was, and they dont know of any dead guy ever talking about a modulus operation, so therefore it 'does not exist'. Whatever you want to call the concept we are talking about, or whether you care to talk about it at all, it is most certainly a binary operation, since there are two arguments involved. There is no way around that. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On Dec 12, 7:09 pm, Ian Kelly wrote: > On Mon, Dec 12, 2011 at 5:21 AM, Eelco wrote: > > You cannot; only constructors modelling a sequence or a dict, and > > only > > in that order. Is that rule clear enough? > > The dict constructor can receive either a sequence or a mapping, so if > I write this: > > def func(a, b, dict(c)): > > what will I get? Probably I would want the equivalent of: > > def func(a, b, **c): > > but you seem to be saying that I would actually get the equivalent of this: > > def func(a, b, *c): > c = dict(c) > > Cheers, > Ian Im not sure if I was clear on that, but I dont care what the constructors accept; I meant to overload on the concept the underlying type models. Dicts model a mapping, lists/tuples model a sequence. MI deriving from both these models is illegal anyway, so one can unambigiously overload on that trait. The syntax only superficially resembles 'call the dict constructor with the object passed into kwargs'. What its supposed to mean is exactly the same as **kwargs, but with added flexibility. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
> False. I stand corrected. > Or are you saying that only classes specifically derived from list, > tuple, or dict should be considered, and custom containers that are > not derived from any of those but implement the correct protocols > should be excluded? If so, that sounds less than ideal. That might be a desirable constraint from an implementational/ performance aspect anyway, but I agree, less than ideal. Either way, its not hard to add some detail to the semantics to allow all this. Even this function definition: def func(Foo(args), Foo(kwargs)) ...could even be defined unambigiously by overloading first on base type, and if that does not uniquely determine the args and kwargs, fall back on positionality, so that: def func(Foo(args), dict(kwargs)) def func(list(args), Foo(kwargs)) would be uniquely defined as well. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
To get back on topic a little bit, lets get back to the syntax of all this: I think we all agree that recycling the function call syntax is less than ideal, since while it works in special contexts like a function signature, its symmetric counterpart inside a function call already has the meaning of a function call. In general, we face the problem of specifying metadata about a variable, or a limited form of type constraint. What we want is similar to function annotations in python 3; in line with that, we could have more general variable annotations. With an important conceptual distinction; function annotations are meaningless to python, but the annotations I have in mind should modify semantics directly. However, its still conceptually close enough that we might want to use the colon syntax here too. To distinguish it from function annotations, we could use a double colon (double colon is an annotation with non-void semantics; quite a simple rule); or to maintain an historic link with the existing packing/unpacking syntax, we could look at an augmented form of the asteriks notation. For instance: def func(list*args, dict*kwargs) <- list-of-args, dict-of-kwargs def func(args::list, kwargs::dict) <- I like the readability of this one even better; args-list and kwargs-dict And: head, deque*tail = somedeque head, tail::deque = somedeque Or some variants thereof -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On Dec 12, 8:05 pm, Eelco wrote: > To get back on topic a little bit, lets get back to the syntax of all > this: I think we all agree that recycling the function call syntax is > less than ideal, since while it works in special contexts like a > function signature, its symmetric counterpart inside a function call > already has the meaning of a function call. > > In general, we face the problem of specifying metadata about a > variable, or a limited form of type constraint. > > What we want is similar to function annotations in python 3; in line > with that, we could have more general variable annotations. With an > important conceptual distinction; function annotations are meaningless > to python, but the annotations I have in mind should modify semantics > directly. However, its still conceptually close enough that we might > want to use the colon syntax here too. To distinguish it from function > annotations, we could use a double colon (double colon is an > annotation with non-void semantics; quite a simple rule); or to > maintain an historic link with the existing packing/unpacking syntax, > we could look at an augmented form of the asteriks notation. > > For instance: > > def func(list*args, dict*kwargs) <- list-of-args, dict-of-kwargs > def func(args::list, kwargs::dict) <- I like the readability of this > one even better; args-list and kwargs-dict > > And: > > head, deque*tail = somedeque > head, tail::deque = somedeque > > Or some variants thereof As for calling functions; calling a function with the content of a collection type rather than the collection as an object itself is a rather weird special case operation I suppose, but we can cover it with the same syntax: def func(args::tuple, kwargs::dict): funccall(args::, kwargs::) <- void type constraint means unpacking, for symmetry with args/kwargs aggregation funccall(::args, ::kwargs) <- I like this better, to emphasize it being 'the other side' of the same coin, and quite close to ** syntax Sequence and Mapping unpacking dont need their own symbols, if things are done like this, since in the function declaration the meaning is clear from the type of the annotations used, plus their position, and in the call the meaning is clear from the type of the object undergoing to unpacking operation. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
> > Im not sure if this is a genuine understanding, or trollish > > obtuseness. > > If you are referring to what I write, it is based on genuine > understanding of Python. This is getting 'interesting'. In a way. I meant to write 'misunderstanding', as I think the context made quite clear. So again this adds another layer of doubt as to whether you are being obtuse for its own sake, or if there is yet another layer of misunderstanding stacked on top of the others. Either way, lets continue with the benefit of the doubt. > One use case of *target is to ignore the stuff collected in the target > because one only wants a few end values from the iterable. Another is to > pull stuff out because one wants to iterate through the rest. For both > uses, a list is as good as anything. So what is the point of having different sequence types, if a list can do anything? I would argue that the different performance characteristics and differences in semantics give each sequence type ample reason for existence. > Convert. For the very few cases one wants to do this, it is quite adequate. Or so you opine. As you may recall, the original idea was motivated by args/kwargs syntactic clarity and flexibility; I merely shifted focus to this use case of collection unpacking since it is somewhat simpler and easier to discuss. Keep that in mind, should you seek to build a case for that assertion in the future. > > but the question is whether this language design can be improved upon. > > Not easily. Again, so you opine. Care to give a refutation of my proposed double colon syntax? Ignoring for a moment whether or not it is useful; does it clash with anything? I havnt been able to think of anything in the past few hours, but im not taking that to mean much; there are probably some subtleties I am overlooking. I think it dos not clash with slicing syntax for instance, but im not sure. > For a linked list, no *target and no copying is needed: > > head, tail = llist I have no idea what this means. > head, deque(tail) = somedeque > > > Is better in every way I can think of (readability, consistence, > > performance) than: > head, *tail = somedeque > tail = deque(tail) > > But your suggestion is much worse in each way than > > head = somedeque.popleft() No its not. First of all, its not semantically equivalent; popleft mutates a collection type, and collection unpacking does not; it creates a set of disjoint views of the collection's data. Whether its worse in terms of readability is debatable, but in terms of the other two stated metrics, your claim of it being any kind of worse is objectively false. Furthermore, this brings us back again to the point I raised several times before. Yes, obviously you can already DO these things, but NOT within the same uniform collection unpacking syntactic construct. Again, you have failed to point out what is wrong with supplying a type constrain to python and let it do the right thing based on that; to reiterate: head, tail::deque = deque No need to mutate anything; python can create the view of the linkedlist internally. A single unambigious syntax, and single unambigious semantics, for all sequence types. Whats not to like? If you dont like the extra characters you have to type; there is of course such a thing as defaults. You can choose: head, tail:: = deque; if the type constraint is omitted, we could make tail a list by default, or my preferred solution, infer it from the right hand side type. In case of the former, all you had to do was type :: instead of *, and your python universe would otherwise be completely unchanged. If thats 'not easily', I dont know what is. > To repeat, there is no reason to copy even once. If one does not want to > mutate the deque, then one mutates an iterator view of the deque. And arrive at yet another construction to do the same thing. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On Dec 13, 1:27 am, alex23 wrote: > On Dec 13, 3:12 am, Eelco wrote: > > > But to relate it to the topic of this thread: no, the syntax does not > > allow one to select the type of the resulting sequence. It always > > constructs a list. > > So by this argument, _every_ function that returns a list should take > an optional argument to specify an alternative form of sequence. > > What, exactly, is so onerous about coercing your list to _whatever_ > type you want? You know, like everybody else has been. > > What does this _gain_ you other than one less line of code? 1) Turning two lines of code into a single more readable one is nothing to scoff at 2) After-the-fact conversion is O(n), getting the view you want right away is O(1) Not every function needs this flexibility; many specialized functions could not care less. But collection unpacking is quite a general thing, and for the record; slicing a tuple returns a tuple. Would you rather have that return a list too? -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On Dec 13, 1:34 am, Ian Kelly wrote: > On Mon, Dec 12, 2011 at 11:51 AM, Eelco wrote: > > Either way, its not hard to add some detail to the semantics to allow > > all this. Even this function definition: > > > def func(Foo(args), Foo(kwargs)) > > > ...could even be defined unambigiously by overloading first on base > > type, and if that does not uniquely determine the args and kwargs, > > fall back on positionality, so that: > > > def func(Foo(args), dict(kwargs)) > > def func(list(args), Foo(kwargs)) > > > would be uniquely defined as well. > > That solves some of the problems, but if I just have: > > def func(SequenceOrMappingType(args)): > > That's going to unpack positionally. If I want it to unpack keywords > instead, how would I change the definition to indicate that? That should raise an ambiguity error. But honestly, how often have you worked with SequenceOrMappingType's? I think this is a rather palatable constraint. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On Dec 13, 2:41 am, Ian Kelly wrote: > On Mon, Dec 12, 2011 at 4:40 PM, Eelco wrote: > >> For a linked list, no *target and no copying is needed: > > >> head, tail = llist > > > I have no idea what this means. > > Each node of a linked list consists of a data member and a "next" > member, that holds the next node in the list. The natural container > for this and the way it is usually implemented in Python is a > 2-element tuple. For example: > > llist = ('one', ('two', ('three', ('four', None > > would be a linked list as typically constructed in Python, and it can > be used in pretty much the same way that lists are used in Lisp. The > result of the operation: > > head, tail = llist > > is: > > head = 'one' > tail = ('two', ('three', ('four', None))) > > and as Terry pointed out, no copying is required to do this. I > believe deque is also implemented as a doubly-linked list, which is > probably why you keep referring to it as such, but that is an > implementation detail. When you say "linked list" in relation to > Python, the preceding is what comes to mind. 'for i in llist' is not quite going to fly is it? Thats probably the reason noone ever uses that construct; its not a proper sequence type. > >> >>>> head, deque(tail) = somedeque > > >> > Is better in every way I can think of (readability, consistence, > >> > performance) than: > >> >>>> head, *tail = somedeque > >> >>>> tail = deque(tail) > > >> But your suggestion is much worse in each way than > > >> head = somedeque.popleft() > > > No its not. First of all, its not semantically equivalent; popleft > > mutates a collection type, and collection unpacking does not; it > > creates a set of disjoint views of the collection's data. Whether its > > worse in terms of readability is debatable, but in terms of the other > > two stated metrics, your claim of it being any kind of worse is > > objectively false. > > I definitely disagree on readability. Skimming this thread as I have > been, it took me a while to get that your proposed syntax would create > a second deque sharing internal state with the original, rather than > creating a simple copy of the deque, which is what it looks like it > should do. Thats a matter of reading up on the semantics of collection unpacking. To be honest I dont even know what they are for lists, since I dont use python 3. But whatever is the case, the important thing is that the semantics should be uniform regardless of the type to be unpacked. > Incidentally, while that change is not really central to your syntax > proposal, I think it would be very messy. For example, how do you > propose keeping the length elements in sync? Inserting an item in one > may or may not affect the length of the other. If I append an item to > the end of one deque, should the other automatically be extended as > well? What if the tail node of the second deque occurs after the tail > node of the deque being appended? Does the appended element then get > inserted into the middle of the second deque (I think it would have to > be)? If I insert an element into the longer (second) deque that just > happens to be immediately after the tail of the shorter deque, does > *that* cause the shorter deque to be automatically extended? And > likewise for operations at the head of the deque. > > None of these questions have obvious answers as to the "right" way to > it, and for that reason I think this is probably best left to the user > to implement a custom deque view class with whatever semantics they > prefer. Good point. Copy-on-write semantics could be used, but really one should have several linked list types reflecting the underlying implementations. I would like to have an immutable singly linked list builtin of the standard functional type, which you can only unpack from one end and renders these issues moot, plus a builtin doubly linked list with copy-on-write or copy-on-unpacking semantics. > > Furthermore, this brings us back again to the point I raised several > > times before. Yes, obviously you can already DO these things, but NOT > > within the same uniform collection unpacking syntactic construct. > > Again, you have failed to point out what is wrong with supplying a > > type constrain to python and let it do the right thing based on that; > > to reiterate: > > > head, tail::deque = deque > > Python users generally follow the rule "explicit is better than > implicit". Setting a general constraint and letti
Re: Verbose and flexible args and kwargs syntax
On Dec 13, 3:43 am, Steven D'Aprano wrote: > On Mon, 12 Dec 2011 04:21:15 -0800, Eelco wrote: > >> No more, or less, explicit than the difference between "==" and "is". > > > == may be taken to mean identity comparison; 'equals' can only mean one > > thing. > > Nonsense. "Equals" can be taken to mean anything the language designer > chooses, same as "==". There is no language police that enforces The One > True Meaning Of Equals. In fact, there is no one true meaning of equals. > Even my tiny Pocket Oxford dictionary lists five definitions. > > It is ironic that the example you give, that of identity, is the standard > definition of equals in mathematics. 2*2 = 4 does not merely say that > "there is a thing, 2*2, which has the same value as a different thing, > 4", but that both sides are the same thing. Two times two *is* four. All > numbers are, in some sense, singletons and equality implies identity. We are not talking mathemathics, we are talking programming languages. Identity versus value equality is a well established concept within its jargon. Within this context, 'equals' and 'is' have clearly defined meanings. Indeed within broader use, including everyday language, the distinction is more subtle and therefore less useful, but obeying a linguistic rule that holds within computer science is better than making something up just for python, even though its not the yet better rule that any five year old might grasp. > > Of course 'formally' these symbols are well defined, but so is > > brainf*ck > > I don't understand your point here. Hence the above. > >> Modulo is hardly an obscure operation. "What's the remainder...?" is a > >> simple question that people learn about in primary school. > > > So is 'how much wood would a woodchucker chuck if a woodchucker could > > chuck wood?'. But how often does that concept turn up in your code? > > You didn't make a statement about how often modulo turns up in code > (which is actually quite frequently, and possibly more frequently than > regular division), but about the obscurity of the operation. Taking the > remainder is not an obscure operation. The names "modulo" and "modulus" > may be obscure to those who haven't done a lot of mathematics, but the > concept of remainder is not. "How many pieces are left over after > dividing into equal portions" is something which even small children get. So 'frequency of use' is no valid interpretation of 'obscurity'? Im not a native speaker, but im pretty sure it is. > >> And you can blame C for the use of % instead of mod or modulo. > > > I didnt know one of Python's design goals was backwards compatibility > > with C. > > Don't be silly. You know full well Python is not backwards compatible > with C, even if they do share some syntactical features. Of course I was being silly; I know this use is following a historical precedent; but id rather see it rectified in the previous version of python rather than the next. My sillyness was prompted by the percieved pointlessness of your remark. Of course python is not trying to be backwards compatible with C; so why bring it up then? > >> If you can supply any function at all, what happens if I write this: > > > You cannot; only constructors modelling a sequence or a dict, and only > > in that order. Is that rule clear enough? > > But why limit yourself to those restrictive rules? > > If I want to collect a sequence of arguments into a string, why shouldn't > I be allowed to write this? > > def func(parg, str(args)): ... > > If I want to sum a collection of arguments, why not write this? > > def func(pargs, sum(args)): ... > > Isn't that better than this? > > def func(pargs, *args): > args = sum(args) > ... > > But no. I don't mean those examples to be taken seriously: when you > answer to your own satisfaction why they are bad ideas, you may be closer > to understanding why I believe your idea is also a bad idea. They are bad ideas because they truely do not lead to the execution of different code, but are merely a reordering, mixing statements in with a function declaration. I am proposing no such thing; again, the type(arg) notation I have dropped, and never was meant to have anything to do with function calling; it is a way of supplying an optional type constraint, so in analogy with function annotations, I changed that to arg::type. Again, this has nothing to do with calling functions on arguments. First off, type constraints must have some use; all those languages cant
Re: Verbose and flexible args and kwargs syntax
> > Python users generally follow the rule "explicit is better than > > implicit". Setting a general constraint and letting the language "do > > the right thing" is a kind of black magic that feels off because it > > tends to break that rule. But that's not to say that black magic > > never wins -- just look at super() and the MRO. > > We are not talking black magic here; we are talking about an EXPLICIT > type constraint provided on the very same line. To hammer that point home: would you say the following C# code performs 'black magic'? float x = 3; After all, exactly the same thing is going on; C# will 'do the right thing'; convert the integer literal 3 to a floating point value, based on the type constraint placed on x. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
> To answer that question: for the same reasons. The conversion is > wasteful; allowing python to do the right thing based on a > typeconstraint is not. Plus, it is less code, and more readable code; > the only rule you have to learn is quite general, which is that :: is > a type constraint annotation; no need to remember specifics, like > 'unpacking always returns lists for some arbitrary reason'. Oh my bad; actually, that should be: 'collecting the remainder of an unpacked iterable using * will always yield a list. That is, unless the construct appears inside a function definition; then somehow a tuple is always the right choice' -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On 13 dec, 11:15, Arnaud Delobelle wrote: > On 13 December 2011 09:50, Eelco wrote: > > >> To answer that question: for the same reasons. The conversion is > >> wasteful; allowing python to do the right thing based on a > >> typeconstraint is not. Plus, it is less code, and more readable code; > >> the only rule you have to learn is quite general, which is that :: is > >> a type constraint annotation; no need to remember specifics, like > >> 'unpacking always returns lists for some arbitrary reason'. > > > Oh my bad; actually, that should be: > > > 'collecting the remainder of an unpacked iterable using * will always > > yield a list. That is, unless the construct appears inside a function > > definition; then somehow a tuple is always the right choice' > > When you quote somebody (even yourself), it would be helpful if you > attributed your quote. > > -- > Arnaud Ah yes; im more used to proper forums, still getting used to these mailing-list things. But point taken. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
With all this being said, I must say that the notion of indtroducing type constraints into Python is quite a radical one*, and one that should not be taken lightly, so I understand the general conservative vibe the notion is getting. It probably has implications beyond just collection types, and if youd introduce such a feature, you would like to introduce it only once, and correctly the first time around. Ill probably start a new thread soon, recapping the accumulated insight, and capping all the OT threads that have spawned. *even though the asteriks syntax is infact a limited form of exactly that -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On 13 dec, 12:28, Steven D'Aprano wrote: > On Tue, 13 Dec 2011 02:46:13 -0800, Eelco wrote: > > With all this being said, I must say that the notion of indtroducing > > type constraints into Python is quite a radical one*, > > Not that radical. Here's the creator of Python musing about adding > optional type checks to Python: > > http://www.artima.com/weblogs/viewpost.jsp?thread=85551http://www.artima.com/weblogs/viewpost.jsp?thread=86641http://www.artima.com/weblogs/viewpost.jsp?thread=87182 Good find; but still radical enough that it hasnt been implemented. Note that these musing are trying to adress a yet far more general problem of specifying arbitrary types constraints on anything; I am primarily interested in specifying container types in the special case of collection packing/unpacking syntax, with further extensions nothing but a welcome addon. The fact that the former was judged infeasible does not mean the more modest goal of the latter might not be attainable. > > *even though the asteriks syntax is infact a limited form of exactly > > that > > It absolutely is not. def f(*args, **kwargs) constructs a tuple and a > dict, it does not type-check that the function is passed a tuple and a > dict as arguments. These are completely different things. Which is of course not something I ever proposed; I never said anything about checking types of existing data; im talking about coercing types of newly created data, like the target of a collection packing. That is exactly what *args and **kwargs also do. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On 13 dec, 12:13, Steven D'Aprano wrote: > On Tue, 13 Dec 2011 01:15:46 -0800, Eelco wrote: > > On Dec 13, 3:43 am, Steven D'Aprano > +comp.lang.pyt...@pearwood.info> wrote: > >> On Mon, 12 Dec 2011 04:21:15 -0800, Eelco wrote: > >> >> No more, or less, explicit than the difference between "==" and > >> >> "is". > > >> > == may be taken to mean identity comparison; 'equals' can only mean > >> > one thing. > [...] > > We are not talking mathemathics, we are talking programming languages. > > What *I* am talking about is your assertion that there is only one > possible meaning for "equals" in the context of a programing language. > This is *simply not correct*. > > You don't have to believe me, just look at the facts. It's hard to find > languages that use the word "equals" (or very close to it) rather than > equals signs, but here are four languages which do: That python is not the only language to not get this quite as right as could be is known to me. But within computer science as a discipline, equality and identity comparisons have a clear enough meaning. 'is' has a narrower meaning than 'equals'. '==' has no meaning whatsoever in computer science. > Again, all this goes to demonstrate that the language designer is free to > choose any behaviour they like, and give it any name they like. Certainly you demonstrated as much. Programming languages are created by people, and they have a tendency to make mistakes, and to have to compromise (backwards compatibility, and so on). Thats a seperate matter from 'what ought to be done', when discussing optimal language design. > > So 'frequency of use' is no valid interpretation of 'obscurity'? Im not > > a native speaker, but im pretty sure it is. > > No. Things which are obscure are used in language infrequently, because > if they were common they would not be obscure. But things which are used > infrequently are not necessarily obscure. > > An example in common language: "Napoleon Bonaparte" does not come up in > conversation very frequently, but he is not an obscure historical figure. > > An example from programming: very few people need to use the > trigonometric functions sin, cos, tan in their code. But they are not > obscure functions: most people remember them from school. People who have > forgotten almost everything about mathematics except basic arithmetic > probably remember sin, cos and tan. But they never use them. I dont think its terribly interesting to debate whether the term obscure applies to trigonometric functions or not: the important matter is that they are where they should be; under math.cos, etc. They dont have their own special character, and I hope you agree that is as it should be. I use trig far more often than modulus, so that argues in favor of modulus being under math too; infact I used modulus quite recently, but naturally it was in a piece of code that should be done in C eventually anyway (evaluating subdivision surfaces) > Because you asked why Python uses the % operator for remainder. So you ARE implying python has backwards compatibility with C as a design goal? Otherwise the given answer to this question is nonsensical. > > [...] > > > They are bad ideas because they truely do not lead to the execution of > > different code, but are merely a reordering, mixing statements in with a > > function declaration. I am proposing no such thing; again, the type(arg) > > notation I have dropped, and never was meant to have anything to do with > > function calling; it is a way of supplying an optional type constraint, > > so in analogy with function annotations, I changed that to arg::type. > > Again, this has nothing to do with calling functions on arguments. > > You have not thought about this carefully enough. Consider what happens > when this code gets called: > > def f(*args): pass > > f(a, b, c) > > The Python virtual machine (interpreter, if you prefer) must take three > arguments a, b, c and create a tuple from them. This must happen at > runtime, because the value of the objects is not known at compile time. > So at some point between f(a, b, c) being called and the body of f being > entered, a tuple must be created, and the values of a, b, c must be > collated into a single tuple. > > Now extend this reasoning to your proposal: > > def f(args:FOO): pass > > At runtime, the supplied arguments must be collated into a FOO, whatever > FOO happens to be. Hence, the function that creates FOO objects must be > called before the body of f can be entered. This doesn't happen for free. > Whethe
Re: Verbose and flexible args and kwargs syntax
On 13 dec, 14:14, Chris Angelico wrote: > On Tue, Dec 13, 2011 at 11:47 PM, Eelco wrote: > >> def f(*args) *constructs* a tuple, it > >> doesn't perform a type-check. > > > I am talking about type constraints... A type-check is something > > along the lines of type(args)==list, a runtime thing and something > > completely different. I havnt mentioned the latter at all, explicitly > > or implicitly, as far as im aware. > > I'm not sure what you mean by a "type constraint". Here's how I understand > such: > > float|int foobar; //Declare that the variable 'foobar' is allowed to > hold a float or an int > foobar = 3.2; //Legal. > foobar = 1<<200; //Also legal (a rather large integer value) > foobar = "hello"; //Not legal > > Python doesn't have any such thing (at least, not in-built). Agreed on what a type constraint is, and that python does not really have any, unless one counts the current use of asterikses, which are infact a limited form of type constrait (*tail is not just any object, but one holding a list, which modifies the semantics of the assignment statement 'head,*tail=sequence' from a regular tuple unpacking to a specific form of the more general collection unpacking syntax); The idea is to enrich this syntax; to add optional and limited type constraints to python, specifically to enrich collection packing/ unpacking syntax, but perhaps the concept can be further generalized. > So suppose you can have a user-defined object type instead of > list/dict. How are you going to write that type's __init__ function? > Somewhere along the way, you need to take a variable number of > arguments and bundle them up into a single one... so somewhere, you > need the interpreter to build it for you. This is going to end up > exactly the same as just accepting the tuple and then passing that to > a constructor, like the list example. Keep things transparent and you > make debugging a LOT easier. Agreed; for user defined collection types there would not be a performance benefit over converting a tuple, since this is exactly what will happen anyway, but for collection types derived from any of the builtins, python could optimize away the intermediate and construct the desired collection type directly from the available information. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On Dec 13, 8:11 pm, Cameron Simpson wrote: > On 13Dec2011 00:30, Eelco wrote: > | On Dec 13, 1:27 am, alex23 wrote: > | > On Dec 13, 3:12 am, Eelco wrote: > | > > But to relate it to the topic of this thread: no, the syntax does not > | > > allow one to select the type of the resulting sequence. It always > | > > constructs a list. > | > > | > So by this argument, _every_ function that returns a list should take > | > an optional argument to specify an alternative form of sequence. > | > > | > What, exactly, is so onerous about coercing your list to _whatever_ > | > type you want? You know, like everybody else has been. > | > > | > What does this _gain_ you other than one less line of code? > | > | 1) Turning two lines of code into a single more readable one is > | nothing to scoff at > | 2) After-the-fact conversion is O(n), getting the view you want right > | away is O(1) > > Regarding (2), it has already cost you O(n) to get there. So your O(1) > is a little ingenuous. Well, yes, but if one takes a given sequence as input (at least O(n) complexity to obtain it in the first place, indeed), and then wants to, say, recursively unwind it, the cost of the total operation is O(n) versus O(n^2) And besides, O(n) < 2*O(n); perhaps of lesser concern than different orders, but still. -- http://mail.python.org/mailman/listinfo/python-list
Re: Verbose and flexible args and kwargs syntax
On Dec 13, 7:15 pm, Ian Kelly wrote: > On Tue, Dec 13, 2011 at 1:44 AM, Eelco wrote: > > 'for i in llist' is not quite going to fly is it? Thats probably the > > reason noone ever uses that construct; its not a proper sequence type. > > Not really a problem, because fortunately Python makes it super-easy > to create custom iterators. > > def listiter(llist): > while llist: > head, llist = llist > yield head > > And you're done. If you like, you could also wrap this up in a class > with all the sequence-related magic methods you want, although you > lose the simplicity of the literal syntax by doing so. If this is > rarely used, it is more likely because custom containers are going to > be less efficient than built-ins, but if you want to do functional > programming and are not overly concerned with the speed of iteration, > this is not a bad way to do it. Fair enough. Still, I dont readily see myself using the construct, and I do feel myself longing for something like that to be included as a builtin collection type. Im not sure why python is so stingy with the collections it provides. > > Good point. Copy-on-write semantics could be used, but really one > > should have several linked list types reflecting the underlying > > implementations. I would like to have an immutable singly linked list > > builtin of the standard functional type, which you can only unpack > > from one end and renders these issues moot, plus a builtin doubly > > linked list with copy-on-write or copy-on-unpacking semantics. > > Copy-on-write could be implemented with any type. You don't need a > doubly linked list for that. True > > We are not talking black magic here; we are talking about an EXPLICIT > > type constraint provided on the very same line. > > An explicit type constraint with very different semantics depending on > what particular type you specify and what particular type you're > unpacking from, as I had understood it before. Now you seem to be > saying that it would always be a copy, but sharing state with > copy-on-write possible, which is a different situation. Yes, I think consistent semantics over all sequence types is very important. Although, returning a view for immutable collections like tuples and 'functional lists' (for lack of a better term), and always returning a copy for mutable container types (lists and doubly-linked- lists / deques) is not so bad either, imo. Just one extra simple rule that is clear and obvious enough. > > Well perhaps, but not always knowing the type of your objects at write- > > time is inherent to weakly typed languages; this happens all the time. > > Not knowing the type of the sequence to be unpacked is in a sense an > > asset; I can use this construct in a function, and unpack any sequence > > type in a manner appropriate for it. About the result of the unpacking > > I will know just as much as about the input to it; that they are the > > same type. > > Just because the issue is inherent doesn't mean we should contribute > to it. How are we contributing to it? If we dont know the type of the RHS, we dont know the type of the LHS either, but its not like we lost any information. If we do know the type of the RHS, then we do know the type of the LHS as well; its conserved. > Anyway, the more I think about it, that concern is really more of an > issue for straight copying. One of my pet peeves is that I prefer > list(x) for copying sequences rather than the more common x[::]. The > latter is fine if all I need is an immutable sequence of uncertain > type to iterate and index over -- but then why did I need to make a > copy? Unpacking implies different use cases, though, and maybe a good > argument can be made for it to match type. Thanks for the constructive feedback; something to think about. -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On Dec 14, 4:18 am, Steven D'Aprano wrote: > > They might not be willing to define it, but as soon as we programmers > > do, well, we did. > > > Having studied the contemporary philosophy of mathematics, their concern > > is probably that in their minds, mathematics is whatever some dead guy > > said it was, and they dont know of any dead guy ever talking about a > > modulus operation, so therefore it 'does not exist'. > > You've studied the contemporary philosophy of mathematics huh? > > How about studying some actual mathematics before making such absurd > pronouncements on the psychology of mathematicians? The philosophy was just a sidehobby to the study of actual mathematics; and you are right, studying their works is the best way to get to know them. Speaking from that vantage point, I can say with certainty that the vast majority of mathematicians do not have a coherent philosophy, and they adhere to some loosely defined form of platonism. Indeed that is absurd in a way. Even though you may trust these people to be perfectly functioning deduction machines, you really shouldnt expect them to give sensible answers to the question of which are sensible axioms to adopt. They dont have a reasoned answer to this, they will by and large defer to authority. -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On 14 dec, 09:56, Jussi Piitulainen wrote: > Steven D'Aprano writes: > > On Mon, 12 Dec 2011 09:29:11 -0800, Eelco wrote: > > > [quoting Jussi Piitulainen ] > > >> They recognize modular arithmetic but for some reason insist that > > >> there is no such _binary operation_. But as I said, I don't > > >> understand their concern. (Except the related concern about some > > >> programming languages, not Python, where the remainder does not > > >> behave well with respect to division.) > > > I've never come across this, and frankly I find it implausible that > > *actual* mathematicians would say that. Likely you are > > misunderstanding a technical argument about remainder being a > > relation rather than a bijunction. The argument would go something > > like this: > > (For 'bijunction', read 'function'.) > > I'm not misunderstanding any argument. There was no argument. There > was a blanket pronouncement that _in mathematics_ mod is not a binary > operator. I should learn to challenge such pronouncements and ask what > the problem is. Maybe next time. > > But you are right that I don't know how actual mathematicians these > people are. I'm not a mathematician. I don't know where to draw the > line. > > A Finnish actual mathematician stated a similar prejudice towards mod > as a binary operator in a Finnish group. I asked him what is wrong > with Knuth's definition (remainder after flooring division), and I > think he conceded that it's not wrong. Number theorists just choose to > work with congruence relations. I have no problem with that. > > He had experience with students who confused congruences modulo some > modulus with a binary operation, and mixed up their notations because > of that. That is a reason to be suspicious, but it is a confusion on > the part of the students. Graham, Knuth, Patashnik contrast the two > concepts explicitly, no confusion there. > > And I know that there are many ways to define division and remainder > so that x div y + x rem y = x. Boute's paper cited in [1] advocates a > different one and discusses others. > > [1] <http://en.wikipedia.org/wiki/Modulo_operation> > > But I think the argument "there are several such functions, therefore, > _in mathematics_, there is no such function" is its own caricature. Indeed. Obtaining a well defined function is just a matter of picking a convention and sticking with it. Arguably, the most elegant thing to do is to define integer division and remainder as a single operation; which is not only the logical thing to do mathematically, but might work really well programmatically too. The semantics of python dont really allow for this though. One could have: d, r = a // b But it wouldnt work that well in composite expressions; selecting the right tuple index would be messy and a more verbose form would be preferred. However, performance-wise its also clearly the best solution, as one often needs both output arguments and computing them simultaniously is most efficient. At least numpy should have something like: d, r = np.integer_division(a, b) And something similar in the math module for scalars. > > "Remainder is not uniquely defined. For example, the division of -42 > > by -5 can be written as either: > > > 9*-5 + 3 = -42 > > 8*-5 + -2 = -42 > > > so the remainder is either 3 or -2. Hence remainder is not a bijection > > (1:1 function)." > > Is someone saying that _division_ is not defined because -42 div -5 is > somehow both 9 and 8? Hm, yes, I see that someone might. The two > operations, div and rem, need to be defined together. > > (There is no way to make remainder a bijection. You mean it is not a > function if it is looked at in a particular way.) Surjection is the word you are looking for That is, if one buys the philosophy of modernists like bourbaki in believing there is much to be gained by such pedantry. -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On 14 dec, 12:55, Arnaud Delobelle wrote: > On 14 December 2011 07:49, Eelco wrote: > > On Dec 14, 4:18 am, Steven D'Aprano > +comp.lang.pyt...@pearwood.info> wrote: > >> > They might not be willing to define it, but as soon as we programmers > >> > do, well, we did. > > >> > Having studied the contemporary philosophy of mathematics, their concern > >> > is probably that in their minds, mathematics is whatever some dead guy > >> > said it was, and they dont know of any dead guy ever talking about a > >> > modulus operation, so therefore it 'does not exist'. > > >> You've studied the contemporary philosophy of mathematics huh? > > >> How about studying some actual mathematics before making such absurd > >> pronouncements on the psychology of mathematicians? > > > The philosophy was just a sidehobby to the study of actual > > mathematics; and you are right, studying their works is the best way > > to get to know them. Speaking from that vantage point, I can say with > > certainty that the vast majority of mathematicians do not have a > > coherent philosophy, and they adhere to some loosely defined form of > > platonism. Indeed that is absurd in a way. Even though you may trust > > these people to be perfectly functioning deduction machines, you > > really shouldnt expect them to give sensible answers to the question > > of which are sensible axioms to adopt. They dont have a reasoned > > answer to this, they will by and large defer to authority. > > Please come down from your vantage point for a few moments and > consider how insulting your remarks are to people who have devoted > most of their intellectual energy to the study of mathematics. So > you've studied a bit of mathematics and a bit of philosophy? Good > start, keep working at it. Thanks, I intend to. > You think that every mathematician should be preoccupied with what > axioms to adopt, and why? Of course I dont. If you wish to restrict your attention to the exploration of the consequences of axioms others throw at you, that is a perfectly fine specialization. Most mathematicians do exactly that, and thats fine. But that puts them in about as ill a position to judged what is, or shouldnt be defined, as the average plumber. Compounding the problem is not just that they do not wish to concern themselves with the inductive aspect of mathematics, they would like to pretend it does not exist at all. For instance, if you point out to them a 19th century mathematician used very different axioms than a 20th century one, (and point out they were both fine mathematicians that attained results universally celebrated), they will typically respond emotionally; get angry or at least annoyed. According to their pseudo-Platonist philosophy, mathematics should not have an inductive side, axioms are set in stone and not a human affair, and the way they answer the question as to where knowledge about the 'correct' mathematical axioms comes from is by an implicit or explicit appeal to authority. They dont explain how it is that they can see 'beyond the platonic cave' to find the 'real underlying truth', they quietly assume somebody else has figured it out in the past, and leave it at that. > You say that mathematicians defer to authority, but do you really > think that thousands of years of evolution and refinement in > mathematics are to be discarded lightly? I think not. It's good to > have original ideas, to pursue them and to believe in them, but it > would be foolish to think that they are superior to knowledge which > has been accumulated over so many generations. For what its worth; insofar as my views can be pidgeonholed, im with the classicists (pre-20th century), which indeed has a long history. Modernists in turn discard large swaths of that. Note that its largely an academic debate though; everybody agrees that 1+1=2. But there are some practical consequences; if I were the designated science-Tsar, all transfinite-analysist would be out on the street together with the homeopaths, for instance. > You claim that mathematicians have a poor understanding of philosophy. > It may be so for many of them, but how is this a problem? I doesn't > prevent them from having a deep understanding of their field of > mathematics. Do philosophers have a good understanding of > mathematics? As a rule of thumb: absolutely not, no. I dont think I can think of any philosopher who turned his attention to mathematics that ever wrote anything interesting. All the interesting writers had their boots on mathematical ground; Quine, Brouwer, Weyl and the earlier renaissance men like Gauss and contemporaries. The fragmentation of disciplines is infact a major p
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On 14 dec, 13:22, Jussi Piitulainen wrote: > > > Is someone saying that _division_ is not defined because -42 div > > > -5 is somehow both 9 and 8? Hm, yes, I see that someone might. The > > > two operations, div and rem, need to be defined together. > > > > (There is no way to make remainder a bijection. You mean it is not > > > a function if it is looked at in a particular way.) > > > Surjection is the word you are looking for > > Um, no, I mean function. The allegedly alleged problem is that there > may be two (or more) different values for f(x,y), which makes f not a > _function_ (and the notation f(x,y) maybe inappropriate). > > Surjectivity is as much beside the point as bijectivity, but I think > we have surjectivity for rem: Z * Z -> Z if we use a definition that > produces both positive and negative remainders, or rem: Z * Z -> N if > we have non-negative remainders (and include 0 in N, which is another > bone of contention). We may or may not want to exclude 0 as the > modulus, or divisor if you like. It is at least a special case. > > It's injectivity that fails: 9 % 4 == 6 % 5 == 3 % 2, while Python > quite sensibly has (9, 4) != (6, 5) != (3, 2). (How I love the > chaining of the comparisons.) My reply was more to the statement you quoted than to yours; sorry for the confusion. Yes, we have surjectivity and not injectivity, thats all I was trying to say. > > That is, if one buys the philosophy of modernists like bourbaki in > > believing there is much to be gained by such pedantry. > > I think something is gained. Not sure I would call it philosophy. Agreed; its more the notion that one stands to gain much real knowledge by writing volumnius books about these matters that irks me, but I guess thats more a matter of taste than philosophy. -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On Dec 14, 1:38 pm, Steven D'Aprano wrote: > On Wed, 14 Dec 2011 02:09:32 -0800, Eelco wrote: > > Arguably, the most elegant thing to do is to define integer division and > > remainder as a single operation; which is not only the logical thing to > > do mathematically, but might work really well programmatically too. > > > The semantics of python dont really allow for this though. One could > > have: > > > d, r = a // b > > That would be: > > >>> divmod(17, 5) > > (3, 2) Cool; if only it were in the math module id be totally happy. > > But it wouldnt work that well in composite expressions; selecting the > > right tuple index would be messy and a more verbose form would be > > preferred. However, performance-wise its also clearly the best solution, > > as one often needs both output arguments and computing them > > simultaniously is most efficient. > > Premature optimization. We are talking language design here, not language use. Whether or not this is premature is a decision that should be left to the user, if at all possible, which in this case it very well is; just provide multiple functions to cover all use cases (only return divisor, only return remainder, or both) -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
'Kindof' off-topic, but what the hell :). On Dec 14, 5:13 pm, Arnaud Delobelle wrote: > On 14 December 2011 12:33, Eelco wrote: > > On 14 dec, 12:55, Arnaud Delobelle wrote: > >> On 14 December 2011 07:49, Eelco wrote: > >> > On Dec 14, 4:18 am, Steven D'Aprano >> > +comp.lang.pyt...@pearwood.info> wrote: > >> >> > They might not be willing to define it, but as soon as we programmers > >> >> > do, well, we did. > > >> >> > Having studied the contemporary philosophy of mathematics, their > >> >> > concern > >> >> > is probably that in their minds, mathematics is whatever some dead guy > >> >> > said it was, and they dont know of any dead guy ever talking about a > >> >> > modulus operation, so therefore it 'does not exist'. > > >> >> You've studied the contemporary philosophy of mathematics huh? > > >> >> How about studying some actual mathematics before making such absurd > >> >> pronouncements on the psychology of mathematicians? > > >> > The philosophy was just a sidehobby to the study of actual > >> > mathematics; and you are right, studying their works is the best way > >> > to get to know them. Speaking from that vantage point, I can say with > >> > certainty that the vast majority of mathematicians do not have a > >> > coherent philosophy, and they adhere to some loosely defined form of > >> > platonism. Indeed that is absurd in a way. Even though you may trust > >> > these people to be perfectly functioning deduction machines, you > >> > really shouldnt expect them to give sensible answers to the question > >> > of which are sensible axioms to adopt. They dont have a reasoned > >> > answer to this, they will by and large defer to authority. > > >> Please come down from your vantage point for a few moments and > >> consider how insulting your remarks are to people who have devoted > >> most of their intellectual energy to the study of mathematics. So > >> you've studied a bit of mathematics and a bit of philosophy? Good > >> start, keep working at it. > > > Thanks, I intend to. > > >> You think that every mathematician should be preoccupied with what > >> axioms to adopt, and why? > > > Of course I dont. If you wish to restrict your attention to the > > exploration of the consequences of axioms others throw at you, that is > > a perfectly fine specialization. Most mathematicians do exactly that, > > and thats fine. But that puts them in about as ill a position to > > judged what is, or shouldnt be defined, as the average plumber. > > You are completely mistaken. Whatever the axiomatisation of the > mathematics that we do, we can still do the same mathematics. We > don't even need an axiomatic basis to do mathematics. In fact, the > formalisation of mathematics has always come after the mathematics > were well established. Euclid, Dedekind, Peano, Zermelo, Frankael, > didn't create axiomatic systems out of nothing. They axiomatised > pre-existing theories. > > Axiomatising a theory is just one way of exploring it. Yes, axiomization is to some extent a side-show. We know what it is that we want mathematics to be, and we try to find the axioms that lead to those conclusions. Not qualitatively different from any other form of induction (of the epistemological rather than mathematical kind). Still, different axioms or meta-mathematics give subtly different results, not to mention are as different to work with as assembler and haskell. There are no alephs if you start from a constructive basis, for instance. Im not sure what 'Axiomatising a theory is just one way of exploring it' means. One does not axiomatize a single theory; that would be trivial (A is true because thats what I define A to be). One constructs a single set of axioms from which a nontrivial set of theorems follow. The way id put it, is that axiomazation is about being explicit in what it is that you assume, trying to minimalize that, and being systematic about what conclusions that forces you to embrace. Could you be more precise as to how I am 'completely mistaken'? I acknowledge that my views are outside the mainstream, so its no news to me many would think so, but it would be nice to know what im arguing against in this thread precisely. > > Compounding the problem is not just that they do not wish to concern > > themselves with the inductive aspect of mathematics, they would like > > to pretend it does not exist at all. For instance, if you point out to
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On Dec 15, 4:43 am, rusi wrote: > On Dec 14, 10:15 pm, Eelco wrote: > > > 'Kindof' off-topic, but what the hell :). > > > We keep having these debates -- so I wonder how off-topic it is... > And so do famous > CSists:http://research.microsoft.com/en-us/um/people/gurevich/opera/123.pdf > Well, you are right, there are some deep links here. My view of what is wrong with mainstream mathematics is its strange interpretation of the semantics of classical logic. (And I dont think any other schools get it quite right either; I think finitists may avoid the mistakes of others, but are rightfully accussed of being needlessly restrictive, for instance) This is best illustrated by means of the principle of explosion. It rests on assuming a contradiction, and then assigning rather peculiar semantics to them. What is typically left unstated are the semantics of symbol lookup, but apparently it is implicitly understood one can pick whatever value upon encountering a contradicting symbol. There is no well defined rule for the lookup of a twice-defined symbol. Of course the sane thing to do, to a mind grown up around computer languages, upon encountering a twice defined symbol, is not to continue to generate deductions from both branches, but to throw an exception and interrupt the specific line of reasoning that depends on this contradicting symbol right then and there. Conceptually, we can see something is wrong with these undefined semantics right away. A logical system that allows you to draw conclusions as to where the pope shits from assertions about natural numbers could not more obviously be broken. If you dont have this broken way of dealing with contradictions, one does not have to do one of many silly and arbitrary things to make infinity work, such as making a choice between one-to-one correspondence and subset-relations for determining the cardinality of a set; one can simply admit the concept of infinity, while useful, is not consistent, keep the contradiction well handled instead of having it explode in your face (or explode into the field of transfinite analysis; a consequece of 'dealing' with these issues by rejecting the intuitively obviously true relation between subset relations and cardinality), and continue reasoning with the branches of your argument that you are interested in. In other words, what logic needs is a better exception-handling system, which completes the circle with programming languages quite nicely. :) -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On Dec 15, 11:47 am, Robert Kern wrote: > On 12/14/11 12:32 PM, Steven D'Aprano wrote: > > > On Wed, 14 Dec 2011 10:56:02 +0200, Jussi Piitulainen wrote: > >> I'm not misunderstanding any argument. There was no argument. There was > >> a blanket pronouncement that _in mathematics_ mod is not a binary > >> operator. I should learn to challenge such pronouncements and ask what > >> the problem is. Maybe next time. > > > So this was *one* person making that claim? > > > I understand that, in general, mathematicians don't have much need for a > > remainder function in the same way programmers do -- modulo arithmetic is > > far more important. But there's a world of difference between saying "In > > mathematics, extracting the remainder is not important enough to be given > > a special symbol and treated as an operator" and saying "remainder is not > > a binary operator". The first is reasonable; the second is not. > > The professional mathematicians that I know personally don't say that > "remainder > is not a binary operator". They *do* say that "modulo is not an operator" in > mathematics just because they have reserved that word and the corresponding > notation to define the congruence relations. So for example, the following two > statements are equivalent: > > 42 = 2 mod 5 > 2 = 42 mod 5 > > The "mod 5" notation modifies the entire equation (or perhaps the = sign if > you > like to think about it like that), not the term it is immediately next to. > Python's % operator is a binary operator that binds to a particular term, not > the whole equation. The following two are not equivalent statements: > > 42 == 2 % 5 > 2 == 42 % 5 > > It's mostly kvetching on their part that programming language designers > misunderstood the notation and applied the name to something that is > confusingly > almost, but not quite, the same thing. They aren't saying that you couldn't > *define* such an operator; they would just prefer that we didn't abuse the > name. > But really, it's their fault for using notation that looks like an operator. > > -- > Robert Kern > > "I have come to believe that the whole world is an enigma, a harmless enigma > that is made terrible by our own mad attempt to interpret it as though it > had > an underlying truth." > -- Umberto Eco Thanks Robert, I think you cut right through the confusion there. To tie it back in with python language design; all the more reason not to opt for pseudo-backwards compatibility. If python wants a remainder function, call it 'remainder'. Not 'rem', not 'mod', and certainly not '%'. Its the more pythonic way; a self-describing name, rather than poorly defined or poorly understood cryptology. -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On Dec 15, 11:56 am, rusi wrote: > On Dec 15, 2:44 pm, Eelco wrote: > > > In other words, what logic needs is a better exception-handling > > system, which completes the circle with programming languages quite > > nicely. :) > > Cute... but dangerously recursive (if taken literally) > Remember that logic is the foundation of programming language > semantics. > And your idea (suggests) that programming language semantics be made > (part of) the foundation of logic. > > Of course I assume you are not being very literal. > Still the dangers of unnoticed circularity are often... well > unnoticed :-) Well, logic as a language has semantics, one way or the other. This circularity is a general theme in epistemology, and one that fits well with the view of deduction-induction as a closed loop cycle. Knowledge does not flow from axioms to theorems; axioms without an encompassing context are meaningless symbols. Its a body of knowledge as a whole that should be put to the test; the language and the things we express in it are inseperable. (the not-quite-famous-enough Quine in a nutshell) The thing is that our semantics of logic are quite primitive; cooked up in a time where people spent far less time thinking about these things, and having a far narrower base of experience to draw ideas from. They didnt have the luxury of already having grown up studying a dozen formal languages before embarking on creating their own. It other words, the semantics of logic is a legacy piece of crap, but an insanely firmly entrenched one. I mean, there are many sensible ways of defining semantics of conflicting symbols, but you'll find on studying these things that the guys who (often implicitly) laid down these rules didnt even seemed to have consciously thought about them. Not because they were stupid; far from it, but for similar reasons as to why the x86 architecture wasnt concieved of the day after the invention of the transistor. -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On Dec 16, 3:58 am, MRAB wrote: > On 16/12/2011 02:14, alex23 wrote: > > > Eelco wrote: > >> To tie it back in with python language design; all the more reason > >> not to opt for pseudo-backwards compatibility. If python wants a > >> remainder function, call it 'remainder'. Not 'rem', not 'mod', and > >> certainly not '%'. > > Python has "def", "del", "int", "str", "len", and so on. "rem" or "mod" > (Ada has both, I believe) would be in keeping with the language. def and del are keywords, and thus in another league. Having shorthand notation for types is somewhat defensible, though I believe I would prefer a more verbose form there too; how often to you encounter these in python anyway? len is a bit of an eeysore to me too; I understand having it as a builtin is a matter of optimization or something, but I do wish we would be given the option of just saying list.length > > Good luck with the PEP. > > >> Its the more pythonic way; a self-describing name, rather than > >> poorly defined or poorly understood cryptology. > > > "Although practicality beats purity." > > > I'm still utterly agog that anyone finds the operator % confusing. > > In financial circles it could be an operator for calculating > percentages, eg. "5 % x" would be 5 percent of x. > > It's an oddity, but an established one. :-) Well yes, thats the only argument ive heard so far that resonated with me. These syntax details are not a very big deal, and backwards compatibility with yourself is quite a big deal. Its nice to keep 'what ought to have been done' and 'what ought we to do' seperate in such discussions. Im not sure we ought to change these syntax details (I mean relating to mod and such), but I am quite sure of what I would have done if I could go back in time. -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On Dec 16, 6:30 am, alex23 wrote: > On Dec 16, 3:01 pm, Chris Angelico wrote: > > > And I would be most sorry to see % renamed to mod in Python. > > > "Hello, %s! My favourite number is %d." mod ("Fred",42) # This just > > looks wrong. > > Finally we can give this operator a more fitting name - I propose > 'inject' - and put an end to this insane desire to leverage off pre- > existing knowledge of other languages. > > Furthermore, I suggest that no two languages should ever have > identical semantics, just to avoid potential confusion. > > New concepts for all! Dont get me started on that one. Its that I never work with strings... 'leverage of pre-existing knowledge'... I would hardly call the particular names of functions the knowledge about a language. The only argument that bears any weight with me is backwards compatibility with itself. Pseudo-backwards compatibility with other languages, I couldnt not care less for. -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On 16 dec, 18:38, rusi wrote: > On Dec 16, 3:25 pm, Eelco wrote: > > > Pseudo-backwards compatibility with other > > languages, I couldnt not care less for. > > Double negations n Goedelian situations have interesting implications > (tho here its triple) Heh. Well at least my extra (unintended) negation is semantically consistent with the actual english usage of the phrase, which omits the negation completely :). (I could care less) But ill stick with trying to change one language at a time :). -- http://mail.python.org/mailman/listinfo/python-list
Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]
On Dec 17, 12:49 am, Gregory Ewing wrote: > Eelco wrote: > > the actual english usage of the phrase, which omits > > the negation completely :). (I could care less) > > No, that's the American usage. The English usage is > "I couldn't care less", which has the advantage of > actually making sense. > > -- > Greg Oh thanks for clearing that up, never noticed a division along these lines. And yes, I agree; 'I couldnt care less' makes much more sense. 'I could care less' can only make sense if you interpret it sarcastically, as if omitting an 'oh wait, I cant', but that does not seem congruent with how its typically pronounced. Just another case of suboptimal language design; but where can you submit EEP's? -- http://mail.python.org/mailman/listinfo/python-list
Pythonification of the asterisk-based collection packing/unpacking syntax
This is a follow-up discussion on my earlier PEP-suggestion. Ive integrated the insights collected during the previous discussion, and tried to regroup my arguments for a second round of feedback. Thanks to everybody who gave useful feedback the last time. PEP Proposal: Pythonification of the asterisk-based collection packing/ unpacking syntax. This proposal intends to expand upon the currently existing collection packing and unpacking syntax. Thereby we mean the following related python constructs: head, *tail = somesequence #pack the remainder of the unpacking of somesequence into a list called tail def foo(*args): pass #pack the unbound positional arguments into a tuple calls args def foo(**kwargs): pass #pack the unbound keyword arguments into a dict calls kwargs foo(*args) #unpack the sequence args into positional arguments foo(**kwargs) #unpack the mapping kwargs into keyword arguments We suggest that these constructs have the following shortcomings that could be remedied. It is unnecessarily cryptic, and out of line with Pythons preference for an explicit syntax. One can not state in a single line what the asterisk operator does; this is highly context dependent, and is devoid of that ‘for line in file’ pythonic obviousness. From the perspective of a Python outsider, the only hint as to what *args means is by loose analogy with the C-way of handling variable arguments. The current syntax, in its terseness, leaves to be desired in terms of flexibility. While a tuple might be the logical choice to pack positional arguments in the vast majority of cases, it need not be true that a list is always the preferred choice to repack an unpacked sequence, for instance. 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. 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. This changes the semantics from normal unpacking, to unpacking and then repacking all but the head into a list. It may be somewhat counter-intuitive to think of this as a type constraint, since python is after all a weakly-typed language. But the current usage of askeriskes is an exception to that rule. For those who are unconvinced, please consider the analogy to the following simple C# code: var foo = 3; An ‘untyped‘ object foo is created (actually, its type will be inferred from its rhs as an integer). float foo = 3; By giving foo a type-constraint of float instead, the semantics are modified; foo is no longer the integer 3, but gets silently cast to 3.0. This is a simple example, but conceptually entirely analogous to what happens when one places an asterisk before an lvalue in Python. It means ‘be a list, and adjust your behavior accordingly’, versus ‘be a float, and adjust your behavior accordingly’. 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. This concept has been considered before, but the costs have not been found to out-weight the benefits. http://www.artima.com/weblogs/viewpost.jsp?thread=86641 Our primary aim is the niche of collection packing/unpacking, but if further generalizations can be made without increasing the cost, those are most welcome. To reiterate: what is proposed is nothing radical; merely to replace the asterisk-based type constraints with a more explicit type constraint. Currently favored alternative syntax: Both for the sake of explicitness and flexibility, we consider it desirable that the name of the collection type is used directly in any collection packing statement. Annotating a variable declaration with a collection type name should signal collection packing. This association between a collection type name and a variable declaration can be accomplished in many ways; for now, we suggest collectionname::collectiontype for packing, and ::collectionname for unpacking. Examples of use: head, tail::tuple = ::sequence def foo(args::list, kwargs::dict): pass foo(::args, ::kwargs) The central idea is to replace annotations with asteriskes by annotations with collection type names, but note that we have opted for several other minor alterations of the existing syntax that seem natural given the proposed changes. First of all, explicitly mentioning the type of the collection involved eliminates the need to have two symbols, * and **. Which variable captures the positional arguments and which captures the keyword arguments can be inferred from the collection type they model, mapping or sequence. The rare case of collections that both model a sequence and a mapping can either be excluded or handled by assigning precedence
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 17, 6:18 pm, Chris Angelico wrote: > On Sun, Dec 18, 2011 at 4:14 AM, Roy Smith wrote: > > Import wildcarding? > > That's not an operator, any more than it is when used in filename > globbing. The asterisk _character_ has many meanings beyond those of > the operators * and **. > > ChrisA To cut short this line of discussion; I meant the asterisk symbol purely in the context of collection packing/unpacking. Of course it has other uses too. Even that single use requires a whole paragraph to explain completely; when does it result in a tuple or a list, when is unpacking implicit and when not, why * versus **, and so on. -- 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 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 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 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
On 18 dec, 18:03, Steven D'Aprano 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 Dec 19, 3:23 am, alex23 wrote: > Evan Driscoll 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 wrote: > On Dec 17, 11:33 pm, Evan Driscoll 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: Python education survey
I taught a Python class just recently, and thought long and hard about this problem. I settled on PyCharm and was happy with that. My reasons: - available on all main platoforms - not entirely broken code completion (ive tried literally every python editor, and pycharm is the only one that meets this requirement on all platforms. Try import numpy; numpy.array. 90% of editors with 'code completion' will fail that simple benchmark. The only thing worse than no completion list is an incomplete list of completions. Only pyscripter is better in this regard, but win-only.) - easy installation - integrated console - integrated debugger - free (for classroom use) - fairly uncluttered > I recently started using PyCharm personally, but not for my courses. > There's a free OSS developers licence and it's a really nice (although > young and somewhat resource hungry) IDE, but you can't really advocate a > non-free IDE for teaching. "Buy me as a teacher, and, BTW, buy this IDE for > everyone as well or I won't teach you"? Doesn't quite work. PyCharm provides a free 1 year classroom license. > For teaching, I think it's better to come around with something simpler > than a full-blown IDE, so that you can show off interactive development, > help() and other introspection features. IMHO much better than hiding all > that behind an IDE, especially behind the additional complexity of an IDE. > IPython is much better suited to present an interactive language like Python. PyCharm has an integrated interpreter (a wrapper around Ipython that superimposes the pycharm based code completion stuff). Plus, it does not start by default into a clutter-overload mode, and if you click away a pane or two, you have a rather clean editor. Aside from worrying about your editor, worry about how to install python. As a windows user, I had scarcely imagined the nightmares of installing everything on all platforms, different OS versions, and so forth. DONT install/compile via the command line, and DO use a precompiled distro like enthought. Macosx does not come with a C compiler, and your only recourse is the 4-gig xcode download. That is, if *friggin ITunes* lets you install it, and does not silently screw up your installation. I could go on, but anyway you get the point. Unless its your own computer, anything more complex than double clicking an installer WILL GO WRONG, and spending hours debugging other peoples computers is not how you want to spend your time. -- http://mail.python.org/mailman/listinfo/python-list
Re: Need advice on the design of my application
My first suggestion would be to keep the rendering in Python, if at all feasible, and do only the actual simulation/computation in C. Rasterizing a heightfield and rigid body plus some plash effects is nothing that couldnt be done in PyOpenGL, or even something higher- level like visvis or mayavi. (visvis would be my first suggestion) I would run the simulation in a python subprocess that calls into the C dll; that should give you at least one core fully focussed on your computations, without competition/blocking from any other modules. Marshalling the simulation data between subprocesses should be a small performance hurdle relative to getting it on your GPU; either way, the python subprocessing module makes it entirely painless. And I would start with an implementation in numpy; probably, you will be doing some fft's and/or boundary element stuff. This can all be done fairly efficiently in numpy; at minimum it will give you a reference implementation, and its not unlikely it will work well enough that you dont even want to bother with the C implementation anymore. -- 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 wrote: > On Dec 19, 8:15 pm, Eelco 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 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 wrote: > Eelco 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 wrote: > On Mon, 19 Dec 2011 19:35:20 -0800, alex23 wrote: > > Eelco 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 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 Dec 24, 3:57 pm, Chris Angelico wrote: > On Sun, Dec 25, 2011 at 1:47 AM, Eelco 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 wrote: > On Sun, Dec 25, 2011 at 1:45 AM, Eelco 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 Dec 25, 2:01 am, Rick Johnson wrote: > On Dec 24, 6:24 pm, alex23 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 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, 2:12 pm, Steven D'Aprano wrote: > On Sat, 24 Dec 2011 06:39:39 -0800, Eelco wrote: > > On Dec 20, 4:30 am, alex23 wrote: > >> On Dec 19, 8:15 pm, Eelco 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 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 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 Dec 25, 5:15 pm, Steven D'Aprano 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 wrote: > On Mon, Dec 26, 2011 at 2:38 AM, Eelco 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 Dec 25, 6:05 pm, Steven D'Aprano wrote: > On Sun, 25 Dec 2011 07:38:17 -0800, Eelco wrote: > > On Dec 25, 2:12 pm, Steven D'Aprano > +comp.lang.pyt...@pearwood.info> wrote: > >> On Sat, 24 Dec 2011 06:39:39 -0800, Eelco wrote: > >> > On Dec 20, 4:30 am, alex23 wrote: > >> >> On Dec 19, 8:15 pm, Eelco 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 f
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 26, 10:01 pm, Chris Angelico wrote: > On Tue, Dec 27, 2011 at 7:39 AM, Eelco 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 wrote: > On Tue, Dec 27, 2011 at 7:58 AM, Eelco 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 Dec 26, 11:27 pm, Chris Angelico wrote: > On Tue, Dec 27, 2011 at 8:51 AM, Eelco 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 R&D, 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: Python education survey
On Dec 27, 6:59 am, Carl Smith wrote: > On Dec 20, 10:58 am, Andrea Crotti wrote: > > > > > > > > > > > On 12/20/2011 03:51 AM, Raymond Hettinger wrote: > > > > Do you use IDLE when teaching Python? > > > If not, what is the tool of choice? > > > > Students may not be experienced with the command-line and may be > > > running Windows, Linux, or Macs. Ideally, the tool or IDE will be > > > easy to install and configure (startup directory, path, associated > > > with a particular version of Python etc). > > > > Though an Emacs user myself, I've been teaching with IDLE because it's > > > free; it runs on multiple OSes, it has tooltips and code colorization > > > and easy indent/dedent/comment/uncomment commands, it has tab > > > completion; it allows easy editing at the interactive prompt; it has > > > an easy run-script command (F5); it has direct access to source code > > > (File OpenModule) and a class browser (Cntl+B). > > > > On the downside, some python distros aren't built with the requisite > > > Tcl/Tk support; some distros like the Mac OS ship with a broken Tcl/Tk > > > so users have to install a fix to that as well; and IDLE sometimes > > > just freezes for no reason. It also doesn't have an easy way to > > > specify the startup directory. > > > > If your goal is to quickly get new users up and running in Python, > > > what IDE or editor do you recommend? > > > > Raymond > > > I think ipython and a good editor gives a much nicer experience > > than IDLE, which I actually almost never used, and > > for everything else there is python and python-mode. > > > New users however can be pointed to something like PyCharm > > or Eclipse+PyDev if they are more familiar to IDEs.. > > I agree; IPython is a excellent choice. You have a much more powerful > interactive Python experience, with all the features you need from an > IDE. You can use any editor (VIM) and you can also readily hack > IPython to death. > > I think the fact that anyone with basic programming skills can > substantially enhance their console is a big winner in CS education. > It gives students something they personally value to work on, it's a > place to store all their little bits of code and actually benefit from > them in real life. > > I've never met a programmer that got familiar with IPython and then > went on to stop using it. It should be included in the standard > library and used as the default Python interactive environment. > > The last line of my .bashrc file: > > ipython3 Youve got one here. I like IPython a lot, but it quite rarely enters into my workflow. While I agree that a good interactive python console is a good way to get your feet wet with programming, I also strongly feel that a more comprehensive programming environment should be introduced to students. That includes opening and editing files, syntax highlighting, and code completion. And painless installation. There are no lightweight editors that provide all this functionality in conjuction with Ipython*. So I prefer to work the other way around; use something like pycharm, and open an IPython interactive session within it. *Your suggestion of VIM is especially objectionable. Though I am sure it is a great tool to you, the subject here is beginner education. Just because it is a good tool for you, does not make it a good tool for a beginner. IPython bundled with a lightweight but function-rich and non-hacker- but-WYSIWYG editor would be a great choice. But until that comes around, pycharm it is for me. -- 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 wrote: > On Tue, Dec 27, 2011 at 10:44 AM, Eelco 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: Python education survey
On Dec 27, 6:53 pm, Lie Ryan wrote: > On 12/27/2011 10:41 PM, Eelco wrote: > > > > > *Your suggestion of VIM is especially objectionable. Though I am sure > > it is a great tool to you, the subject here is beginner education. > > Just because it is a good tool for you, does not make it a good tool > > for a beginner. > > Before using VIM, I used to use gedit (and still do, though not as often > now); I don't think I've ever had any problem with not using a full > blown IDE with Python. I generally don't miss not using an IDE since > Python doesn't have the tradition of using overly verbose names like in > Java. As for my personal use, I very much prefer an IDE. I hate having only crappy code completion, for starters, and I like a good integrated debugger. But then again, im spoiled I suppose coming from C#. On the other hand, ive worked for many years using a very minimal notepad +command line compilation setup as well. But I can very well imagine that people are perfectly happy with more hackerish tools. That is, once they have gotten past the learning curve. > I'm personally of the opinion that beginners generally should start with > a simple programmer text editors (gedit is a good example). Firstly, you > don't want to confuse beginners with IDE vs language features; secondly, > at the size of the problem beginners typically had, they don't **need** > 95% of those features; and if you teach beginners powerful IDE features > too early, by the time their problem gets big enough that the IDE > features would actually help, they'd already forgotten about them. A good IDE should get out of your way if you want it to. I like pycharm in this regard; click an x or two, and you are facing just your text editor and console/output window. Generally, I think a non-cluttered IDE is ideal for a beginner. You dont have to explain to them how to open a file, and if you tell them to hit the 'play' button to start running their code (not a hard concept to grasp or remember either) they are good to start hacking. Also, I think code completion is a blessing to beginning programmers. IPython is good in that regard; until you switch to editing files, where your choice is between notepad, or configuring an other editor you dont want your class to spend any time on, and youll end up with something that still doesnt do much more than syntax highlighting. -- http://mail.python.org/mailman/listinfo/python-list
Re: Python education survey
On Dec 27, 9:04 pm, Rick Johnson wrote: > On Dec 27, 1:45 pm, Eelco wrote: > > > On Dec 27, 6:53 pm, Lie Ryan wrote: > > > On 12/27/2011 10:41 PM, Eelco wrote: > > > Before using VIM, I used to use gedit > > Eelco, please don't get offended, but can you (and everyone else) stop > using silly verbage like "used to", "use to", "suppose to", "hard" > when you "difficult", and "pretty" when you mean "very". I find this > verbiage to be quite ridiculous. In this case you could have simply > said... > > """Before using VIM, I USED gedit.""" > > or if you want to stress that you don't use gedit anymore you could > say... > > """ Previously i used gedit, but have since moved on to VIM.""" > > Thanks Despite the fact that you mis-attributed that quote to me, im going to be a little bit offended in the name of its actual author anyway. Thats a lot of words to waste on your linguistic preferences. Personally, I reserve the right to botch my non-native languages as much as I please. > > You > > dont have to explain to them how to open a file, and if you tell them > > to hit the 'play' button to start running their code (not a hard > > concept to grasp or remember either) they are good to start hacking. > > I always though "run" was a perfect verb for "running" code... but who > knows :) Im assuming the audience is familiar with an ipod, but not an IDE, or programming in general. To their eyes, it looks like a 'play' button; but yes, 'running' is what its called in my mind. -- 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 wrote: > On Mon, 26 Dec 2011 13:41:34 -0800, Eelco wrote: > > On Dec 25, 6:05 pm, Steven D'Aprano > +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 differe
Re: Pythonification of the asterisk-based collection packing/unpacking syntax
On Dec 28, 2:11 am, Rick Johnson wrote: > On Dec 27, 5:10 pm, Steven D'Aprano > +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 wrote: > On Wed, Dec 28, 2011 at 5:25 PM, Steven D'Aprano > > > > > > > > > > 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 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: Python education survey
On Dec 28, 2:56 am, Rick Johnson wrote: > On Dec 27, 3:44 pm, Eelco wrote: > > > Despite the fact that you mis-attributed that quote to me, im going to > > be a little bit offended in the name of its actual author anyway. > > Thats a lot of words to waste on your linguistic preferences. > > Personally, I reserve the right to botch my non-native languages as > > much as I please. > > I hope you're just joking a bit because i have little respect for > those who refuse to better themselves. If you are learning English as > a second language then you have a legitimacy excuse, but at some point > that excuse just becomes a lie. In any case, i apologize for mis- > quoting you. Yes, I was joking a bit; I learned my english primarily on programming boards, and im proud to say it rivals that of a majority of native speakers (low bar to beat, true). Furthermore, you are free to direct criticism at my writing or that of anyone else, but I must say I dont much care to hear it. A language is learned by using it, in reading, writing or speech; not by grammar nazis, or style nazis for that matter. Im here to discuss issues related to python, and anyone who manages to make himself understood is welcome to do so, as far as I am concerned. Im much more worried whether they have something interesting to contribute to the actual discussion. Not getting stuck picking nits, fighting personal feuds or getting dragged into the swamp by trolls; those are the real challenges, in my opinion. If you are insistent on bettering yourself; there is half a dozen other languages we could continue the conversation in. Your marginal gain per sentence read and written might be much larger there than in english. -- 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 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 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 Jan 3, 3:38 am, alex23 wrote: > On Dec 27 2011, 8:01 pm, Eelco 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: Python education survey
> Why do people use pretty when we already have words that carry more > specific meaning? Because they are lazy! And laziness begets > stupidity. No, that would be because they are not autistic. Most people like having a repertoire of words with subtly different meanings in their natural language, because there is a demand for this semantic richness. -- http://mail.python.org/mailman/listinfo/python-list
Re: replacing __dict__ with an OrderedDict
i havnt read every post in great detail, but it doesnt seem like your actual question has been answered, so ill give it a try. AFAIK, changing __dict__ to be an ordereddict is fundamentally impossible in python 2. __dict__ is a builtin language construct hardcoded into the C API. There is no way to mess with it. Apparently this is different in python 3, but I dont know much about that. -- http://mail.python.org/mailman/listinfo/python-list
Re: NaN, Null, and Sorting
On 13 jan, 20:04, Ethan Furman wrote: > With NaN, it is possible to get a list that will not properly sort: > > --> NaN = float('nan') > --> spam = [1, 2, NaN, 3, NaN, 4, 5, 7, NaN] > --> sorted(spam) > [1, 2, nan, 3, nan, 4, 5, 7, nan] > > I'm constructing a Null object with the semantics that if the returned > object is Null, it's actual value is unknown. > > From a purist point of view if it is unknown then comparison results > are also unknown since the actual value might be greater, lesser, or the > same as the value being compared against. > > From a practical point of view a list with Nulls scattered throughout > is a pain in the backside. > > So I am strongly leaning towards implementing the comparisons such that > Null objects are less than other objects so they will always sort together. > > Thoughts/advice/criticisms/etc? > > ~Ethan~ My suggestion would be thus: nans/nulls are unordered; sorting them is fundamentally an ill defined notion. What you want, conceptually, is a sorted list of the sortable entries, and a seperate list of the unsorted entries. Translated into code, the most pure solution would be to filter out the nanas/nulls in their own list first, and then sort the rest. If the interface demands it, you can concatenate the lists afterwards, but probably it is most convenient to keep them in seperate lists. Perhaps arbitrarily defining the ordering of nulls/nans is slightly more efficient than the above, but it should not make a big difference, and in terms of purity its no contest. -- http://mail.python.org/mailman/listinfo/python-list
Re: Splitting a file from specific column content
The grep solution is not cross-platform, and not really an answer to a question about python. The by-line iteration examples are inefficient and bad practice from a numpy/vectorization perspective. I would advice to do it the numpythonic way (untested code): breakpoints = [3, 5, 7] data = np.loadtxt('data.txt') time = data[:,0] indices = np.searchsorted(time, breakpoints) chunks = np.split(data, indices, axis=0) for i, d in enumerate(chunks): np.savetxt('data'+str(i)+'.txt', d) Not sure how it compared to the grep solution in terms of performance, but that should be quite a non-issue for 20mb of data, and its sure to blow the by-line iteration out of the water. If you want to be more efficient, you are going to have to cut the text-to-numeric parsing out of the loop, which is the vast majority of the computational load here; but if thats possible at all depends on how structured your timestamps are; there must be a really compelling performance gain to justify throwing the elegance of the np.split based solution out of the window, in my opinion. -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
Throwing an idea for a PEP out there: It strikes me that the def func(*args, **kwargs) syntax is rather unpytonic. It certainly did not have that 'for line in file' pythonic obviousness for me as a beginner. Plus, asterikses are impossible to google for, so finding out what exactly they do more or less forces you to write a forum post about it. A more readable form occurred to me, which also happens to be more flexible, and which I think is fully compatible with the syntax of the language: def func(parg, list(args), dict(kwargs)) Perhaps this is considered abuse of notation; dict(kwargs) already has a meaning rather different from the one we try to give it here; but then again the context (being inside a function definition) is unique and easily recognizable. An added advantage would be the possibility of using subclasses of dict and list as well; imagine how much more beautiful a lot of code would be if one could say def func(attrdict(kwargs)) Problems im still wrestling with: the same syntax could not be used when calling a function; that lack of symmetry would make things more confusing, not less. Thoughts? -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
Yes, that's just a strict keywordification of the * and ** symbols. The same argument could be made for eliminating the standard algebraic + operator and replacing it with a keyword "__add__". I don't think that's worthwhile. Well, its not quite the same in the sense that algebraic operators are essentially part of 'natural language', or at least extremely widely adopted. They have earned their own special symbols. Argument packing/unpacking is a very specific thing; a small corner of a particular programming language. However, as seen in the light of python 3 head-tail syntax, perhaps the above is not quite true, and one could argue that packing/unpacking of collections is indeed a quite general concept, deserving of its own symbols. Breaking uniformity with that use case would also be a bad thing; ideally, a verbose alternative to all occurances of collection packing/unpacking would be available. That said, a more verbose and flexible syntax would be desirable there too; as of now, the tail is always a list. I havnt read the discussions leading up to those design decisions, but that seems like a compromise to me; something like head,tuple(tail) = someiterable would be preferrable there too, id say -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
As for syntax; what about coopting/integrating with the function annotation syntax? so: def func(args: list, kwargs: attrdict) and correspondingly in the function call? a, b:tuple = someiterable? I guess a rule that interprets every function argument annotated as a subclass of list or dict as a special case would severely restrict its intended use though... -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
No more so than any other form of punctuation. Plus and minus + - may be so common that just about everyone knows it, but how about | == @ % and even . (dot)? None of these things will be obvious to newbies who have never programmed before. Oh well. Some things you just have to learn. Yes, some things you just have to learn. Nonetheless, I strongly prefer explicit logical operators over |, would much rather have 'equals' instead of ==, which is stylistic in line with 'is' and explicitly distinguishes between equality and identity comparisons. As for %; it is entirely unclear to me why that obscure operation ever got its own one-character symbol. Ill take 'mod', or even better, 'modulus' any day of the week. The dot is clearly quantitatively in another realm here. 90% of typical python code is attribute accesses. The dot is entirely unambigious and cannot be mistaken for anything else. It reads like a book. It's a judgement call as to where a language divides "cryptic punctuation line noise" and "useful short operators", and in my opinion * and ** tuple and dict unpacking fall strongly on the "useful short operators" side. Your opinion may differ, but luckily for me, the BDFL agrees with me :) I also agree that it is a value judgement as to which constructs get their own cryptic symbols and which do not, but the are some reasonable guidelines we should be able to agree upon. Obscure operations should not reserve any of the few available characters. Furthermore, the language should not just be formally consistent, but also easy to grasp at a glance, without deciphering subtle semantics of a blurb of weird characters. (some programming languages obviously disagree, but python, as far as I am allowed to speak for it, does not). And most importantly, if you cant come up with a terse syntax that does everything you want to do, the terse syntax should at best be an alternative to the verbose one. It is also misleading because args are not collected into a list, but into a tuple. In case you wanted a tuple youd write tuple(args), obviously. Exactly that added flexibility is half of my case in favor. Why shouldnt it be a list when I want it to? Worse, it suggests that one should be able to generalise to something like this: def func(parg, str(args), int(kwargs), my_func(more_args)): which is incoherent. Sorry, but I dont get this point at all. Does ** suggests one should be able to generalize to ***? The rules are the rules. The real questions, in my mind, are: 1) How useful is this added flexibility? Not insanely, but I can see it making a lot of code significantly more clean. And: 2) How fundamental is collection packing/unpacking? One can easily argue that it is indeed quite fundamental and therefore deserves its own terse symbols, I feel. However, if more flexibility is indeed deemed desirable, such terse syntax quickly gives way to a more verbose one. Can you come up with some terse symbols that will be able to express all of the below and dont make you wish you hadnt rather typed out the names? head, tuple(tail) = iterable head, list(tail) = iterable head, str(tail) = somestring head, generator(tail) = mygenerator And so on. If not, one has to admit that functionality is being sacrificed on the alter of terseness, which seems like a raw deal to me. -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
There are other means of finding information than Google. Really. This is really only a very minor point in my argument, so I dont want to put the focus on this. But really, no. Googling 'myprogramminglanguage conceptimtryingtofigureout' is my first, second and third line of defence. Yes, I could read the reference manual from top to bottom, and if I already knew about the existence of your article then im sure that would be a great help too. But the situation one finds oneself in is seeing two asterikses and not even being aware they are particular to function definitions/invocations. Im fluent in many different languages and well versed in CS concepts and jargon, but I had no idea what to search for when first trying to figure out the meaning of these symbols, and that does not happen often to me. -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
The above examples are seldom needed in Python because we have one general method to repeatedly split a sequence into head and tail. it = iter(iterable) # 'it' now represents the sequenced iterable head = next(it) # 'it' now represents the tail after removing the head In other words, next(it) encompasses all of your examples and many more. Because 'it' is mutated to represent the tail, it does not need to be rebound and therefore is not. The question in language design is never 'could we do these things before'. The answer is obvious: yes our CPUs are turing complete; we can do anything. The question is; how would we like to do them? So do you think the new head/tail unpacking features in python 3 are entirely uncalled for? I personally quite like them, but I would like them to be more general. -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
> No more, or less, explicit than the difference between "==" and "is". == may be taken to mean identity comparison; 'equals' can only mean one thing. Of course 'formally' these symbols are well defined, but so is brainf*ck Modulo is hardly an obscure operation. "What's the remainder...?" is a simple question that people learn about in primary school. So is 'how much wood would a woodchucker chuck if a woodchucker could chuck wood?'. But how often does that concept turn up in your code? > And you can blame C for the use of % instead of mod or modulo. I didnt know one of Python's design goals was backwards compatibility with C. I can't imagine what sort of Python code you have seen that you consider 90% attribute access "typical". I've just run the Python tokenizer over my startup.py file, and I get these results: Yes, that was a hyperbole; but quite an often used construct, is it not? If you can supply any function at all, what happens if I write this: You cannot; only constructors modelling a sequence or a dict, and only in that order. Is that rule clear enough? > I believe that your proposal leads to an over-generalisation "call > arbitrary functions when handling parameter lists". I hope the above clears that up. It is as much about calling functions as ** is about raising kwargs to the power of. > I don't believe you > need this added complication. If you want to your var args as a list, > call list(args) inside your function. We dont strictly 'need' any language construct. Real men use assembler, right? >/ head, tuple(tail) = iterable /> In Python 3, that is spelled: head, *tail = iterable tail = tuple(tail) Yes, I know. How is that not a lot more verbose and worse than what I have proposed in all possible ways? > head, tail = somestring[0], somestring[1:] Well yes, splendid; we can do that with lists too since the dawn of Python. What you are saying here in effect is that you think the head/tail syntax is superfluous; that youd rather see it eliminated than generalized. > head, tail = next(mygenerator), mygenerator Which again of course works, but is yet again of entirely different form than any of the above solutions, while conceptually doing the same thing. Certainly, there is room for improved elegance here? -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
On the contrary, it is a major point. You want us to change the language so you can program by Google. Sorry, aint't gonna happen. On the contrary; I believe I get to decide which points I consider important. This one, I do not. Sorry for putting it in the first paragraph. -- http://mail.python.org/mailman/listinfo/python-list
Verbose and flexible args and kwargs syntax
> On the contrary, it is a major point. Sorry, but im affraid it is up to ME to decide which point I feel are important. No, this is a minor point to me, and one that has been admirably put to rest by pointing out that spelling out the name of the symbol in google directly leads you to the information you are looking for. -- http://mail.python.org/mailman/listinfo/python-list