from multiprocessing import Pool
p = Pool(5)
def f(x):
return x*x
p.map(f, [1,2,3])
I do not have direct experience with the library, but from what I've seen, the code you would write is not significantly different from the code you'd write using a decent multithreading interface.Why I chose Common Lisp over Python, Ruby, and Clojure
11–20 of 143 posts
Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#12Basically: I started with my conclusion, and then went through all the other options and rationalized them away until it seemed like my choice was based on objective reasoning.
I freely admit my personal biases and experiences eliminated a lot of potentially good options without ever giving them due consideration (e.g., Haskell, Scheme, Lua). But I really did try to give the 3 options listed in the article a fair shake at the time.
For what it's worth - I was about 50-50 on using Python till the very end ...
Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#13Basically: I started with my conclusion, and then went through all the other options and rationalized them away until it seemed like my choice was based on objective reasoning.
Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#14Basically: I started with my conclusion, and then went through all the other options and rationalized them away until it seemed like my choice was based on objective reasoning.
Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#15The fact that he proposed removing map, reduce, filter, and lambda from Python 3. In the case of map and filter, is there any compelling reason to use either of those instead of list comprehensions or generator expressions?
A single, non-nested list comprehension or generator exp is basically map(filter). You need nesting to get filter(map). e.g. map(expensive_call, filter(cond, seq)) equals [expensive_call(each) for each in seq if cond(each)] but filter(cond, map(expensive_call, seq)) equals [each for each in [expensive_call(x) for x in seq] if cond(each)] note because of "expensive_call", it's inefficient (and silly) to do [expensive_…
filtered = [x for x in seq if x>10]
Python's list comprehension is much more readable than using map/filter/reduce - at least for Python programmers :) Anyhow, I really like Guido's decision on dropping these - it creates a cleaner language and forces people to think Pythonic when programming in Python.Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#16Before learning CL I was a fairly decent, C, C++ and Perl programmer. Did assembly, Pascal, TCL and Awk. Up to that point, I always had to pause a for a minute when starting a new project/script, think about its scope, and choose a language based on the necessary performance, development speed, expressiveness, available libraries, etc. (and whether whoever was going to read the code afterward knew the language; C was often a natural choice for code shared with others on Unix, C++ for MFC/COM, Perl for sysadmin stuff, and TCL and Awk for my own tools.)
I learned Lisp in over a month, to spite someone (I dared a notorious troll I would write an AI bot of his choice if he stopped spamming us, youthful bravado for sure, and I lost the bet) While researching "AI" I came across Winston and Horn's "Common Lisp", then the hyperspec, then a few more books over the course of a month. I sat down with SICP and did the exercises on my break, while I was in school and waiting tables.
After I learned it however, specially with CLOS, there was no contest. Three months after buying Sonya Keene's CLOS book it was fair to say I forgot all other programming languages. There were no more "projects"; I no longer had to sketch out designs on paper or do "requirement analysis" (something I was told in school was necessary for all software.) For once, the great ideas in my head were a new emacs buffer away. I could write code faster than I would in Perl, Awk or TCL, it ran as fast as C++, and it was more expressive than the English in my head. I could type "commands" into a shell get a dialog embedded in my window, a few more commands and it would move to the upper right corner, I could change its name property and add text to it, then I could fold that dialog box into a menu-item named "Help" in the menubar and call that dialogbox "About". Amazing.
I went on hacking like this for about year when I realized I was doing the "wrong thing". You see, I have been using CMUCL with its builtin editor and writing GUI applications in Motif (it was 2001 and Motif wasn't open source yet, so I got the hang on Lesstif and learned its quirks.) Right around this time, Linux GUIs were maturing and people were being snobs about their Enlightenment themes and dissing each other over their choices of Windows Manager. So I was peer-pressured into learning DHTML and Web Design. I read comp.lang.lisp and those too were snobbish condescending idiots who flamed everyone, specially competent programmers whose work I admired (including Scott McKay and Robert Fahlman (the very people who gave me my CMUCL.))
It was really hard to be a Lisper for a while, specially a young impressionable one who read cll uncritically; news of corporate giants coming with new tools and programming languages to enslave humanity were abound. First C++, then Java, then XML, and finally .NET. You literally had to pick your battles and choose a corporate sponsor or you would have no future in computing! (you think I am kidding?) cll is all doom and gloom, and of course, there is the obligatory stabs at Lisp vendors by Open Source proponents, and stabs at Open Source for people alleging it's killing our beloved vendors. Every once in a while there was news of a Lisp dialect that's going to kill Common Lisp (Smalltalk, Dylan, and the ancient religions of Mesopotamia.)
Fuck, that was painful.
All the while I was following this 4-year long intellectual funeral, becoming ever more "hardcore" and learning mathematics, there was a small group of "Yobos" silently kicking ass and churning out great software. CMUCL got forked to SBCL, added unicode support and threads, not to mention easy building, SLIME was a new Emacs mode better than anything before and since, Cliki was launched, C-L.net, and the #lisp IRC channel was born and hit puberty overnight. Perfect ecosystem.
Today, Lisp is nothing like what it was 8,7,6, even 2 years ago. It's not just "good" in the well-explored text book fashion; no, it's _good shit_. Get work done good. Think, hack, ship, bill for it good. 2-3 products per month good. You still have to know where things are, who is working on what, what's maintained and what's obsoleted by what. Sure. But there is absolutely no lack of libraries.
Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#17Earlier quoted context omitted.
A single, non-nested list comprehension or generator exp is basically map(filter). You need nesting to get filter(map). e.g. map(expensive_call, filter(cond, seq)) equals [expensive_call(each) for each in seq if cond(each)] but filter(cond, map(expensive_call, seq)) equals [each for each in [expensive_call(x) for x in seq] if cond(each)] note because of "expensive_call", it's inefficient (and silly) to do [expensive_…
Most times you are interested in doing the simple, e.g.: filtered = [x for x in seq if x>10] Python's list comprehension is much more readable than using map/filter/reduce - at least for Python programmers :) Anyhow, I really like Guido's decision on dropping these - it creates a cleaner language and forces people to think Pythonic when programming in Python.
For simple cases, yes. But I wouldn't say
[each for each in [expensive_call(x) for x in seq] if cond(each)]
is more readable than filter(cond, map(expensive_call, seq))
at least for functional-thinking minds. The level of thinking in abstract is different here.Now the problem is, some people see Python as a very functional language (with first-class functions etc) and want to use it that way (like Lisp), but BDFL and some core Python devs believe it is better to keep it Pythonic, thus those functional people are kinda pissed off by this and switch away from Python.
Personally I don't think it will make Python a lot cleaner to remove two auxiliary functions and force people to use list comprehension when it is completely trivial to add these missing pair back (two lines of code).
(disclosure: I prefer FP, but I also think keeping things Pythonic is fine most of the time. It's just that in this case, I think map/filter is pretty "Pythonic" according to me. :)
Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#18Did you really choose Lisp over alternatives? Before learning CL I was a fairly decent, C, C++ and Perl programmer. Did assembly, Pascal, TCL and Awk. Up to that point, I always had to pause a for a minute when starting a new project/script, think about its scope, and choose a language based on the necessary performance, development speed, expressiveness, available libraries, etc. (and whether whoever was going to re…
Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#19Earlier quoted context omitted.
Most times you are interested in doing the simple, e.g.: filtered = [x for x in seq if x>10] Python's list comprehension is much more readable than using map/filter/reduce - at least for Python programmers :) Anyhow, I really like Guido's decision on dropping these - it creates a cleaner language and forces people to think Pythonic when programming in Python.
> Python's list comprehension is much more readable than using map/filter/reduce - at least for Python programmers For simple cases, yes. But I wouldn't say [each for each in [expensive_call(x) for x in seq] if cond(each)] is more readable than filter(cond, map(expensive_call, seq)) at least for functional-thinking minds. The level of thinking in abstract is different here. Now the problem is, some people see Python…
Re: Why I chose Common Lisp over Python, Ruby, and Clojure
#20The fact that he proposed removing map, reduce, filter, and lambda from Python 3. In the case of map and filter, is there any compelling reason to use either of those instead of list comprehensions or generator expressions?
A single, non-nested list comprehension or generator exp is basically map(filter). You need nesting to get filter(map). e.g. map(expensive_call, filter(cond, seq)) equals [expensive_call(each) for each in seq if cond(each)] but filter(cond, map(expensive_call, seq)) equals [each for each in [expensive_call(x) for x in seq] if cond(each)] note because of "expensive_call", it's inefficient (and silly) to do [expensive_…
(filter (map expensive_call X) cond)
So do list comprehensions: [y for y in [expensive_call(x) for x in X] if cond(y)]
Near as I can tell, the only difference is that list comprehensions also provide a syntactic sugar for the convenience function filter_then_map. Sometimes this saves you a level of nesting, sometimes not.Incidentally, this isn't even an issue in a pure functional language with sufficiently smart compiler.