Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam wrote: Christopher Subich wrote: As others have mentioned, this looks too much like a list comprehension to be elegant, which also rules out () and {}... but I really do like the infix syntax. Why would it rule out ()? Generator expressions. Mind you, Py3k might want to unify generators and lists in some way anyway, freeing up (). :) You need to put a lambda express in ()'s anyways if you want to use it right away. print (lambda x,y:x+y)(1,2) Although print x+y with (x,y)(1,2) has natural grouping: the lambda itself is effectively a single token. I also like the infix style reminiscent of Python's existing comprehensions. Hell, call it a 'function comprehension' or 'expression comprehension,' and we can pretend we invented the damn thing. My choice: name = (let x,y return x+y) # easy for beginners to understand value = name(a,b) value = (let x,y return x+y)(a,b) And a zero-argument lambda is (aside from really arcane)? (let return 2)? I think the association of (lambda) to [list_comp] is a nice distinction. Maybe a {dictionary_comp} would make it a complete set. ;-) Yeah, dictionary comprehensions would be an interesting feature. :) Syntax might be a bit unwieldy, though, and I doubt they'd be used often enough to be worth implementing, but still neat. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Christopher Subich wrote: Ron Adam wrote: I think the association of (lambda) to [list_comp] is a nice distinction. Maybe a {dictionary_comp} would make it a complete set. ;-) Yeah, dictionary comprehensions would be an interesting feature. :) Syntax might be a bit unwieldy, though, and I doubt they'd be used often enough to be worth implementing, but still neat. Dict comprehensions were recently rejected: http://www.python.org/peps/pep-0274.html The reason, of course, is that dict comprehensions don't gain you much at all over the dict() constructor plus a generator expression, e.g.: dict((i, chr(65+i)) for i in range(4)) STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Steven Bethard [EMAIL PROTECTED] wrote: Christopher Subich wrote: Ron Adam wrote: I think the association of (lambda) to [list_comp] is a nice distinction. Maybe a {dictionary_comp} would make it a complete set. ;-) Yeah, dictionary comprehensions would be an interesting feature. :) Syntax might be a bit unwieldy, though, and I doubt they'd be used often enough to be worth implementing, but still neat. Dict comprehensions were recently rejected: http://www.python.org/peps/pep-0274.html The reason, of course, is that dict comprehensions don't gain you much at all over the dict() constructor plus a generator expression, e.g.: dict((i, chr(65+i)) for i in range(4)) Sure, but the same holds for list comprehensions: list(i*i for i in xrange(10)). The difference is historic I guess; list comprehensions preceded generator expressions and so they cannot be removed, at least not before 3.0. I wonder if they will/should be in the language when the constraint of backwards compatibility is lifted. IMO they should not (TIOOWTDI, uniformity among builtin data structures, not overwhelmingly more useful than set or dict comprehensions), but there's a long way till that day. George -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam wrote: Given the statement: a = None And the following are all true: a == None Okay. (a) == (None) Okay. (a) == () Whoops! a (which is None) is equal to the empty tuple (which is not None)? (None) == () Then this conceptual comparison should also be true: if (None): == if (): if (): == if: I can't really see any coherent concept here. Reinhold -- http://mail.python.org/mailman/listinfo/python-list
Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
Steven Bethard wrote: If you're really afraid of two lines, write it as: def r(): randint(1, 100) This is definitely a bad case for an anonymous function because it's not anonymous! You give it a name, r. This is something I've never understood. Why is it bad form to assign an anonymous function (an object) to a name? It isn't just that lambda _can_ create functions that aren't bound to any name. That I get. But why is it suppose to be wrong to bind such a function to a name? Sure, if the lambda is so complicated that it becomes unreadable, the usage case is wrong and a def should be used instead. But I see nothing wrong with doing this: func = lambda x: x**3 - 3*x**2 Why is it considered abuse of lambda to assign the functions to a name? Is it an abuse of lambda to do this? D = {one: lambda noun: noun, two: lambda noun: noun + 's', many: lambda noun: 'lots of ' + noun + 's' } assert D[two](python) == pythons -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
Steven D'Aprano wrote: This is something I've never understood. Why is it bad form to assign an anonymous function (an object) to a name? Because it obfuscates your code for no benefit. You should avoid making it hard for others to read your code (and 'others' includes yourself in the future). Also, it obfuscates tracebacks: all lambda expressions will identify in tracebacks as lambda, but if you define a function you can give it a meaningful name. Why is it considered abuse of lambda to assign the functions to a name? Is it an abuse of lambda to do this? D = {one: lambda noun: noun, two: lambda noun: noun + 's', many: lambda noun: 'lots of ' + noun + 's' } assert D[two](python) == pythons No, that is approaching a reasonable use of lambda, however I would still be inclined to write it with functions. e.g. def one(noun): return noun def two(noun): return noun+'s' def many(noun): return 'lots of %ss' % (noun,) D = dict(one=one, two=two, many=many) although in this particular case I would probably just put format strings in the dictionary: def D(style, noun): formats = dict(one=%s, two=%ss, many=lots of %ss) return formats.get(style, an indeterminate number of %ss) % (noun,) assert D(two,python) == pythons -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Tom Anderson wrote: def flatten(ll): return reduce(lambda a, l: a.extend(l), ll, []) How would one do that as a list comp, by the way? I'm really not very good with them yet. Not really a list-comprehension based solution, but I think what you want is ll=[[1,2],[3,4,5],[6]] sum(ll,[]) [1, 2, 3, 4, 5, 6] -- Paweł Sakowski [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
On Thu, 07 Jul 2005 09:36:24 +, Duncan Booth wrote: Steven D'Aprano wrote: This is something I've never understood. Why is it bad form to assign an anonymous function (an object) to a name? Because it obfuscates your code for no benefit. You should avoid making it hard for others to read your code (and 'others' includes yourself in the future). I don't particularly think I'm that much smarter than the average programmer. In fact I *know* that I'm not that much smarter. So why do I see nothing obfuscated or obscure or difficult to understand in func = lambda x: x**3 - 5*x when apparently most of the Python community find it too complicated? Whichever is more readable in the absolute sense, the abused lambda expression above is within a gnat's whisker of the def equivalent, def func(x): return x**3 - 5*x I honestly don't understand why it is supposed to be so hard to follow. I can think of many function which should not be written with lambda, just as some things shouldn't be written as list comps. But within the limits of how much complexity you can reasonably include in a single expression, I don't see why lambda puts people off. I make it, eight mental tokens (not necessarily the same as Python tokens) for the lambda versus nine for the def. A trivial difference. In my mind, the tokens are: func, =, lambda, x, :, x**3, -, 5*x compared to: def, func, (), x, :, return, x**3, -, 5*x (Your mental parser may differ.) Also, it obfuscates tracebacks: all lambda expressions will identify in tracebacks as lambda, but if you define a function you can give it a meaningful name. Well there is that. If you have lots of lambdas assigned to names, I guess debugging could be more difficult: py f = lambda x: 1.0/x py f(0) Traceback (most recent call last): File stdin, line 1, in ? File stdin, line 1, in lambda ZeroDivisionError: float division py def f(x): ... return 1.0/x ... f(0) Traceback (most recent call last): File stdin, line 1, in ? File stdin, line 2, in f ZeroDivisionError: float division So far so good. But then: py g = f py del f py g(0) Traceback (most recent call last): File stdin, line 1, in ? File stdin, line 2, in f ZeroDivisionError: float division (but we actually got the error by calling g, not f, and in fact f no longer exists at the point we called g) Why is it considered abuse of lambda to assign the functions to a name? Is it an abuse of lambda to do this? D = {one: lambda noun: noun, two: lambda noun: noun + 's', many: lambda noun: 'lots of ' + noun + 's' } assert D[two](python) == pythons No, that is approaching a reasonable use of lambda, however I would still be inclined to write it with functions. e.g. def one(noun): return noun def two(noun): return noun+'s' def many(noun): return 'lots of %ss' % (noun,) D = dict(one=one, two=two, many=many) I find your version far more difficult to follow than mine. Psychologically, I find that defs seem to carry significant mental weight in a way that lambdas don't. Even though the lambda forms are equivalent to the def forms, I find that the defs are more heavy-weight in my conceptual map of the program than a lambda would be. Put it this way: whenever I see a two-line def as above, I can't help feeling that it is a waste of a def. (Somebody went to all the trouble to define a function for *that*?) Yet I would never think the same about a lambda -- lambdas just feel like they should be light-weight. Am I just weird? -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
=?ISO-8859-2?Q?Pawe=B3?= Sakowski [EMAIL PROTECTED] wrote: ll=[[1,2],[3,4,5],[6]] sum(ll,[]) [1, 2, 3, 4, 5, 6] That's a great argument for list.__add__ having the semantics of extend rather than append 8-) -- \S -- [EMAIL PROTECTED] -- http://www.chaos.org.uk/~sion/ ___ | Frankly I have no feelings towards penguins one way or the other \X/ |-- Arthur C. Clarke her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Reinhold Birkenfeld wrote: Ron Adam wrote: Given the statement: a = None And the following are all true: a == None Okay. (a) == (None) Okay. (a) == () Whoops! a (which is None) is equal to the empty tuple (which is not None)? It's not an empty tuple, it's an empty parenthesis. Using tuples it would be. (a,) == (,) which would be the same as: (,) == (,) (None) == () Then this conceptual comparison should also be true: if (None): == if (): if (): == if: I can't really see any coherent concept here. Reinhold It would work out that. if: == if: Does that help? Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
On 7 Jul 2005 15:46:23 GMT, Duncan Booth [EMAIL PROTECTED] wrote: Steven D'Aprano wrote: Put it this way: whenever I see a two-line def as above, I can't help feeling that it is a waste of a def. (Somebody went to all the trouble to define a function for *that*?) Yet I would never think the same about a lambda -- lambdas just feel like they should be light-weight. Obviously we think differently there. I don't see why lambdas are any different than single expression functions. I certainly don't think of them as lighter weight; they take just as long to call; and they involve just as much stack setup/tear down. On the other hand I don't consider functions as heavyweight, I'm happy to define short helper functions anywhere I think it makes the code more expressive. Am I just weird? No, just different[*]. There's nothing wrong with different. [*] conclusion based entirely on your postings here. I have no evidence beyond that. I think def is a form of assignment, with the target binding name specified inside the expression syntax instead of to the left of an '=' as usual. I.e., def f(args): suite is like f = def(args): suite except that I can't use an arbitrary left-hand side in the assignment, such as MyClass.method = def(self, args): suite or somedict['foo'] = def(self, args): suite Personally, I think def(args): suite ought to be allowed as an expression that you could put in parentheses like any other expression if you need/want to write it with multiple lines. Obviously this could both replace and expand the functionality of lambda ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list
Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
Steven D'Aprano wrote: On Thu, 07 Jul 2005 09:36:24 +, Duncan Booth wrote: Steven D'Aprano wrote: This is something I've never understood. Why is it bad form to assign an anonymous function (an object) to a name? Because it obfuscates your code for no benefit. You should avoid making it hard for others to read your code (and 'others' includes yourself in the future). Use a descriptive name like this? def get_the_cube_of_x_and_then_subtract_five_multiplied_by_x(x): x**3 - 5*x I think I like the lambda version here. ;-) It would probably have a name which refers to the context in which it's used, but sometimes the math expression it self is also the most readable. Put it this way: whenever I see a two-line def as above, I can't help feeling that it is a waste of a def. (Somebody went to all the trouble to define a function for *that*?) Yet I would never think the same about a lambda -- lambdas just feel like they should be light-weight. In the case of an interface module you might have a lot of two like def's that simply change the name and argument format so several modules can use it and have a standard consistent or simplified interface. The lambda may be perfectly fine for that. But why not use def? func_x = lambda x: (someother_func_x(x,'value')) def func_x(x): return someother_func_x(x,'value') There's both nearly identical, but the def is understandable to beginners and advanced python programs. Cheers, Ron Am I just weird? Aren't we all? ;-) -- http://mail.python.org/mailman/listinfo/python-list
Re: Deleting variables [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
On Thu, 7 Jul 2005, Steven D'Aprano wrote: On Wed, 06 Jul 2005 14:28:55 +0100, Tom Anderson wrote: del - delete How about just getting rid of del? Removal from collections could be done with a method call, Which would be called object.del() I presume. That would be fine. And that opens a big can of worms. Suppose we have a list L = [4, 3, 2, 1, 0], what should L.del(1) do? Delete the item at index 1, just as del L[1] would. It looks like it should result in L becoming [4, 3, 2, 0]. Why? I guess if you hadn't read the documentation and were just calling methods at random, you might, but i can't think of any other case. An easy mistake to make, if you forget that the argument is (presumably) an index. Not the kind of thing people tend to forget! There is the problem that people might get del and remove mixed up; i didn't actually realise there was a remove method on lists until i looked just now. You could make it clear by insisting on L.del[1] but that requires a big change in Python's syntax. It would, so i wouldn't dream of insisting on it. What should L.del() do, with no arguments? Raise an error? Er, exactly the same as calling any other method with a wrong-length argument list - a TypeError, i should think. Now, you have something like this: class thing: pass obj = thing() obj.alpha = [4, 3, 2, 1, 0] obj.beta = 5 Python's object model suggests that obj.alpha.del() should call alpha's del method, in the same way that obj.alpha.append() would call alpha's append method. Exactly so. So how do you delete obj.alpha? obj.del(alpha) might work. But what if obj itself is a mapping, with a key alpha as well as an attribute alpha. Which one should obj.del(alpha) delete? I don't think objects should have a del method by default. I'd suggest a delattr or removeattr builtin, working along the lines of getattr and setattr, for this task. Now, if you said that L.del() should raise an exception earlier, what about obj.beta.del()? Unless int has a del method, that would be an exception - an AttributeError, to be precise. Presumably every object automatically has a del method, I'd say no, but for the sake of argument, let's say it does. so you don't have to program a del method yourself. obj.del is a method object. So it has a del method. (Yes, sometimes you want to delete methods. Functions are first class objects in Python.) Which has a del method. Which has a del method. Right. What should obj.del.del.del.del.del.del.del.del.del() do? Raise a TypeError, since you haven't passed any parameters. As for obj.del.del.del.del.del.del.del.del.del(del), that's an interesting one - it comes down to the question of whether those del methods are the same object or not. I'd say not: for two objects a and b of the same class, a.foo and b.foo are considered different objects in python, and that applies here. and i'm not convinced that deleting variables is something we really need to be able to do (most other languages manage without it). Most other languages don't have namespaces that can get polluted, or on-the-fly creation of variables. Most other languages don't consider variables to be simply attributes of a module object. How much is that really used? And how many of those cases wouldn't be covered by a delattr builtin? And most other languages don't allow you to run interactive sessions where it is easy to mistakenly make variables you don't want. py x = 1 py u = x+2 # oops, typo, meant y not u py del u # prevent confusion in the programmer's mind It is also useful sometimes to delete a module object from the top level namespace before re-importing it, rather than merely reloading it. That requires being able to delete a variable. That's a very strong use case. However, it would be straightforward to make variable deletion an interpreter thing rather than a language thing. In summary: del being a keyword works. del() being an object method is unclear, confusing and complicated. Only if you give it the bizarre semantics you use above! I think having del as a keyword is actually unhelpful, since it's overloaded to do two quite different things - remove items from lists and dicts, and expunge attributes from namespaces. Far better to do let lists and dicts expose methods to let themselves be manipulated, and to play with attributes through a uniform troika of {get, set, del}attr builtins. tom -- They travel the world in their ice cream van ... -- http://mail.python.org/mailman/listinfo/python-list
Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
Am I just weird? I feel the same way about where to use lambda's and where *not* I come from C and C++ background and defining a function at the top level (no nested functions) would always require good reasons function name has to be remembered, to put it in other words it has to be added in a mental list of available function and writing a 2 liner function would only cause call overhead (if not inlined) this may be the reason why def feels to me to have more weight as lambda usually you define lambda and forget it, no wasted time to find proper name, which may also pollute the namespace I find it more clear solution, it's concise -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Wednesday 06 July 2005 09:41 am, Steven Bethard wrote: Terry Hancock wrote: And a syntax just occured to me -- what about this: [expression for argument list] If you haven't already, see: http://wiki.python.org/moin/AlternateLambdaSyntax for other similar proposals. Yeah, it's basically Robert Brewer: for (no-parens) syntax [3] isn't it (except that his eliminates the [], which is probably saner). But hey, it's surely a good thing (in the sense of being more obvious) that it occured to me independently, right? ;-) -- Terry Hancock ( hancock at anansispaceworks.com ) Anansi Spaceworks http://www.anansispaceworks.com -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Wednesday 06 July 2005 08:38 am, Tom Anderson wrote: On Wed, 6 Jul 2005, Terry Hancock wrote: With list comprehensions and generators becoming so integral, I'm not sure about unpythonic. I'm going to resist the temptation to argue that list comps are themselves unpythonic :). Ah, but GvR likes them, so that pretty much makes them pythonic by definition, doesn't it? ;-) Hang on, where's the punctuation in either of those? They *are* done with keywords! Yeah, that's true, and it could be true here too, if you throw away the []. I see that's one of the proposed alternatives. -- Terry Hancock ( hancock at anansispaceworks.com ) Anansi Spaceworks http://www.anansispaceworks.com -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
In [EMAIL PROTECTED], Ron Adam wrote: Reinhold Birkenfeld wrote: Ron Adam wrote: (a) == () Whoops! a (which is None) is equal to the empty tuple (which is not None)? It's not an empty tuple, it's an empty parenthesis. Using tuples it would be. But empty parenthesis are parsed as empty tuple:: In [8]: type( () ) Out[8]: type 'tuple' Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Terry Hancock wrote: With list comprehensions and generators becoming so integral, I'm not sure about unpythonic. And a syntax just occured to me -- what about this: [y*x for x,y] ? (that is: [expression for argument list] It's just like the beginning of a list comprehension or generator, but without the iterator. That implies that one must be given, and the result is therefore a callable object. As others have mentioned, this looks too much like a list comprehension to be elegant, which also rules out () and {}... but I really do like the infix syntax. Perhaps using angle-brackets would be useful? These have no grouping-meaning in Python that I'm aware of. Example, y*x for x,y I'd also prefer using 'with' rather than 'for' as the keyword -- 'with' doesn't suggest iteration. I also suggest parenthization of the argument list, since that makes a zero-argument lambda not look weird. To replicate the examples from http://wiki.python.org/moin/AlternateLambdaSyntax 1 lambda a, b, c:f(a) + o(b) - o(c) f(a) + o(b) - o(c) with (a, b, c) 2 lambda x: x * x x * x with (x) 3 lambda : x x with () 4 lambda *a, **k: x.bar(*a, **k) x.bar(*a, **k) with (*a, **k) 5 ((lambda x=x, a=a, k=k: x(*a, **k)) for x, a, k in funcs_and_args_list) (x(*a,**k) with (x=x, a=a, k=k) for x, a, k in funcs_and_args_list) -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam wrote: It's not an empty tuple, it's an empty parenthesis. Using tuples it would be. (a,) == (,) which would be the same as: (,) == (,) () () a = () type(a) type 'tuple' (,) File stdin, line 1 (,) ^ SyntaxError: invalid syntax You've wandered way off into the woods now. -- Erik Max Francis [EMAIL PROTECTED] http://www.alcyone.com/max/ San Jose, CA, USA 37 20 N 121 53 W AIM erikmaxfrancis But since when can wounded eyes see / If we weren't who we were -- Joi -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Christopher Subich wrote: As others have mentioned, this looks too much like a list comprehension to be elegant, which also rules out () and {}... but I really do like the infix syntax. Why would it rule out ()? You need to put a lambda express in ()'s anyways if you want to use it right away. print (lambda x,y:x+y)(1,2) If you don't use the ()'s it reads the y(1,2) as part of the lambda expression, might as well require the ()'s to start with rather than leave it open for a possible error. You could even say () is to function as [] is to list. a function : name(args) - returns a value a list : name[index] - returns a value My choice: name = (let x,y return x+y) # easy for beginners to understand value = name(a,b) value = (let x,y return x+y)(a,b) I think the association of (lambda) to [list_comp] is a nice distinction. Maybe a {dictionary_comp} would make it a complete set. ;-) Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Erik Max Francis wrote: Ron Adam wrote: It's not an empty tuple, it's an empty parenthesis. Using tuples it would be. (a,) == (,) which would be the same as: (,) == (,) () () a = () type(a) type 'tuple' (,) File stdin, line 1 (,) ^ SyntaxError: invalid syntax You've wandered way off into the woods now. Yes, ummm seems soo... err. This is one of those Python isn't quite consistent for practical reasons area. I don't create empty tuples that way very often, but [] is to () is to {} is pretty obvious so I don't really have a good excuse. (1) 1 () () (1) 1 ((())) () Well in my previous explanation I *mean* it to be empty parenthesis. Does that help? Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam wrote: Well in my previous explanation I *mean* it to be empty parenthesis. Does that help? Maybe it might be beneficial to learn a little more of the language before proposing such wide-reaching (and un-Pythonic) reforms? -- Erik Max Francis [EMAIL PROTECTED] http://www.alcyone.com/max/ San Jose, CA, USA 37 20 N 121 53 W AIM erikmaxfrancis But since when can wounded eyes see / If we weren't who we were -- Joi -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Erik Max Francis wrote: Ron Adam wrote: Well in my previous explanation I *mean* it to be empty parenthesis. Does that help? Maybe it might be beneficial to learn a little more of the language before proposing such wide-reaching (and un-Pythonic) reforms? Hi Erik, Getting more sleep is the answer to not making those kinds of oversights in this case. It's really was not a (my) proposal, but a suggestion someone else made. It seemed like an interesting idea and I wanted to see what kind of problems and benefits it would have. Discussing an idea with other before it's fully thought out is a good way to explore its possibilities even though it may mean appearing silly at times, which I don't mind. :) In the previous posts I was attempting to show a possible pattern or logic which doesn't currently correspond to the languages syntax using parenthesis. (None) That's as close to an empty parenthesis as Python gets. I was really trying to explain an underlying concept, not show actual python code. And the conclusion (opinion) I've come to, is such a change might be made to work, but it would be very confusing to most people who have gotten use to the current None usage. And difficult to emplement in a way that's consistant overall. An alternative is to use a different word such as 'undefined'. Then None can be used as it is currently, and undefined, can be used to test for in a comparison for undefined names. Assigning a name to undefined could be used as an alternative to delete a name but so far I don't see an advantage to doing that way over using del. if name is undefined: do something. Instead of: try: name except: do something And maybe: name = undefined can be used in expressions where del name can't? But so far this doesn't seem useful enough to propose and it would probably cause more problems (or confusion) than it solves. Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Tuesday 05 July 2005 06:57 pm, Steven D'Aprano wrote: On Tue, 05 Jul 2005 12:11:47 -0700, mcherm wrote: And besides, def isn't a magic word... it's an abreviation for define... Really? I thought it was an abbreviation for definition. As in, definition of MyFunc is... Does it matter? But no, define is correct, because the def keyword is active. It is *not* a declaration of a function but a command to define one then and there. I hope that any student who didn't understand a word as common as define wouldn't have graduated from our school. How about tuple? It's a generalization rather than a specialization: double (or couple) triple quadruple quintuple sextuple septuple octuple nontuple ... Maybe a wee bit less obvious, but still understandable. Besides, the existence of another poor choice of words wouldn't make the first one any better, would it? If you are arguing that lambda is the right and proper word for this operator that Python should use, I still will have to disagree. OTOH, if you just want the functionality of lambda to remain, I must say I agree. It's a useful construct. But it *is* poorly named. It really stands out as the least intuitive keyword in the language, IMHO. -- Terry Hancock ( hancock at anansispaceworks.com ) Anansi Spaceworks http://www.anansispaceworks.com -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Tuesday 05 July 2005 03:43 pm, Tom Anderson wrote: I understand that the backslash is popular in some ivory-tower functional languages. Currently, a backslash can be used for explicit line joining, and is illegal elsewhere on a line outside a string literal, so i think it's available for this. It would be utterly unpythonic to use puntuation instead of a keyword, and it would make no sense to novices, but it would scare the crap out of C programmers, which has to be worth something. With list comprehensions and generators becoming so integral, I'm not sure about unpythonic. And a syntax just occured to me -- what about this: [y*x for x,y] ? (that is: [expression for argument list] It's just like the beginning of a list comprehension or generator, but without the iterator. That implies that one must be given, and the result is therefore a callable object. Wouldn't do anything more or less than present day lambda, but gets rid of the weird keyword, and integrates nicely with list comps and generators. It's currently a syntax error, and it requires no special delimiter -- it's really just an extension of list comp syntax. -- Terry Hancock ( hancock at anansispaceworks.com ) Anansi Spaceworks http://www.anansispaceworks.com -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
I said I'd drop the discussion about lambda, but this isn't really the same discussion even if it is part of the same thread. That's my excuse, and I'm sticking to it. Terry Hancock wrote: On Tuesday 05 July 2005 03:43 pm, Tom Anderson wrote: I understand that the backslash is popular in some ivory-tower functional languages. Currently, a backslash can be used for explicit line joining, and is illegal elsewhere on a line outside a string literal, so i think it's available for this. It would be utterly unpythonic to use puntuation instead of a keyword, and it would make no sense to novices, but it would scare the crap out of C programmers, which has to be worth something. With list comprehensions and generators becoming so integral, I'm not sure about unpythonic. And a syntax just occured to me -- what about this: [y*x for x,y] ? (that is: [expression for argument list] It's just like the beginning of a list comprehension or generator, but without the iterator. That implies that one must be given, and the result is therefore a callable object. That is a very long chain of implication: It looks like a list comprehension... but there is no iterator... so we have to supply an iterator... so it takes an argument... so it is a callable object... oh and by the way, it can take any arguments, not just iterators. It is also far too easy to make a mistake, eg to write something like newlist = [y*x for x,y] when you actually wanted the list comp [y*x for x,y in L]. This would create an anonymous function where you expected to create a list. It is hard to think of a usage case where you didn't discover the error reasonably soon, but it would be better for leaving the iterator out of a list comp to remain a syntax error, rather than produce an unexpected, but legal, object. Besides, I think Guido should be very cautious about introducing new features that use punctuation, instead of keywords. We don't want to become perl do we? :-) -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Op 2005-07-01, Mike Meyer schreef [EMAIL PROTECTED]: iK [EMAIL PROTECTED] writes: Seems like he wants python programmers to solve their problems all in the same way. While that is great for corporate slaves it is terrible for the creative programmer. No, he wants Python to be Pythonic. TMTOWTDI is not Pythonic. If Guido should change his mind on this, then it will be pythonic. I don't think a concept that has so little meaning has any real value. Python is quickly becoming the visual basic of the 21 century. If you want to have fun while getting some work done you need to look elsewhere. It's a shame... If you'd rather spend your time figuring out which of multiple ways to do things is the best for the job at hand than producing code, there's a language that makes TMTOWTDI a way of life. There are always many ways to do things, and depending on circumstances the best way to do something may differ every time. So if python no longer allows multiple ways to do things, it won't help the programmer. The programmer will now face the question if python is still the right language to do the job. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Op 2005-07-02, Mike Meyer schreef [EMAIL PROTECTED]: Sean McIlroy [EMAIL PROTECTED] writes: Peter Hansen wrote: snip Sean, what gave you the impression this would change? if that's the case then list comprehensions and/or first class functions are likely to be the next target. The existence of list comprehensions are the reason that these functions are going away, so they aren't likely to be next. It's all part of There should be one-- and preferably only one --obvious way to do it. IMO people concentrate too much on the and preferably only one part of this. If you really want at least one obvious way to do things then, there also will be a lot of things that have more than one obvious way. Trying to eliminate all those mulitiple obvious ways, which seems to be one of the goals here, will result in removing the one obvious way for doing other things. -- Antoon Pardon -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Full Acknowledge -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
map, filter, reduce and lambda Lisp constructs, bring flexibility to the language and is why I started programming in python to begin with. Removing these constructs will be a shame and one step closer to the death of some of the basic features that make python great. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Wed, 5 Jul 2005, George Sakkis wrote: Steven D'Aprano [EMAIL PROTECTED] wrote: On Tue, 05 Jul 2005 09:46:41 -0500, Terry Hancock wrote: [snip] Def would be short for ... defend? defile? defer? defame? default? deflect? There's always *something* to learn. Why def instead of define? Because easy to write beats instantly obvious to a beginner, if the word is used all the time and is easy to memorize. Still it's hard to explain why four specific python keywords - def, del, exec and elif - were chosen to be abbreviated, while all the rest are full words (http://docs.python.org/ref/keywords.html). Ease of typing is a joke for an excuse; For exec and probably del, yes, but def and elif are two of the most frequently used keywords in the language, so i think it's reasonable to keep them short. So, who would object the full-word versions for python 3K ? def - define I'd keep this short - it's one of the most commonly-used keywords. It's particularly commonly used if you break your programs down into lots of little functions; since this is, IMHO, something we want to encourage people to do, we should strive to minimise boilerplate. del - delete How about just getting rid of del? Removal from collections could be done with a method call, and i'm not convinced that deleting variables is something we really need to be able to do (most other languages manage without it). exec - execute This should be a function somewhere, maybe a builtin, maybe not - it absolutely should not be a keyword. What that function should be called, i don't know! elif - else if I'm not sure about splitting it into two words; there's currently a very simple relationship between flow control keywords, meanings, and blocks of code, which would be broken if we moved to using else if. I don't know that this relationship is actually important, though. tom -- Don't believe his lies. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Wed, 6 Jul 2005, Terry Hancock wrote: On Tuesday 05 July 2005 03:43 pm, Tom Anderson wrote: I understand that the backslash is popular in some ivory-tower functional languages. Currently, a backslash can be used for explicit line joining, and is illegal elsewhere on a line outside a string literal, so i think it's available for this. It would be utterly unpythonic to use puntuation instead of a keyword, and it would make no sense to novices, but it would scare the crap out of C programmers, which has to be worth something. With list comprehensions and generators becoming so integral, I'm not sure about unpythonic. I'm going to resist the temptation to argue that list comps are themselves unpythonic :). Hang on, where's the punctuation in either of those? They *are* done with keywords! A generator is just a function with yield instead of return, list comprehensions are just list literals where the explicit sequence of items is replaced with code producing them, using the keywords for, in and if, and a generator expression is a list comp *without any punctuation!* And a syntax just occured to me -- what about this: [y*x for x,y] ? Terrible. Square brackets mean a list, and a lambda is not anything like a list. I see where you're coming from, though; a lambda is a lot like the first half of a list comp that's broken off and is roaming free. I can't think of a good syntax for it, though. tom -- find porn apricot -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Tom Anderson wrote: del - delete How about just getting rid of del? Removal from collections could be done with a method call, and i'm not convinced that deleting variables is something we really need to be able to do (most other languages manage without it). Since this is a Python 3k item... What would be the consequence of making None the default value of an undefined name? And then assigning a name to None as a way to delete it? Some benefits = *No more NamesError exceptions! print value None value = 25 print value 25 value = None#same as 'del value' *No initialization needed for a while loop! While not something: if condition: something = True *Test if name exists without using a try-except! if something == None: something = value *And of course one less keyword! Any drawbacks? Cheers, Ron PS... not much sleep last night, so this may not be well thought out. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Wed, 06 Jul 2005 14:33:47 GMT, Ron Adam [EMAIL PROTECTED] wrote: Since this is a Python 3k item... What would be the consequence of making None the default value of an undefined name? And then assigning a name to None as a way to delete it? [ ... ] Any drawbacks? Lots more hard-to-find errors from code like this: filehandle = open( 'somefile' ) do_something_with_an_open_file( file_handle ) filehandle.close( ) Regards, Dan -- Dan Sommers http://www.tombstonezero.net/dan/ -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Terry Hancock wrote: And a syntax just occured to me -- what about this: [y*x for x,y] ? (that is: [expression for argument list] If you haven't already, see: http://wiki.python.org/moin/AlternateLambdaSyntax for other similar proposals. STeVe -- http://mail.python.org/mailman/listinfo/python-list
Deleting variables [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
On Wed, 06 Jul 2005 14:28:55 +0100, Tom Anderson wrote: del - delete How about just getting rid of del? Removal from collections could be done with a method call, Which would be called object.del() I presume. And that opens a big can of worms. Suppose we have a list L = [4, 3, 2, 1, 0], what should L.del(1) do? It looks like it should result in L becoming [4, 3, 2, 0]. An easy mistake to make, if you forget that the argument is (presumably) an index. You could make it clear by insisting on L.del[1] but that requires a big change in Python's syntax. What should L.del() do, with no arguments? Raise an error? Now, you have something like this: class thing: pass obj = thing() obj.alpha = [4, 3, 2, 1, 0] obj.beta = 5 Python's object model suggests that obj.alpha.del() should call alpha's del method, in the same way that obj.alpha.append() would call alpha's append method. So how do you delete obj.alpha? obj.del(alpha) might work. But what if obj itself is a mapping, with a key alpha as well as an attribute alpha. Which one should obj.del(alpha) delete? Now, if you said that L.del() should raise an exception earlier, what about obj.beta.del()? Presumably every object automatically has a del method, so you don't have to program a del method yourself. obj.del is a method object. So it has a del method. (Yes, sometimes you want to delete methods. Functions are first class objects in Python.) Which has a del method. Which has a del method. What should obj.del.del.del.del.del.del.del.del.del() do? and i'm not convinced that deleting variables is something we really need to be able to do (most other languages manage without it). Most other languages don't have namespaces that can get polluted, or on-the-fly creation of variables. Most other languages don't consider variables to be simply attributes of a module object. And most other languages don't allow you to run interactive sessions where it is easy to mistakenly make variables you don't want. py x = 1 py u = x+2 # oops, typo, meant y not u py del u # prevent confusion in the programmer's mind It is also useful sometimes to delete a module object from the top level namespace before re-importing it, rather than merely reloading it. That requires being able to delete a variable. In summary: del being a keyword works. del() being an object method is unclear, confusing and complicated. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Dan Sommers wrote: On Wed, 06 Jul 2005 14:33:47 GMT, Ron Adam [EMAIL PROTECTED] wrote: Since this is a Python 3k item... What would be the consequence of making None the default value of an undefined name? And then assigning a name to None as a way to delete it? [ ... ] Any drawbacks? Lots more hard-to-find errors from code like this: filehandle = open( 'somefile' ) do_something_with_an_open_file( file_handle ) filehandle.close( ) Regards, Dan If do_something_with_an_open_file() is not defined. Then you will get: TypeError: 'NoneType' object is not callable If file_handle (vs filehandle) is None. Then you will still get an error as soon as you tried to use the invalid file handle. AttributeError: 'NoneType' object has no attribute 'read' If the error was filehundle.close() you will get: AttributeError: 'NoneType' object has no attribute 'close' I don't think any of those would be hard to find. Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Here's a couple of examples from my own code: # from a Banzhaf Power Index calculator # adds things that aren't numbers return reduce(operator.add, (VoteDistributionTable({0: 1, v: 1}) for v in electoral_votes)) return sum([VoteDistributionTable({0:1, v:1} for v in electoral_votes],VoteDistributionTable({})) Any time you use operator.add, you can probably use sum(sequence,initialvalue) # from a custom numeric class # converts a tuple of digits into a number mantissa = sign * reduce(lambda a, b: 10 * a + b, mantissa) I'll admit I can't figure out a way to replace reduce without writing some ugly code here, but I doubt these sorts of things appear often. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Devan L wrote: # from a custom numeric class # converts a tuple of digits into a number mantissa = sign * reduce(lambda a, b: 10 * a + b, mantissa) I'll admit I can't figure out a way to replace reduce without writing some ugly code here, but I doubt these sorts of things appear often. It's not ugly or difficult to define a named function. def digits_to_value(seq): v = 0 for d in seq: v = v*10+d return v Then where you need it. mantissa = sign * digits_to_value(mantissa) One of the motivations is the reduce-lambda expressions are a lot harder to read than a properly named function. And a function will often work faster than the reduce-lambda version as well. Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Devan L wrote: Here's a couple of examples from my own code: # from a Banzhaf Power Index calculator # adds things that aren't numbers return reduce(operator.add, (VoteDistributionTable({0: 1, v: 1}) for v in electoral_votes)) return sum([VoteDistributionTable({0:1, v:1} for v in electoral_votes],VoteDistributionTable({})) Any time you use operator.add, you can probably use sum(sequence,initialvalue) Actually, it's sum([VoteDistributionTable({0:1, v:1}) for v in electoral_votes], VoteDistributionTable({0: 1})) but you're right about being able to use sum here. # from a custom numeric class # converts a tuple of digits into a number mantissa = sign * reduce(lambda a, b: 10 * a + b, mantissa) I'll admit I can't figure out a way to replace reduce without writing some ugly code here, but I doubt these sorts of things appear often. Of the quarter-megabyte of my Python code currently on my hard drive, I can find two reduces that can't be replaced by sum, product, any, or all. The other one is return reduce(lambda x, y: x 1 | y, bits) -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Wed, 06 Jul 2005 15:18:31 GMT, Ron Adam [EMAIL PROTECTED] wrote: Dan Sommers wrote: On Wed, 06 Jul 2005 14:33:47 GMT, Ron Adam [EMAIL PROTECTED] wrote: Since this is a Python 3k item... What would be the consequence of making None the default value of an undefined name? And then assigning a name to None as a way to delete it? [ ... ] Any drawbacks? Lots more hard-to-find errors from code like this: filehandle = open( 'somefile' ) do_something_with_an_open_file( file_handle ) filehandle.close( ) Regards, Dan [ ... ] If file_handle (vs filehandle) is None. Then you will still get an error as soon as you tried to use the invalid file handle. AttributeError: 'NoneType' object has no attribute 'read' This is the one of which I was thinking. So you see this error at the end of a (long) traceback, and try to figure out where along the (long) line of function calls I typed the wrong name. Currently, the very end of the traceback points you right at the bad code and says NameError: name 'filehandle' is not defined, which tells me (very nearly) exactly what I did wrong. If the error was filehundle.close() you will get: s/u/a/ ;-) I don't think any of those would be hard to find. I guess it depends on how long your traceback is and how big those functions are. Also, from the Zen: Explicit is better than implicit. although from previous threads, we know that every pythonista has his or her own definitions of explicit and implicit. Regards, Dan -- Dan Sommers http://www.tombstonezero.net/dan/ -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On 2005-07-06 02:46:27, George Sakkis wrote: So, who would object the full-word versions for python 3K ? def - define del - delete exec - execute elif - else if I'm all for it. I would even be tempted of changing def to function, but it would look stupid in: class A: function make_my_day(self): return Your day a = A() since a.make_my_day() is really a method, not a standalone function. We could use function instead of lambda though =) Objections for the else if might be that it sounds like you can replace else if with else x=94 if you want. Thumbs up for else if because it explains what it is much better than elif. elseif ? -- Stian Søiland Work toward win-win situation. Win-lose Trondheim, Norway is where you win and the other lose. http://soiland.no/ Lose-lose and lose-win are left as an exercise to the reader. [Limoncelli/Hogan] -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On 2005-07-06 01:46:05, Steven D'Aprano wrote: I had NEVER even heard the word tuple before learning Python. I spent weeks mispelling it as turple, and I finally had to look it up in a dictionary to see if it was a real English word. Out of the four English dictionaries in my house, none of them have the word. Agree, I have the problem of writing tupple in all comments and documentations. It's a weird word indeed =) t = immutable_list(L) map(anonymous_function x: x+1, L) Hey, I know! t = python.util.ImmutableArrayList.fromCollection(L.getAbstractCollection()) python.util.functional.applyFunctionOnCollection( (class implements python.util.functional.AnonymousFunction: def anonymousFunction(x): return x+1 ), L) -- Stian Søiland Work toward win-win situation. Win-lose Trondheim, Norway is where you win and the other lose. http://soiland.no/ Lose-lose and lose-win are left as an exercise to the reader. [Limoncelli/Hogan] -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On 2005-07-06 16:33:47, Ron Adam wrote: *No more NamesError exceptions! print value None So you could do lot's of funny things like: def my_fun(extra_args=None): if not extraargs: print Behave normally extra_args = 1337 if extraargs: asdkjaskdj .. if extra_args: kajsdkasjd and get no errors at all, but switching back and forth between the different behavours because you actually did expect None, but from an EXISTING variable. *No initialization needed for a while loop! while not something: if condition: something = True This is the only good case I could find, but opening for a lots of errors when you get used to that kind of coding: while not finished: foo() finished = calculate_something() (..) (..) # Added another loop while not finished: bar() finished = other_calculation() Guess the amount of fun trying to find out the different errors that could occur when bar() does not run as it should because the previous finished variable changes the logic. If you want to experiment with such designs, all you need to do is to start your code with ?php *Test if name exists without using a try-except! if something == None: something = value Now this is a question from newcomers on #python each day.. How do I check if a variable is set?. Why do you want to check if a variable is set at all? If you have so many places the variable could or could not be set, your program design is basically flawed and must be refactored. -- Stian Søiland Work toward win-win situation. Win-lose Trondheim, Norway is where you win and the other lose. http://soiland.no/ Lose-lose and lose-win are left as an exercise to the reader. [Limoncelli/Hogan] -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Dan Sommers wrote: AttributeError: 'NoneType' object has no attribute 'read' This is the one of which I was thinking. So you see this error at the end of a (long) traceback, and try to figure out where along the (long) line of function calls I typed the wrong name. Currently, the very end of the traceback points you right at the bad code and says NameError: name 'filehandle' is not defined, which tells me (very nearly) exactly what I did wrong. The actual error could be improved a bit to refer the the name of the and line the error is in. Which would help some. AttributeError: 'NoneType' object file_handle has no attribute 'read' I guess it depends on how long your traceback is and how big those functions are. Also, from the Zen: Explicit is better than implicit. although from previous threads, we know that every pythonista has his or her own definitions of explicit and implicit. True, but this isn't any different than any other 'Type' error, or value error. And considerably easier to find than one off errors. There would be more restrictions on None than there are now so it wouldn't be as bad as it seems. For example passing a None in a function would give an error as the name would be deleted before the function actually gets it. So doing this would give an error for functions that require an argument. def foo(x): return x a = None b = foo(a)# error because a dissapears before foo gets it. TypeError: foo() takes exactly 1 argument(0 given) So they wouldn't propagate like you would expect. Hmmm interesting that would mean... lets see. 1. var = None# removes ref var, this is ok 2. None = var# give an error of course 3. var = undefined_var # same as var = None, that's a problem! Ok... this must give an error because it would delete var silently! Definitely not good. So going on, on that basis. 4. undefined == None # Special case, evaluates to True. 5. def foo():return None # same as return without args 6. x = foo()# Would give an error if foo returns None This might be an improvement over current behavior. Breaks a lot of current code though. 7. if undefined:# error 8. if undefined==None # Special case - True Good for checking if vars exist. 9. if undefined==False # Error, None!=False (or True) 9. while undefined: # error 10 while undefined==None: Possible loop till defined behavior. Ok... and undefined var returning None is a bad idea, but using None to del names could still work. And (undefined==None) could be a special case for checking if a variable is defined. Otherwise using an undefined name should give an error as it currently does. Cheers, Ron Regards, Dan -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Stian Søiland wrote: On 2005-07-06 16:33:47, Ron Adam wrote: *No more NamesError exceptions! print value None So you could do lot's of funny things like: def my_fun(extra_args=None): if not extraargs: print Behave normally extra_args = 1337 if extraargs: asdkjaskdj .. if extra_args: kajsdkasjd Yes, returning None from an undefined name is DOA. In the above case you would get an error by the way. if extraargs: would evaluate to if None:, which would evaluate to if: which would give you an error. *No initialization needed for a while loop! while not something: if condition: something = True This is the only good case I could find, but opening for a lots of errors when you get used to that kind of coding: It would need to be.. while not (something==None): and the compiler would need to handle it as a special case. But this one could still work without allowing something=undefined to be valid. while not finished: foo() finished = calculate_something() (..) (..) # Added another loop while not finished: bar() finished = other_calculation() Guess the amount of fun trying to find out the different errors that could occur when bar() does not run as it should because the previous finished variable changes the logic. It's not really differnt than any other value test we currently use. notfinished = True while notfinished: notfinished = (condition) # Need to set notfinished back to True here. while notfinished: morestuff *Test if name exists without using a try-except! if something == None: something = value Now this is a question from newcomers on #python each day.. How do I check if a variable is set?. Why do you want to check if a variable is set at all? If you have so many places the variable could or could not be set, your program design is basically flawed and must be refactored. There's a few places the Python library that do exactly that. try: value except: value = something I admit it's something that should be avoided if possible because if there's doubt that a name exists, then there would also be doubt concerning where it came from and weather or not it's value/object is valid. Anyway, it was an interesting but flawed idea, I should of thought more about it before posting it. Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Wed, 6 Jul 2005 20:42:51 +0200, Stian Søiland [EMAIL PROTECTED] wrote: I'm all for it. I would even be tempted of changing def to function, but it would look stupid in: class A: function make_my_day(self): return Your day a = A() since a.make_my_day() is really a method, not a standalone function. We could use function instead of lambda though =) So use method instead, which has the added advantage of implicity declaring an extra argument named this: class A: method __init__(): this.x = 0 method make_my_day(foo): this.x += foo there-aren't-enough-winks-in-the-universe'ly yours, Dan -- Dan Sommers http://www.tombstonezero.net/dan/ -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Stian Søiland a écrit : (snip) Hey, I know! t = python.util.ImmutableArrayList.fromCollection(L.getAbstractCollection()) python.util.functional.applyFunctionOnCollection( (class implements python.util.functional.AnonymousFunction: def anonymousFunction(x): return x+1 ), L) Reminds me of something, but what ?-) -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam wrote: if extraargs: would evaluate to if None:, which would evaluate to if: which would give you an error. In what way is if None: equivalent to if:? -- Benji York -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
I think in some contextes map is more readable than [f() for i in S] because it's more verbatim Removing lamdba would be reduce readability of Python, I think here for examble of code like class App: def drawLines(self, event): from random import randint r = lambda : randint(1, 100) self.canvas.create_line(r(), r(), r(), r()) defining one extra function would only confuse and self.canvas.create_line(r(1, 100), r(1, 100), r(1, 100), r(1, 100)) is not very nice to look at and what about creating one liner factories like from math import log10 log = lambda basis: lambda x: log10(x) / log10(basis) log2 = log(2) log2(2**10) - 10.0 I would consider it as a great loss for Python if lambda will disappear -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Daniel Schüle wrote: Removing lamdba would be reduce readability of Python, I think here for examble of code like class App: def drawLines(self, event): from random import randint r = lambda : randint(1, 100) self.canvas.create_line(r(), r(), r(), r()) defining one extra function would only confuse and But you just did define one extra function!! If you're really afraid of two lines, write it as: def r(): randint(1, 100) This is definitely a bad case for an anonymous function because it's not anonymous! You give it a name, r. and what about creating one liner factories like from math import log10 log = lambda basis: lambda x: log10(x) / log10(basis) log2 = log(2) log2(2**10) - 10.0 This is slightly better, because at least one of your functions really is anonymous. I'm not really sure I'm convinced that it's any better than this though: def log(base): def log_in_base(x): return log10(x)/log10(base) return log_in_base because when I first read the code, I didn't catch the second, nested lambda. Of course, with a syntax-highlighting editor, I probably would have. Again though, to fix your abuse of anonymous function syntax for non-anonymous functions, you should write this as: def log(basis): return lambda x: log10(x) / log10(basis) Or if you're afraid of multiple lines: def log(basis): return lambda x: log10(x) / log10(basis) STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Tom Anderson [EMAIL PROTECTED] writes: Comrades, During our current discussion of the fate of functional constructs in python, someone brought up Guido's bull on the matter: http://www.artima.com/weblogs/viewpost.jsp?thread=98196 He says he's going to dispose of map, filter, reduce and lambda. He's going to give us product, any and all, though, which is nice of him. What really struck me, though, is the last line of the abstract: I expect tons of disagreement in the feedback, all from ex-Lisp-or-Scheme folks. :-) I disagree strongly with Guido's proposals, and i am not an ex-Lisp, -Scheme or -any-other-functional-language programmer; my only other real language is Java. I wonder if i'm an outlier. So, if you're a pythonista who loves map and lambda, and disagrees with Guido, what's your background? Functional or not? Not. But I've gained a real appreciation for functional programming from my use of both C++ and Python. -- Dave Abrahams Boost Consulting www.boost-consulting.com -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Bruno Desthuilliers [EMAIL PROTECTED] writes: I discovered FP with David Mertz's papers about FP in Python. I had never read nor write a line of lisp, scheme, haskell, caml etc before. And I'd certainly start thinking of choosing another MYFL if anonymous functions where to disappear from Python. Note that I said anonymous functions, not lambda. Concerning map, filter, reduce etc, these functions can live in a separate module, and this wouldn't bother me. But anonymous functions are part of the language syntax, so there is no work-around. Actually I'm pretty sure there is. It should be possible to re-implement the Boost Lambda library in Python: http://www.boost.org/libs/lambda Compared with in-language lambda support it would have the advantage of brevity and clarity for very small functions, but there are lots of disadvantages, too. I wonder how Guido would feel if people started using a (relatively) slow library solution with odd warts as a consequence of dropping real lambdas. -- Dave Abrahams Boost Consulting www.boost-consulting.com -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Benji York wrote: Ron Adam wrote: if extraargs: would evaluate to if None:, which would evaluate to if: which would give you an error. In what way is if None: equivalent to if:? -- Benji York It's not now.. but if None where to really represent the concept None, as in not bound to anything, it would evaluate to nothing. Given the statement: a = None And the following are all true: a == None (a) == (None) (a) == () (None) == () Then this conceptual comparison should also be true: if (None): == if (): if (): == if: Comparing if's like that wouldn't be a valid code of course, but it demonstrates the consistency in which the comparison is made. I think. ;-) Of course this is all hypothetical anyways, so it could be what ever we decide makes the most since, include not changing anything. Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam [EMAIL PROTECTED] writes: So doing this would give an error for functions that require an argument. def foo(x): return x a = None b = foo(a)# error because a dissapears before foo gets it. So how do I pass None to a function? TypeError: foo() takes exactly 1 argument(0 given) So they wouldn't propagate like you would expect. Hmmm interesting that would mean... lets see. 1. var = None# removes ref var, this is ok 2. None = var# give an error of course 3. var = undefined_var # same as var = None, that's a problem! Ok... this must give an error because it would delete var silently! Definitely not good. So going on, on that basis. 4. undefined == None # Special case, evaluates to True. 5. def foo():return None # same as return without args 6. x = foo()# Would give an error if foo returns None Why? Shouldn't it delete x? This might be an improvement over current behavior. Breaks a lot of current code though. I don't think so. I've programmed in langauges that gave undefined variables a value rather than an exception. It almost inevitabley led to hard-to-find bugs. FORTRAN used to give all variables a type, so that a typo in a variable name could well lead to a valid expression. The technic for disabling this was baroque (IMPLICIT BOOLEAN*1 A-Z), but so common they invented a syntax for it in later versions of FORTRAN (IMPLICIT NONE). mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Mike Meyer wrote: Ron Adam [EMAIL PROTECTED] writes: So doing this would give an error for functions that require an argument. def foo(x): return x a = None b = foo(a)# error because a dissapears before foo gets it. So how do I pass None to a function? You wouldn't. What would a function do with it anyway? If you wanted to pass a neutral value of some sort, then you'd just have to pick something else and test for it. Maybe we could use Nil as an alternative to None for that purpose? 6. x = foo()# Would give an error if foo returns None Why? Shouldn't it delete x? That was my first thought as well. It would cause all sorts of problems. One way to avoid those is to insist that the only way to assign (delete) a name to None is by literally using None and only None on the right side of the = sign. Any undefined name on the right side would give an error except for None itself. This might be an improvement over current behavior. Breaks a lot of current code though. I don't think so. I've programmed in langauges that gave undefined variables a value rather than an exception. It almost inevitabley led to hard-to-find bugs. That is why the above should give an error I believe. ;) FORTRAN used to give all variables a type, so that a typo in a variable name could well lead to a valid expression. The technic for disabling this was baroque (IMPLICIT BOOLEAN*1 A-Z), but so common they invented a syntax for it in later versions of FORTRAN (IMPLICIT NONE). It's been so long since I did anything if Fortran I've actual don't recall any of it. :) '83-'84 I went from that to pascal, which I thought was a big improvement at the time. Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Mon, 4 Jul 2005, George Sakkis wrote: Tom Anderson [EMAIL PROTECTED] wrote: I'll just chip in and say i'd quite like a flatten(), too; at the moment, i have one like this: def flatten(ll): return reduce(lambda a, l: a.extend(l), ll, []) This doesn't work; a.extend() returns None, not the extended list a: Ah, no, very good, i was hoping someone would notice that. Well done. I think my lambda looks more like lambda a, b: a + b, but i realised the other day that extend could make it more efficient, and didn't think it through properly. tom -- The revolution will not be televised. The revolution will be live. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Tue, 05 Jul 2005 05:03:32 -0700, mcherm wrote: Steven D'Aprano writes: Lambda is no more an obscure name than function, decorator, closure, class, or module. The first time you come across it, you don't know what it means. Then you learn what it means, and then you know. I believe you've made two errors here. First of all, lambda is part of the Python language, while function, decorator, closure, and module are not. Sorry, but you are mistaken. lambda is a _reserved_ word in the Python language, while function etc are not, but they are certainly part of the language. Try explaining what def and import do without using the words function or module. Maybe you can do it, using circumlocutions, but it isn't easy, and costs clarity. [snip] The second error is that I believe most english speakers COULD provide a definition for the fairly common words function, class, and decorator. The exact meaning of class might not be what they expect at first, Function, in the sense of a mathematical function, I agree. Class as in the thing you go to at school and decorator as in the person who advises you what colour curtains to have, certainly. But in the Python sense? No. Especially not decorator, which I believe most _programmers_ would have trouble explaining, let alone non-programmer English speakers. I know I do. but exposure to any object oriented language would make the concept quickly familiar. Just as exposure to functional languages would make lambda very familiar. But lambda has a very clear meaning... it's a letter of the greek alphabet. The connection between that letter and anonymous functions is tenuous at best, and fails the test of making Python read like executable pseudocode. Think back to when you were a schoolboy at your first day of school. Unless you had a very unusual upbringing, you probably had never heard the word function before. There is nothing about the word function that brings to mind a mathematical entity which transforms a variable into a different variable, let alone a programming subroutine that returns a result. (Or for that matter, the purpose which a person or thing is for, as in the function of a spanner is to tighten nuts on bolts.) You had to learn that word, discover what it means, and then it becomes familiar. You don't notice the process only because it happened so long ago, at an age that your brain was operating in language acquisition mode and picking up vocabulary at an incredible rate. There is nothing about the word string that especially brings to mind an array of bytes representing characters. The analogy of string of characters to string of beads breaks down as soon as you have multiple lines of text. And as for float, that's what boats do, heaven only knows what it has to do with numbers. (Yes, I know what it has to do with numbers. But that is something I had to learn, and even now I still have difficulty because I expect floats to operate like mathematical real numbers, and they don't.) And dare I say it, what do constricting snakes have to do with programming? I won't say that the anonymous function meaning of lambda comes to my mind before the Greek letter, but it isn't very far behind, and rapidly catching up. (I use lambda a lot more than I speak Greek.) It wouldn't surprise me if one day I think of Python programming before the Greek letter, just as the world aleph brings to my mind the sense of infinity before the sense of it being a Hebrew letter. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Mon, 4 Jul 2005, Ron Adam wrote: George Sakkis wrote: And finally for recursive flattening: def flatten(seq): return reduce(_accum, seq, []) def _accum(seq, x): if isinstance(x,list): seq.extend(flatten(x)) else: seq.append(x) return seq flatten(seq) [1, 2, 3, 4, 5, 6] How about this for a non recursive flatten. def flatten(seq): s = [] while seq: while isinstance(seq[0],list): seq = seq[0]+seq[1:] s.append(seq.pop(0)) return s seq = [[1,2],[3],[],[4,[5,6]]] flatten(seq) The trouble with these is that they make a lot of temporary lists - George's version does it with the recursive calls to flatten, and Ron's with the slicing and concatenating. How about a version which never makes new lists, only appends the base list? We can use recursion to root through the lists ... def isiterable(x): return hasattr(x, __iter__) # close enough for government work def visit(fn, x): # perhaps better called applytoall if (isiterable(x)): for y in x: visit(fn, y) else: fn(x) def flatten(seq): a = [] def appendtoa(x): a.append(x) visit(appendtoa, seq) return a If you hate recursion, you can write a non-recursive version of visit; you'll have to manage a stack of lists yourself, though. Something like: def visit(fn, x): if (not isiterable(x)): x = (x,) stack = [None] # stack of iterators cur = iter(x) # current iterator while (cur != None): try: thing = cur.next() if (isiterable(thing)): stack.append(cur) cur = iter(thing) else: fn(thing) except StopIteration: cur = stack.pop() There might be a cleverer way to do this. tom -- The revolution will not be televised. The revolution will be live. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Tuesday 05 July 2005 08:17 am, Steven D'Aprano wrote: Sorry, but you are mistaken. lambda is a _reserved_ word in the Python language, while function etc are not, but they are certainly part of the language. Try explaining what def and import do without using the words function or module. Maybe you can do it, using circumlocutions, but it isn't easy, and costs clarity. This is still a relevant distinction. One relevant point is that I am perfectly free to use, say, the Spanish or Chinese word to describe module or function, but the keywords def and import will remain the same. The second error is that I believe most english speakers COULD provide a definition for the fairly common words function, class, and decorator. The exact meaning of class might not be what they expect at first, Function, in the sense of a mathematical function, I agree. Class as in the thing you go to at school and decorator as in the person who advises you what colour curtains to have, certainly. But in the Python sense? No. Especially not decorator, which I believe most _programmers_ would have trouble explaining, let alone non-programmer English speakers. I know I do. The Python sense is not arbitrary. There are very direct visual or logical (i.e. INTUITIVE) connections between these words' *English* meanings (not just mathematical, either) and their meanings in Python. A Function is (in English) (kdict-gcide*): 1.) The act of executing or performing any duty, office, or calling; performance 2.) The appropriate action of any special organ or part of an animal or vegetable organism... [...] 5.) (math) A quantity so connected with another quantity, that if any alteration be made in the latter there will be a consequent alteration in the former. The programming use is probably *closer* to the English meaning than the math jargon meaning (except in the sense of functional programming which leans more on the math meaning. Similarly, decorate is 'make more attractive by adding ornament, colour, etc.' In Python, a decorator applies a wrapper to a function to provide it with some additional functionality. The function definition is furthermore decorated with the decorator declaration to give it more meaning, which is arguably more aesthetically pleasing (otherwise, why not literally wrap with a function after defining the function?). These meanings are very connected with the English definition of the word. Class can, of course, mean a room in which you teach classes, but again Webster's will certainly provide meaning much closer to the programming term: 1. A group of individuals ranked together as possessing common characteristics... [2 is the class of students sense] 3. A comprehensive division of animate or inanimate objects, grouped together on account of their common characteristics 4. A set; a kind or description, species or variety. Meanings 1,3, 4 are all arguably intimately connected to the OOP meaning, especially meaning #3 which even mentions objects. (And I won't bother to point out that the English meaning of object is tied closely to what it means in programming). A similar argument can be made for object, module, script, and even method and program. Now, if you are armed ONLY with the English definition, you will possibly run into some trouble, because the programming usage is a *specialization* of the term -- we strictly take only *one* of the English definitions to apply, and we narrow its meaning a bit. Objects in computer science never means the purpose of the program nor does it ever refer to a small brick, even though the English word can mean both of those things. But it's not exactly a shocker that a programming term is going to apply to things you can find in a program, so I don't think we're stumping the newbie with such terms. lambda has no such advantage. Here's the *entire* gcide definition: Lambda \Lambda\, n. [NL., fr. Gr. la`mbda.] 1. The name of the Greek letter [Lambda], [lambda], corresponding with the English letter L, l. [1913 Webster] 2. (Anat.) The point of junction of the sagittal and lambdoid sutures of the skull. [1913 Webster] 3. (Phys.) A subatomic particle carrying no charge, having a mass equal to 2183 times that of an electron; it decays rapidly, typically forming a nucleon and a pion. --MW10 [PJC] Lambda moth (Zool.), a moth so called from a mark on its wings, resembling the Greek letter lambda ([Lambda]). [1913 Webster] but exposure to any object oriented language would make the concept quickly familiar. Just as exposure to functional languages would make lambda very familiar. Yeah, well, there *is* an entry in the Online Dictionary of Computing: LAMBDA A version of typed lambda-calculus, used to describe semantic domains. [Outline of a Mathematical Theory of Computation, D.S. Scott, TM
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
[EMAIL PROTECTED] wrote: concept quickly familiar. But lambda has a very clear meaning... it's a letter of the greek alphabet. The connection between that letter and anonymous functions is tenuous at best, and fails the test of making Python read like executable pseudocode. But 'lambda' does have a very clear meaning in the realm of functional programming, and it means precisely (mostly) what it means in Python: an anonymous function. It might not be the -best- possible name, but anyone who's had a computer science education should have had a class that introduced basic functional programming topics (even if only for academic interest), and so they should be familiar with the keyword name. If not, then it's just a magic word. Kind of like 'def'. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Up until a few years ago, I ran the computer science department at a high-school. I provided support for the English teachers who taught *all* students -- but they taught things like the use of a word processor or the internet, and never covered the meaning of lambda. I taught a computer applications course which was taken by only small fraction of the students (10%) but there I taught things like the use of photo-editing software, creating web sites, and the use of simple databases; I never covered the meaning of lambda. I also taught the programming class (taken by only a dozen or so students per graduating class) -- students learned basic concepts like variables, looping, up through fancier bits like a couple different sorting algorithms. But I didn't cover the meaning of lambda. And I also taught the AP computer course (taken by an average of just 4 students per year!), in which I explained things like object oriented programming and recursion and managed to get the students to the level where they could work together as a group to write a moderately complex program, like a simple video game. And I didn't teach the meaning of lambda, nor was it covered by the AP exam, which is supposed to be equivalent to a single college-level course in computer programming. So I'd say that it's a pretty obscure name that most people wouldn't know. And besides, def isn't a magic word... it's an abreviation for define... I hope that any student who didn't understand a word as common as define wouldn't have graduated from our school. -- Michael Chermside -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
[EMAIL PROTECTED] wrote: [snip description of experience teaching high school students] So I'd say that it's a pretty obscure name that most people wouldn't know. It would be hard to argue against that statement; certainly lambda in this context (or probably any) is not a word most people would know. On the other hand, the name itself is probably not very important. I still remember my first encounter with lambda in Python very clearly. I saw the word, thought huh? what the heck is that?, then read a sentence about it that included some comment about its background in other fields. Oh, I said, pre-existing usage. Whatever. I proceeded to read about what it did and how to use it. The name was irrelevant. If the text had said anonymous functions are created using the keyword 'tribble' (named for a similar feature in a fictional Klingon programming language), I wouldn't have felt any differently about it. So it makes some sense to a few trekkers... big furry deal. What bothered me was the syntax. Arguments without parentheses? What possessed anyone to put something so inconsistent in the language? No statements? Dang, that will limit my interest in using them. Oh well, what's page four of the tutorial got for me next? It shouldn't take anyone more than ten seconds to integrate lambda into their brain and carry on with useful work. Really, the name is such a trivial, unimportant part of this whole thing that it's hardly worth discussing. The syntax is more important, and the limitations are of definite interest. Not the name. -Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On 2005-07-05, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: Up until a few years ago, I ran the computer science department at a high-school. I provided support for the English teachers who taught *all* students -- but they taught things like the use of a word processor or the internet, That's not computer science. and never covered the meaning of lambda. I taught a computer applications course which was taken by only small fraction of the students (10%) but there I taught things like the use of photo-editing software, creating web sites, and the use of simple databases; That's not computer science. I never covered the meaning of lambda. I also taught the programming class (taken by only a dozen or so students per graduating class) -- students learned basic concepts like variables, looping, up through fancier bits like a couple different sorting algorithms. Now you're getting a little closer to computer science. It sounds like you ran a computer user training department. I don't think it could be called computer science. But I didn't cover the meaning of lambda. And I also taught the AP computer course (taken by an average of just 4 students per year!), in which I explained things like object oriented programming and recursion and managed to get the students to the level where they could work together as a group to write a moderately complex program, like a simple video game. And I didn't teach the meaning of lambda, nor was it covered by the AP exam, which is supposed to be equivalent to a single college-level course in computer programming. Computer programming isn't the same thing as computer science. It's just one of the tools used to do computer science. So I'd say that it's a pretty obscure name that most people wouldn't know. I can't believe that anybody with any computer science background doesn't know it. And besides, def isn't a magic word... it's an abreviation for define... I hope that any student who didn't understand a word as common as define wouldn't have graduated from our school. Lamda isn't a magic word either. It comes from lambda calculus. -- Grant Edwards grante Yow! Is this where people at are HOT and NICE and they visi.comgive you TOAST for FREE?? -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
def flatten(iterable): if not hasattr(iterable, '__iter__'): return [iterable] return sum([flatten(element) for element in iterable],[]) Recursion makes things so much shorter. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Grant Edwards enlightened us with: It sounds like you ran a computer user training department. I don't think it could be called computer science. Being a computer science student at the University of Amsterdam, I can tell you that it definitely should not be called computer science. I can't believe that anybody with any computer science background doesn't know it. I agree. Sybren -- The problem with the world is stupidity. Not saying there should be a capital punishment for stupidity, but why don't we just take the safety labels off of everything and let the problem solve itself? Frank Zappa -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Devan L wrote: def flatten(iterable): if not hasattr(iterable, '__iter__'): return [iterable] return sum([flatten(element) for element in iterable],[]) Recursion makes things so much shorter. The last line can faster and more compact by: from itertools import imap def flatten(iterable): if not hasattr(iterable, '__iter__'): return [iterable] return sum(imap(flatten,iterable),[]) George -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Tue, 5 Jul 2005, Terry Hancock wrote: Having said that, I too will miss the *concept* of an anonymous function, although I wouldn't mind at all if its name changed, or if it were somehow integrated into the def keyword's usage. Using backticks or some other syntax delimiter also sounds promising, although we're sort of running out of them. ;-) I understand that the backslash is popular in some ivory-tower functional languages. Currently, a backslash can be used for explicit line joining, and is illegal elsewhere on a line outside a string literal, so i think it's available for this. It would be utterly unpythonic to use puntuation instead of a keyword, and it would make no sense to novices, but it would scare the crap out of C programmers, which has to be worth something. tom -- [Philosophy] is kind of like being driven behind the sofa by Dr Who - scary, but still entertaining. -- Itchyfidget -- http://mail.python.org/mailman/listinfo/python-list
flatten(), [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
Tom Anderson wrote: The trouble with these is that they make a lot of temporary lists - George's version does it with the recursive calls to flatten, and Ron's with the slicing and concatenating. How about a version which never makes new lists, only appends the base list? We can use recursion to root through the lists ... Ok... How about a non-recursive flatten in place? ;-) def flatten(seq): i = 0 while i!=len(seq): while isinstance(seq[i],list): seq.__setslice__(i,i+1,seq[i]) i+=1 return seq seq = [[1,2],[3],[],[4,[5,6]]] print flatten(seq) I think I'll be using the __setslice__ method more often. And the test: # # Georges recursive flatten init_a = def flatten(seq): return reduce(_accum, seq, []) def _accum(seq, x): if isinstance(x,list): seq.extend(flatten(x)) else: seq.append(x) return seq seq = [[1,2],[3],[],[4,[5,6]]] # Ron's non-recursive init_b = def flatten(seq): s = [] while seq: while isinstance(seq[0],list): seq = seq[0]+seq[1:] s.append(seq.pop(0)) return s seq = [[1,2],[3],[],[4,[5,6]]] # Tom's recursive, no list copies made init_c = def isiterable(x): return hasattr(x, __iter__) # close enough for government work def visit(fn, x): # perhaps better called applytoall if (isiterable(x)): for y in x: visit(fn, y) else: fn(x) def flatten(seq): a = [] def appendtoa(x): a.append(x) visit(appendtoa, seq) return a seq = [[1,2],[3],[],[4,[5,6]]] # Devan' smallest recursive init_d = def flatten(iterable): if not hasattr(iterable, '__iter__'): return [iterable] return sum([flatten(element) for element in iterable],[]) seq = [[1,2],[3],[],[4,[5,6]]] # Ron's non-recursive flatten in place! Much faster too! init_e = def flatten(seq): i = 0 while i!=len(seq): while isinstance(seq[i],list): seq.__setslice__(i,i+1,seq[i]) i+=1 return seq seq = [[1,2],[3],[],[4,[5,6]]] import timeit t = timeit.Timer(flatten(seq),init_a) print 'recursive flatten:',t.timeit() import timeit t = timeit.Timer(flatten(seq),init_b) print 'flatten in place-non recursive:',t.timeit() import timeit t = timeit.Timer(flatten(seq),init_c) print 'recursive-no copies:',t.timeit() import timeit t = timeit.Timer(flatten(seq),init_d) print 'smallest recursive:',t.timeit() import timeit t = timeit.Timer(flatten(seq),init_e) print 'non-recursive flatten in place without copies:',t.timeit() # The results on Python 2.3.5: (maybe someone can try it on 2.4) recursive flatten: 23.6332723852 flatten in place-non recursive: 22.1817641628 recursive-no copies: 30.909762833 smallest recursive: 35.2678756658 non-recursive flatten in place without copies: 7.8551944451 A 300% improvement!!! This shows the value of avoiding copies, recursion, and extra function calls. Cheers, Ron Adam -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Tue, 05 Jul 2005 09:46:41 -0500, Terry Hancock wrote: On Tuesday 05 July 2005 08:17 am, Steven D'Aprano wrote: Sorry, but you are mistaken. lambda is a _reserved_ word in the Python language, while function etc are not, but they are certainly part of the language. Try explaining what def and import do without using the words function or module. Maybe you can do it, using circumlocutions, but it isn't easy, and costs clarity. This is still a relevant distinction. One relevant point is that I am perfectly free to use, say, the Spanish or Chinese word to describe module or function, but the keywords def and import will remain the same. No, that isn't relevant. That's just localisation. I'm also free to fork Python and change the keywords. [snip] The Python sense is not arbitrary. There are very direct visual or logical (i.e. INTUITIVE) connections between these words' *English* meanings (not just mathematical, either) and their meanings in Python. I had NEVER even heard the word tuple before learning Python. I spent weeks mispelling it as turple, and I finally had to look it up in a dictionary to see if it was a real English word. Out of the four English dictionaries in my house, none of them have the word. Let's dump tuple from the language too, its just a stupid name for a list that can't change. Agreed? [snip] Similarly, decorate is 'make more attractive by adding ornament, colour, etc.' In Python, a decorator applies a wrapper to a function to provide it with some additional functionality. Which is certainly NOT decoration, since the point of decoration is that it is not functional! Plain bathroom tiles are functional. Decorating them with leaves or flowers or patterns is not functional. [snip] Now, if you are armed ONLY with the English definition, you will possibly run into some trouble, because the programming usage is a *specialization* of the term -- we strictly take only *one* of the English definitions to apply, and we narrow its meaning a bit. Yes. Every specialization has its own jargon, and computer programming is no different. One of the things new programmers have to learn is the jargon. [snip] lambda has no such advantage. Here's the *entire* gcide definition: Nonsense. All that means is that lambda in the programming sense is too specialized to make it into most ordinary dictionaries. Just like tuple. [snip] Think back to when you were a schoolboy at your first day of school. Unless you had a very unusual upbringing, you probably had never heard the word function before. Total BS. I knew the word function in it's English language sense, probably by the time I was 6. I *know* my kids know it. Okay, maybe my memories of being five are faulty. But if not six, then five, or four, or three, or two. At _some_time_ function was entirely unknown to you, and you had to just learn it. [snip] You had to learn that word, discover what it means, and then it becomes familiar. You don't notice the process only because it happened so long ago, at an age that your brain was operating in language acquisition mode and picking up vocabulary at an incredible rate. If you're arguing that language is acquired rather than innate, you are bludgeoning an obvious point. The point is that *jargon* should ideally derive in a natural way from commonly-used language, That's a bonus, sure. It is an important rule to follow, but not at the expense of distorting the language: t = immutable_list(L) map(anonymous_function x: x+1, L) versus: t = tuple(L) map(lambda x: x+1, L) if we want it to be easy to acquire for people who don't learn programming between the ages of 1 and 5 as we learn our native languages. Even in the 21st century, I think this includes just about all of us. ;-) If they can't memorize one or two things, they aren't going to be much good at programming no matter how easy the language is to use. There is nothing about the word string that especially brings to mind an array of bytes representing characters. The analogy of string of characters to string of beads breaks down as soon as you have multiple lines of text. Ah, but that's useful. Strings AREN'T multiple lines of text in the computer's memory, are they? '\n' is just another bead. The multiple lines is a representation, or way of laying out the beads. Very useful distinction, and immediately driven by the choice of analogy. Who cares about the implementation details of how the bytes are laid out in the computer's memory? Unless you are programming in a low level language like C or assembly, this is entirely irrelevant. You have characters laid out along lines, and lines laid out in a second dimension. The natural way to work with text is something like this: for line in text: for word in line: # or character do_something() [snip] I won't say that the anonymous function meaning of lambda comes to my mind before the Greek letter, but it isn't
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Tue, 05 Jul 2005 12:11:47 -0700, mcherm wrote: And besides, def isn't a magic word... it's an abreviation for define... Really? I thought it was an abbreviation for definition. As in, definition of MyFunc is... I hope that any student who didn't understand a word as common as define wouldn't have graduated from our school. How about tuple? -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: flatten(), [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
On Tue, 5 Jul 2005, Ron Adam wrote: Tom Anderson wrote: The trouble with these is that they make a lot of temporary lists - George's version does it with the recursive calls to flatten, and Ron's with the slicing and concatenating. How about a version which never makes new lists, only appends the base list? We can use recursion to root through the lists ... Ok... How about a non-recursive flatten in place? ;-) How about, er, oh, i give up. def flatten(seq): i = 0 while i!=len(seq): while isinstance(seq[i],list): seq.__setslice__(i,i+1,seq[i]) i+=1 return seq seq = [[1,2],[3],[],[4,[5,6]]] print flatten(seq) I think I'll be using the __setslice__ method more often. Um, can't you just do slice assignment? Make that line: seq[i:i+1] = seq[i] And the test: Stupendous and timely work! The results on Python 2.3.5: (maybe someone can try it on 2.4) recursive flatten: 23.6332723852 flatten in place-non recursive: 22.1817641628 recursive-no copies: 30.909762833 smallest recursive: 35.2678756658 non-recursive flatten in place without copies: 7.8551944451 GH! A 300% improvement!!! This shows the value of avoiding copies, recursion, and extra function calls. Specifically, it shows the value of avoiding extra function calls, since my zerocopy version is slower than the copy-happy single-function versions. Also, there are some differences between the functions which constitute potential hillocks on the playing field - i test flattenability by looking for an __iter__ method, whereas other implementations mostly ask instanceof list? (less general, and less in the spirit of duck typing, IMNERHO). I'd argue that my decomposition into functions is this sort of difference, too - a matter of style (good style!), not algorithm. So, levelling those differences, and throwing in my non-recursive zerocopy foolery, here's my take on it ... # # here be a quick reimplementation of timeit to time function objects # no exec for me no siree bob # all you need to know is that timeit(fn) gives you time taken to run fn import sys import time TIMERS = { win32: time.clock } timer = TIMERS.get(sys.platform, time.time) def timeit(fn, n=None): if (n == None): t = 0.1 n = 1 while (t 1.0): n = max(int((n * min((1.0 / t), 10))), (n + 1)) t = _timeit(fn, n) else: t = _timeit(fn, n) return t / n def _timeit(fn, n): it = xrange(n) t0 = timer() for i in it: fn() t1 = timer() return float((t1 - t0)) # there is real code now # i've rewritten the functions to use uniform variable names # and to use isiterable def isiterable(obj): return hasattr(obj, __iter__) def georges_recursive_flatten(seq): return reduce(_accum, seq, []) def _accum(a, item): if isiterable(item): a.extend(georges_recursive_flatten(item)) else: a.append(item) return a def rons_nonrecursive_flatten(seq): a = [] while seq: while isiterable(seq[0]): seq = seq[0] + seq[1:] a.append(seq.pop(0)) return a def toms_recursive_zerocopy_flatten(seq, a=[]): if (isiterable(seq)): for item in seq: toms_recursive_zerocopy_flatten(item, a) else: a.append(seq) return a def toms_iterative_zerocopy_flatten(seq): stack = [None] cur = iter(seq) a = [] while (cur != None): try: item = cur.next() if (isiterable(item)): stack.append(cur) cur = iter(item) else: a.append(item) except StopIteration: cur = stack.pop() return a def devans_smallest_recursive_flatten(seq): if (isiterable(seq)): return sum([devans_smallest_recursive_flatten(item) for item in seq], []) else: return [seq] def rons_nonrecursive_inplace_flatten(seq): i = 0 while (i != len(seq)): while (isiterable(seq[i])): seq[i:(i + 1)] = seq[i] # setslice takes iterators! i = i + 1 return seq flattens = [ georges_recursive_flatten, rons_nonrecursive_flatten, toms_recursive_zerocopy_flatten, toms_iterative_zerocopy_flatten, devans_smallest_recursive_flatten, rons_nonrecursive_inplace_flatten ] seq = [[1,2],[3],[],[4,[5,6]]] def timeflatten(flatten): return timeit(lambda: flatten(seq)) def funcname(fn): return fn.func_name print zip(map(funcname,
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Grant Edwards wrote: [EMAIL PROTECTED] wrote: So I'd say that it's a pretty obscure name that most people wouldn't know. I can't believe that anybody with any computer science background doesn't know it. Perhaps this reflects on the quality of education in the United States ;) but I managed to get a BS in Computer Science at the University of Arizona without ever seeing the word lambda (in the programming languages sense). However, I only took one class in programming languages, and it was more of a survey class than a theory class. When I did take a theory class, here at University of Colorado at Boulder, they did, of course, cover lambda calculus. But there was at least a year or two in which I would have considered myself somebody with any computer science background who wasn't familiar with lambda. OTOH, I fully agree with Peter Hansen: Really, the name is such a trivial, unimportant part of this whole thing that it's hardly worth discussing. STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Steven D'Aprano [EMAIL PROTECTED] wrote: On Tue, 05 Jul 2005 09:46:41 -0500, Terry Hancock wrote: [snip] Having said that, I too will miss the *concept* of an anonymous function, although I wouldn't mind at all if its name changed, or if it were somehow integrated into the def keyword's usage. Def would be short for ... defend? defile? defer? defame? default? deflect? There's always *something* to learn. Why def instead of define? Because easy to write beats instantly obvious to a beginner, if the word is used all the time and is easy to memorize. Still it's hard to explain why four specific python keywords - def, del, exec and elif - were chosen to be abbreviated, while all the rest are full words (http://docs.python.org/ref/keywords.html). Ease of typing is a joke for an excuse; finally is longer than define,delete and equally long to execute and else if (the latter has the even more serious flaw of going against TOOWTDI and in this case practicallity hardly beats purity IMO). In any case, python was never about minimizing keystrokes; theres another language that strives for this wink. So, who would object the full-word versions for python 3K ? def - define del - delete exec - execute elif - else if George -- http://mail.python.org/mailman/listinfo/python-list
Re: flatten(), [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]
Tom Anderson wrote: We really ought to do this benchmark with a bigger list as input - a few thousand elements, at least. But that would mean writing a function to generate random nested lists, and that would mean specifying parameters for the geometry of its nestedness, and that would mean exploring the dependence of the performance of each flatten on each parameter, and that would mean staying up until one, so i'm not going to do that. tom Without getting to picky, would this do? import random import time random.seed(time.time()) def rand_depth_sequence(seq): for n in range(len(seq)): start = random.randint(0,len(seq)-2) end = random.randint(start,start+3) seq[start:end]=[seq[start:end]] return seq seq = rand_depth_seq(range(100)) print seq [0, 1], 2, [3, [4, 5, 6]]], [7], [8, [[9, [], 10, [11, [12]], [[[, [[], [13, 14, 15]], [[[16, 17]]], [18], [[[19], 20, [[21, 22, [23]], [[24, 25, 26], [], [27, 28], [], 29, [], [30, [31, 32, 33]], [34], [[35]], 36, [[37, 38, 39], [[40, 41], [[42, [43, 44], 45, 46, [47, []], [[[48, 49], [50], [51]], 52], [[[53], [54, 55, [56, 57, 58]], []], [], []], [[59, 60, 61]], 62, [[63]], [], [64], [[[65]]], [[[66, 67, 68], [69, 70, [71, 72]], [[73, 74], [75, 76]]], [77, 78]], [], 79, 80, [[81], []], 82, [[[83, [[], 84], [85]], 86, [[87, 88]]], [[[89], 90, 91], [92, [93], [94, 95, 96, [97, [98, 99]]] -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Devan L wrote: Claiming that sum etc. do the same job is the whimper of someone who doesn't want to openly disagree with Guido. Could you give an example where sum cannot do the job(besides the previously mentioned product situation? Here's a couple of examples from my own code: # from a Banzhaf Power Index calculator # adds things that aren't numbers return reduce(operator.add, (VoteDistributionTable({0: 1, v: 1}) for v in electoral_votes)) # from a custom numeric class # converts a tuple of digits into a number mantissa = sign * reduce(lambda a, b: 10 * a + b, mantissa) Also, map is easily replaced. map(f1, sequence) == [f1(element) for element in sequence] There's also the issue of having to rewrite old code. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Dan Bishop wrote: There's also the issue of having to rewrite old code. It's Python 3000. You will have to rewrite old code regardless if reduce stays. -- Robert Kern [EMAIL PROTECTED] In the fields of hell where the grass grows high Are the graves of dreams allowed to die. -- Richard Harter -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Robert Kern wrote: Dan Bishop wrote: There's also the issue of having to rewrite old code. It's Python 3000. You will have to rewrite old code regardless if reduce stays. And from what I understand Python 2.x will still be maintained and supported. It will probably be more reliable than Python 3000 for a version or two as well. It's going to take time for all the batteries included to catch up, so it won't be like we have to all of a sudden rewrite all the old Python programs over night. We'll probably have a couple of years to do that to our own programs if we decide it's worth while. And if not, Python 2.x will still work. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Sun, 3 Jul 2005, Robert Kern wrote: Erik Max Francis wrote: Ron Adam wrote: So you are saying that anything that has a 1% use case should be included as a builtin function? I think I can find a few hundred other functions in the library that are used more than ten times as often as reduce. Should those be builtins too? This is a practical over purity issue, so what are the practical reasons for keeping it. It's already there isn't a practical reason. And it covers 100% of it's own potential use cases, is circular logic without a real underlying basis. But the Python 3000 plan, at least what we've heard of it so far, isn't to move it to a standard library module. It's to remove it altogether, replacing it with sum and product. Since sum and product don't cover all the uses cases for reduce, this is a case of taking one function that handles all the required use cases and replacing it with _two_ functions that don't. Since it's doubling the footprint of the reduce functionality, arguments about avoiding pollution are red herrings. Four, in fact. sum(), product(), any(), and all(). I'll just chip in and say i'd quite like a flatten(), too; at the moment, i have one like this: def flatten(ll): return reduce(lambda a, l: a.extend(l), ll, []) A builtin, which had fast special-case code for then the argument is a list of lists (rather than an iterable of iterables), would be nice, since this is a reasonably big use of reduce for me. How would one do that as a list comp, by the way? I'm really not very good with them yet. [1] Okay, there was that guy who predicted that list comprehensions and first-class functions were the next to go. That was new. But also wrong. I think we can discount that. True. Guido will only get rid of those after he's got rid of lowercase letters in identifiers. tom -- A military-industrial illusion of democracy -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Tom Anderson [EMAIL PROTECTED] wrote: I'll just chip in and say i'd quite like a flatten(), too; at the moment, i have one like this: def flatten(ll): return reduce(lambda a, l: a.extend(l), ll, []) This doesn't work; a.extend() returns None, not the extended list a: seq = [[1,2],[3],[],[4,[5,6]]] flatten(seq) AttributeError: 'NoneType' object has no attribute 'extend' This works for 1-level flattening: def flatten(ll): return reduce(lambda a, l: a.extend(l) or a, ll, []) flatten(seq) [1, 2, 3, 4, [5, 6]] And finally for recursive flattening: def flatten(seq): return reduce(_accum, seq, []) def _accum(seq, x): if isinstance(x,list): seq.extend(flatten(x)) else: seq.append(x) return seq flatten(seq) [1, 2, 3, 4, 5, 6] George -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Erik Max Francis wrote: Ron Adam wrote: In this case sum and product fulfill 90% (estimate of course) of reduces use cases. It may actually be as high as 99% for all I know. Or it may be less. Anyone care to try and put a real measurement on it? Well, reduce covers 100% of them, and it's one function, and it's already there. And it's almost two times slower: $ python -m timeit -s x = xrange(1000) sum(x) 1 loops, best of 3: 92.5 usec per loop $ python -m timeit -s from operator import add; x = xrange(1000) reduce(add, x) 1 loops, best of 3: 157 usec per loop And that's only if I have the sense to import from operator: $ python -m timeit -s x = xrange(1000); add = lambda x, y: x + y reduce(add, x) 1000 loops, best of 3: 587 usec per loop Note that the simple for-loop beats the case where you define your own function because it doesn't have the repeated overhead of function calls (which are expensive in Python): $ python -m timeit -s sum = 0; x = xrange(1000) for i in x: sum += i 1 loops, best of 3: 291 usec per loop What would really help here is if you could identify the cases where you think reduce is really a gain. A lot of them are actually not good practice in Python because of the function-call overhead. However, I'm willing to be convinced otherwise with a few good examples. STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Steven Bethard wrote: And it's almost two times slower: That's because you're not using operator.add. -- Erik Max Francis [EMAIL PROTECTED] http://www.alcyone.com/max/ San Jose, CA, USA 37 20 N 121 53 W AIM erikmaxfrancis Virtue has never been as respectable as money. -- Mark Twain -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
George Sakkis wrote: And finally for recursive flattening: def flatten(seq): return reduce(_accum, seq, []) def _accum(seq, x): if isinstance(x,list): seq.extend(flatten(x)) else: seq.append(x) return seq flatten(seq) [1, 2, 3, 4, 5, 6] George How about this for a non recursive flatten. def flatten(seq): s = [] while seq: while isinstance(seq[0],list): seq = seq[0]+seq[1:] s.append(seq.pop(0)) return s seq = [[1,2],[3],[],[4,[5,6]]] flatten(seq) Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Erik Max Francis wrote: Steven Bethard wrote: And it's almost two times slower: That's because you're not using operator.add. Huh? Please re-read my post. That's exactly what I used. STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Steven D'Aprano wrote: On Sat, 02 Jul 2005 20:26:31 -0700, Devan L wrote: Claiming that sum etc. do the same job is the whimper of someone who doesn't want to openly disagree with Guido. Could you give an example where sum cannot do the job(besides the previously mentioned product situation? There is an infinite number of potential lambdas, and therefore an infinite number of uses for reduce. sum only handles a single case, lambda x,y: x+y product adds a second case: lambda x,y: x*y So sum and product together cover precisely 2/infinity, or zero percent, of all possible uses of reduce. But together, sum and product, probably cover about 90% of situations in which you would use reduce. Getting a total (sum) from a list probably covers 80% of the situations reduce would be used on it's own. (I can't think of any real uses of product at the moment. It's late.) I'm just estimating, but I think that is the gist of adding those two in exchange for reduce. Not that they will replace all of reduce use cases, but that sum and product cover most situations and can be implemented more efficiently than using reduce or a for loop to do the same thing. The other situations can easily be done using for loops, so it's really not much of a loss. Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam wrote: But together, sum and product, probably cover about 90% of situations in which you would use reduce. Getting a total (sum) from a list probably covers 80% of the situations reduce would be used on it's own. (I can't think of any real uses of product at the moment. It's late.) It's not uncommon in mathematics to do repeated products. If you're familiar with the capital Greek letter sigma notation, if it's replaced with a capital Greek letter pi, then it's an iterated product, rather than an iterated sum: http://mathworld.wolfram.com/Product.html In general, pretty much _any_ operator can be replaced in this symbol to indicate a repeated operation. Function composition, set unions and intersections, logical conjunctions and disjunctions, direct sums and products, the list goes on and on. I'm just estimating, but I think that is the gist of adding those two in exchange for reduce. Not that they will replace all of reduce use cases, but that sum and product cover most situations and can be implemented more efficiently than using reduce or a for loop to do the same thing. The other situations can easily be done using for loops, so it's really not much of a loss. I really don't understand this reasoning. You essentially grant the position that reduce has a purpose, but you still seem to approve removing it. Let's grant your whole point and say that 90% of the use cases for reduce are covered by sum and product, and the other 10% are used by eggheads and are of almost no interest to programmers. But it still serves a purpose, and a useful one. That it's not of immediate use to anyone is an argument for moving it into a functional module (something I would have no serious objection to, though I don't see its necessity), not for removing it altogether! Why would you remove the functionality that already exists _and is being used_ just because? What harm does it do, vs. the benefit of leaving it in? I'm not myself a huge functional programming guy, but I'm certainly not in favor of the proposal to remove map, filter, reduce, and lambda. For map and filter, I can at least see the argument, because they truly are expressible with list comprehensions (which I do use myself, of course). lambda I also don't buy, but at least there, yes, you can just define a local function and use it locally, although I think expressively that it skirts the line between expressivity and verbosity (if you know what lambda is, straightforward use of lambda is not at all unclear, in fact it's quite clear). So at least there's something to that, but I don't follow it the whole way. But removing reduce is just removing functionality for no other reason, it seems, than spite. -- Erik Max Francis [EMAIL PROTECTED] http://www.alcyone.com/max/ San Jose, CA, USA 37 20 N 121 53 W AIM erikmaxfrancis Who knows whether any of us will be around in 1972? -- John F. Kennedy -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Sat, Jul 02, 2005 at 08:26:31PM -0700, Devan L wrote: Also, map is easily replaced. map(f1, sequence) == [f1(element) for element in sequence] How do you replace map(f1,sequence1, sequence2) especially if the sequences are of unequal length ? I didn't see it mentioned yet as a candidate for limbo, but the same question goes for: zip(sequence1,sequence2) -- Egbert Bouwman - Keizersgracht 197 II - 1016 DS Amsterdam - 020 6257991 -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Erik Max Francis wrote: Ron Adam wrote: I'm just estimating, but I think that is the gist of adding those two in exchange for reduce. Not that they will replace all of reduce use cases, but that sum and product cover most situations and can be implemented more efficiently than using reduce or a for loop to do the same thing. The other situations can easily be done using for loops, so it's really not much of a loss. I really don't understand this reasoning. You essentially grant the position that reduce has a purpose, but you still seem to approve removing it. Let's grant your whole point and say that 90% of the use cases for reduce are covered by sum and product, and the other 10% are used by eggheads and are of almost no interest to programmers. But it still serves a purpose, and a useful one. That it's not of immediate use to anyone is an argument for moving it into a functional module (something I would have no serious objection to, though I don't see its necessity), not for removing it altogether! Why would you remove the functionality that already exists _and is being used_ just because? What harm does it do, vs. the benefit of leaving it in? There are really two separate issues here. First on removing reduce: 1. There is no reason why reduce can't be put in a functional module or you can write the equivalent yourself. It's not that hard to do, so it isn't that big of a deal to not have it as a built in. 2. Reduce calls a function on every item in the list, so it's performance isn't much better than the equivalent code using a for-loop. *** (note, that list.sort() has the same problem. I would support replacing it with a sort that uses an optional 'order-list' as a sort key. I think it's performance could be increased a great deal by removing the function call reference. *** Second, the addition of sum product: 1. Sum, and less so Product, are fairly common operations so they have plenty of use case arguments for including them. 2. They don't need to call a pre-defined function between every item, so they can be completely handled internally by C code. They will be much much faster than equivalent code using reduce or a for-loop. This represents a speed increase for every program that totals or subtotals a list, or finds a product of a set. But removing reduce is just removing functionality for no other reason, it seems, than spite. No, not for spite. It's more a matter of increasing the over all performance and usefulness of Python without making it more complicated. In order to add new stuff that is better thought out, some things will need to be removed or else the language will continue to grow and be another visual basic. Having sum and product built in has a clear advantage in both performance and potential frequency of use, where as reduce doesn't have the same performance advantage and most poeple don't use it anyway, so why have it built in if sum and product are? Why not just code it as a function and put it in your own module? def reduce( f, seq): x = 0 for y in seq: x = f(x,y) return x But I suspect that most people would just do what I currently do and write the for-loop to do what they want directly instead of using lambda in reduce. x = 1 for y in seq: x = x**y If performance is needed while using reduce with very large lists or arrays, using the numeric module would be a much better solution. http://www-128.ibm.com/developerworks/linux/library/l-cpnum.html Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Christopher Subich wrote: One caevat that I just noticed, though -- with the for-solution, you do need to be careful about whether you're using a generator or list if you do not set an explicit initial value (and instead use the first value of 'sequence' as the start). The difference is: _accum = g.next() for i in g: _accum = stuff(_accum,i) versus _accum = g[0] for i in g[1:]: _accum = stuff(_accum,i) If you want to be general for all iterables (list, generators, etc), you can write the code like: itr = iter(g) _accum = itr.next() for i in itr: _accum = stuff(_accum, i) STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Steven D'Aprano [EMAIL PROTECTED] writes: I don't object to adding sum and product to the language. I don't object to adding zip. I don't object to list comps. Functional, er, functions are a good thing. We should have more of them, not less. Yes, but where should they go? Adding functions in the standard library is one thing. Adding builtins is another. Builtins make every python process heavier. This may not matter on your desktop, but Python gets used in embedded applications as well, and it does there. Builtins also clutter the namespace. Nothing really wrong with that, but it's unappealing. I'd say that removing functions is a bad thing. On the other hand, I'd say moving them from builtins to the standard library when Python has functionality that covers most of the use cases for them is a good thing. The latter has occured for map, filter, and reduce. Lambda I'm not so sure of, but it gets swept up with the same broom. Moving the first three into a library module seems like a good idea. I'm not sure about removing lambda. Removing map, filter and reduce remove most of my use cases for it. But not all of them. mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Mike Meyer wrote: I'd say that removing functions is a bad thing. On the other hand, I'd say moving them from builtins to the standard library when Python has functionality that covers most of the use cases for them is a good thing. We all can pretty much guess that map, filter, and reduce will be reimplemented in a functional module by a third party within mere seconds of Python 3000 being released :-). So it's really just a question of whether it will be let back in to the standard library as a module (rather than builtins) or not. Even granting the reasons for removing them as builtins, I really can't understand the motivation for removing them entirely, not even as a standard library module. -- Erik Max Francis [EMAIL PROTECTED] http://www.alcyone.com/max/ San Jose, CA, USA 37 20 N 121 53 W AIM erikmaxfrancis Golf is a good walk spoiled. -- Mark Twain -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam wrote: Each item needs to stand on it's own. It's a much stronger argument for removing something because something else fulfills it's need and is easier or faster to use than just saying we need x because we have y. In this case sum and product fulfill 90% (estimate of course) of reduces use cases. It may actually be as high as 99% for all I know. Or it may be less. Anyone care to try and put a real measurement on it? Well, reduce covers 100% of them, and it's one function, and it's already there. -- Erik Max Francis [EMAIL PROTECTED] http://www.alcyone.com/max/ San Jose, CA, USA 37 20 N 121 53 W AIM erikmaxfrancis I'm not jumping in / A wave that just passes -- Sandra St. Victor -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Erik Max Francis wrote: Ron Adam wrote: Each item needs to stand on it's own. It's a much stronger argument for removing something because something else fulfills it's need and is easier or faster to use than just saying we need x because we have y. In this case sum and product fulfill 90% (estimate of course) of reduces use cases. It may actually be as high as 99% for all I know. Or it may be less. Anyone care to try and put a real measurement on it? Well, reduce covers 100% of them, and it's one function, and it's already there. So you are saying that anything that has a 1% use case should be included as a builtin function? I think I can find a few hundred other functions in the library that are used more than ten times as often as reduce. Should those be builtins too? This is a practical over purity issue, so what are the practical reasons for keeping it. It's already there isn't a practical reason. And it covers 100% of it's own potential use cases, is circular logic without a real underlying basis. Cheers, Ron -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Ron Adam wrote: So you are saying that anything that has a 1% use case should be included as a builtin function? I think I can find a few hundred other functions in the library that are used more than ten times as often as reduce. Should those be builtins too? This is a practical over purity issue, so what are the practical reasons for keeping it. It's already there isn't a practical reason. And it covers 100% of it's own potential use cases, is circular logic without a real underlying basis. But the Python 3000 plan, at least what we've heard of it so far, isn't to move it to a standard library module. It's to remove it altogether, replacing it with sum and product. Since sum and product don't cover all the uses cases for reduce, this is a case of taking one function that handles all the required use cases and replacing it with _two_ functions that don't. Since it's doubling the footprint of the reduce functionality, arguments about avoiding pollution are red herrings. -- Erik Max Francis [EMAIL PROTECTED] http://www.alcyone.com/max/ San Jose, CA, USA 37 20 N 121 53 W AIM erikmaxfrancis Every astronaut who goes up knows the risks he or she faces. -- Sally Ride -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Mike Meyer wrote: Steven D'Aprano [EMAIL PROTECTED] writes: I don't object to adding sum and product to the language. I don't object to adding zip. I don't object to list comps. Functional, er, functions are a good thing. We should have more of them, not less. Yes, but where should they go? Adding functions in the standard library is one thing. Adding builtins is another. Builtins make every python process heavier. This may not matter on your desktop, but Python gets used in embedded applications as well, and it does there. Builtins also clutter the namespace. Nothing really wrong with that, but it's unappealing. I'd say that removing functions is a bad thing. On the other hand, I'd say moving them from builtins to the standard library when Python has functionality that covers most of the use cases for them is a good thing. The latter has occured for map, filter, and reduce. Lambda I'm not so sure of, but it gets swept up with the same broom. Moving the first three into a library module seems like a good idea. I'm not sure about removing lambda. Removing map, filter and reduce remove most of my use cases for it. But not all of them. Metoobe!!! Practicality beats purity: I am perfectly happy to have list comps in the language and fast, efficient functional programming tools in a module. I'm even happy to see sum and product and zip as builtins, even though logically they belong with map and reduce in the (hypothetical) functional module. I know Python isn't, and never will be, a purely functional language. But being able to use some functional techniques is good, and shouldn't be lost. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Erik Max Francis wrote: Ron Adam wrote: So you are saying that anything that has a 1% use case should be included as a builtin function? I think I can find a few hundred other functions in the library that are used more than ten times as often as reduce. Should those be builtins too? This is a practical over purity issue, so what are the practical reasons for keeping it. It's already there isn't a practical reason. And it covers 100% of it's own potential use cases, is circular logic without a real underlying basis. But the Python 3000 plan, at least what we've heard of it so far, isn't to move it to a standard library module. It's to remove it altogether, replacing it with sum and product. Since sum and product don't cover all the uses cases for reduce, this is a case of taking one function that handles all the required use cases and replacing it with _two_ functions that don't. Since it's doubling the footprint of the reduce functionality, arguments about avoiding pollution are red herrings. Four, in fact. sum(), product(), any(), and all(). The problem with this discussion is that no one is saying anything new[1]. We've heard all of the arguments for and against removing these functions. Over and over and over again. They're not changing anyone's mind, not yours, not mine, and definitely not Guido's. And it's not even like Python 3000 is around the corner or in any stage of concrete planning. Adding our voices to the chorus *now* won't make a bit of difference, nor should it. The size of the chorus doesn't matter; Python isn't developed by votes. We tried that once before; it didn't work so well. When planning for Python 3000 really gets going, when Guido gets a year's sabbatical to work on it, when we can see how map/filter/reduce/lambda fit into the whole scheme of how this new language works, *then* is the time to be having these discussions. Right now, all we're doing is making each other bitter and angry for no good reason. [1] Okay, there was that guy who predicted that list comprehensions and first-class functions were the next to go. That was new. But also wrong. I think we can discount that. -- Robert Kern [EMAIL PROTECTED] In the fields of hell where the grass grows high Are the graves of dreams allowed to die. -- Richard Harter -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Tom Anderson wrote: So, if you're a pythonista who loves map and lambda, and disagrees with Guido, what's your background? Functional or not? I have no functional language background. Until recently, I had no use for programming expression to be evaluated later or deferred expressions or whatever else they are being called. Where I came to see the awesomeness of deferred expressions was a few months ago when I started a major rewrite of KirbyBase for Ruby. I wanted to make the Ruby version of KirbyBase take advantage of the strengths of the language. Another Ruby programmer, Hal Fulton, was helping me by constantly pushing me to make KirbyBase more Ruby-ish. One thing he kept pushing was to be able to specify select querys using Ruby's deferred expression mechanism, code blocks (before anyone starts yelling, I know that Ruby code blocks are *much* more than just deferred expressions; I'm just using that descriptor here for the sake of this discussion). Code blocks allow you to wrap up any Ruby code and pass it to a method and have it executed within that method. It is more powerful than lambda, because you can have multiple statements in the code block and you can do assignment within the code block. This allowed me to rewrite KirbyBase so that you can do a select like this: plane_tbl.select { |r| r.country == 'USA' and r.speed 350 } Now, this is cool, but you can do this using lambda in Python. Where Ruby code blocks really shine is that you can also do this: plane_tbl.update {|r| r.name == 'P-51'}.set {|r| r.speed = 405 r.range = 1210 } I have one code block that I pass to the update method which says Select all planes with name equal to P-51. Then, I pass a code block to the set method which assigns new values to the speed and range fields for those records (i.e. P-51) that were selected in the update method. This is something you can't do with lambda. Now, I think I can duplicate the same functionality of Ruby code blocks by using Python functions, but it is not going to be as pretty. So, even though lambda is not as powerful as Ruby code blocks, I was still bummed to read that it is going away, because it is better than nothing. Hopefully, Guido will reconsider or, even better, give us something even more powerful. Jamey Cribbs -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
Jamey Cribbs [EMAIL PROTECTED] writes: Code blocks allow you to wrap up any Ruby code and pass it to a method and have it executed within that method. It is more powerful than lambda, because you can have multiple statements in the code block and you can do assignment within the code block. Just FYI, the inability to have statements - even multiple statements - in a lambda is what people are talking about when they talk about the limitations of lambda. It's a common thing for someone with a background that includes a proper lambda to trip over when they first start programming in Python. It's not that uncommon for newcommers to trip over it with print. mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Fri, 01 Jul 2005 09:13:58 -0700, mcherm wrote: Lambda serves a very specific purpose: declaring small, in-place functions which are no bigger than a single expression. I do this often enough that I DO want special syntax for it. But I'll admit that I wish lambda were about 5 or 6 characters shorter As in an empty string? :-) and didn't have such an obscure name. Lambda is no more an obscure name than function, decorator, closure, class, or module. The first time you come across it, you don't know what it means. Then you learn what it means, and then you know. -- Steve -- http://mail.python.org/mailman/listinfo/python-list
Re: map/filter/reduce/lambda opinions and background unscientific mini-survey
On Fri, 01 Jul 2005 13:42:10 -0400, Mike Meyer wrote: iK [EMAIL PROTECTED] writes: Seems like he wants python programmers to solve their problems all in the same way. While that is great for corporate slaves it is terrible for the creative programmer. No, he wants Python to be Pythonic. TMTOWTDI is not Pythonic. Too Many T--- Only Way To Do It? There Might Tangle One Way To Do It? T--- M--- Two Obvious Ways To Do It? Nope, sorry, still not getting it. Python is quickly becoming the visual basic of the 21 century. If you want to have fun while getting some work done you need to look elsewhere. It's a shame... If you'd rather spend your time figuring out which of multiple ways to do things is the best for the job at hand than producing code, there's a language that makes TMTOWTDI a way of life. Figuring out which of multiple ways to do things is the best for the job at hand _is_ part of producing code. There will always be multiple ways to do the job. For starters, there is the choice, which language should I use? Top-Down or Bottom-Up design? Test-driven or not? For loop or list comprehension or generator? Procedural programming or object-oriented or a mixture of both? Singleton or Borg design pattern? Test your data first or deal with the exceptions when they happen? And so on. Only One Obvious Way makes a nice slogan, but it is easy to turn a flexible language like Python into a straight-jacket where there is Only One Way To Do It Regards Of Whether It Is The Best For The Job On Hand Or Not. Not such a short and concise slogan. Now that Python has list comps, should for loops be removed from the language? Why did Python bother introducing list comps when there is nothing they can do that a for loop can't? Functional programming using map etc does require a slightly different way of thinking about programming than does procedural programming, just as object-oriented needs a different way of thinking than spaghetti-coding using GOTOs. Different ways of thinking about programming should be encouraged, not discouraged. Even the much-maligned GOTO has its modern usage case: the Exception. If map/filter/reduce have to be removed from the built-ins, and I don't think they should, I'd prefer for them to be moved into a module rather than dropped altogether. Provided list comps are made as fast as map and filter, then at the cost of readability they can be replaced by list comps. But reduce can't be written as a list comp, only as a relatively complex for loop at a HUGE loss of readability -- and I've never used Lisp or Scheme in my life. I'm surely not the only one. -- Steven -- http://mail.python.org/mailman/listinfo/python-list