8 ms·
all i could think of is "stop writing python". it seems to me that a lot of these problems are fundamental problems with python. i continue to not understand wh
by nikofeyn 8y ago
all i could think of is "stop writing python". it seems to me that a lot of these problems are fundamental problems with python. i continue to not understand why anybody likes python the language.
the fact that creating a function with lambda versus the normal way is different is bonkers. for example, in f# (and other sane languages), the following are identical:
let test1 = fun x -> x * x
let test2 x = x * x
both return:
x:int -> int
are they really different in python or is it just a weird naming problem? the article isn't explicit on the actual differences other than what is reported by the REPL.
also, you can't pass operators as functions in python? in f#, you simply wrap them in parentheses.
let test3 f x y = f x y
> test3 (*) 2 3 ;;
val it : int = 6
i read an interview with hal abelson where he called python's lambda broken. seems so.
edit: also, this guy's thoughts on map and filter, in my opinion, show the python community's backwoods thinking regarding functional programming. yes, it seems generator expressions are nice (they are called sequence expressions in f#), but map and filter, even for his simple examples are much more clear. they communicate better what is actually happening. the fact that he never uses map and filter at all and then goes on to basically say map and filter aren't even needed in python says a lot.
- tincholio 8y agoAmen, brother. I'm not proficient in Python, but from my (admittedly, limited) experience with it, it feels like programming with a straightjacket on.
- furgooswft13 8y agoIt is, and that's the point. The Python community coined TOOWTDI (there's only one way to do it) in response to Perl's "There's more than one way to do it". What that way is seems to be "what even the most clueless programmer could reasonably understand". This to the point where even the adoption of a concept as common as assignment expressions was met with a community shitstorm. It seems like a language designed for people who really have no interest in craft of programming, and just use it as a means to an end (note I'm not saying there's anything wrong with this, but if your career is in programming, and you keep that attitude, I'd suggest you find another one or move to management, you're not gonna be happy).
- orn688 8y agoTo be honest, I feel like Python's philosophy makes it easier to focus on the "craft" of programming; instead of worrying about small details like how to iterate through a collection, I'm able to just do it the boring-but-effective Pythonic way and move on to higher-level details of the program. So I guess I'm not strictly disagreeing with you, but I think the craft of programming is about far more than just how your code looks, and I find Python to be excellent for pursuing those other areas of craftsmanship.
- furgooswft13 8y agoI suppose so, but the higher level details of a program will often follow from the nature of the language you are coding it in. I know a lot of my code would be "architected" differently if the language I was working in had a general disdain for passing anonymous functions around, and I don't think it would end up as effective. And finding new more effective ways to do common things, new tricks so to speak, is important in keeping the mind engaged. The tools might not be as important as the end product, but for the person who is always using those tools, being able to improve and customize them to their liking is extremely important. I guess the difference is a programming language is less a tool than an end product in itself, that needs to be able to be understood and modified by other people. As opposed to say, a plumbers preferred toolset, of which no trace will be left when the next person comes to do the job.
- zmmmmm 8y ago> It seems like a language designed for people who really have no interest in craft of programming, and just use it as a means to an end It's kind of funny how much that echos the past criticisms of Java - a language lacking in all kinds of features that frustrate advanced programmers. Yet Python's popularity was in many ways a reaction against Java - perhaps for other reasons.
- jjnoakes 8y agoIn F#, can you ask a function object what its original name was? If so, what is the original name of "test1" and "test2" in your example? That's what python is doing and why the two are different. (I don't think a language should track that sort of thing, but that's a different story).
- nikofeyn 8y agoi am not for sure what you mean by "original name". the value of each of those function definitions are: val test1 : x:int -> int val test2 : x:int -> int you call them the same way, and they have the same type. a caller has no knowledge of how they were defined because it isn't important. they're identical.
- yorwba 8y ago> they're identical. Does that mean that test1 == test2 will return true? Personally, I have found it very useful for debugging that function objects in Python carry their name. That makes it much easier to find out where something is coming from.
- jjnoakes 8y agoI mean in python, one can ask a function what it was originally defined as. Sounds like in F# one can not, so that's why there's a difference in python between "var x = lambda..." and "def y(): ..."; the latter knows it is named "y" and the former has no idea what its name is (so it is "lambda").
- JasonFruit 8y agoNobody really likes Python the language especially much, but lots of people love Python the ecosystem, because it lets them get stuff done. I can think of a dozen languages I like better than Python, but none that's more practical in as many different contexts. -------------------- Edit: Apparently, there are some people who do like Python the language, and some people who dislike Python the ecosystem. If you want to find a thing, just say it doesn't exist, and it will find you.
- alexchamberlain 8y agoI disagree... I came for the syntax and readability; I've stayed for the community.
- JasonFruit 8y agoI suppose I like the readability too, but there are a number of things about the language I would rather had been done differently; I still insist that its approach to scope is worse than any choice except making everything global.
- alexchamberlain 8y agoI tend to recommend people refavtor their functions into smaller ones if scope is not clear, but I accept it's different from many of its predecessors.
- AlexCoventry 8y agoIf the local/ global scooping rules are hurting you that much, you are probably putting more state in module-level variables than is healthy.
- JasonFruit 8y agoIt's not that: it's the hobbled function scope that doesn't handle nested functions the way I would expect and hope.
- 8y ago
- theamk 8y agoOne of the python motto's is "explicit is better than implicit". Not having to pattern-parse the structures makes programs much easier to read for some people (lke me). But the point is, even with f# syntax, most of the blog post would still apply (needless function calls, non-trivial functions, multiline-unpacking and so on) I do not agree with some of the premises of this post, but saying that changing lambda syntax will somehow help is just not true.
- nikofeyn 8y ago> I do not agree with some of the premises of this post, but saying that changing lambda syntax will somehow help is just not true. i wasn't really suggesting changing the syntax would help (although the confusion here is more semantic than syntactic). i was pointing out that in other languages, like in f#, things are much more clear than in python. the section mentioning the name thing is still not clear to me (in python) in terms of what exactly the differences are, and that was my point. that exists a lot in python.
- pdonis 8y ago> i continue to not understand why anybody likes python the language Here are some reasons why I like it: It's cleaner to read because there aren't curly braces and semicolons cluttering up the code. It's cleaner to write because the expressions are simpler and look like something readable instead of line noise. It has a REPL, so it's easy to experiment. It doesn't force me to write boilerplate code, such as types for every variable declaration or everything having to be a class or huge amounts of scaffolding just to write "Hello, world!". I'm sure I could think of more, but those are what come to mind on the spur of the moment.
- nikofeyn 8y agof# (and also ocaml and sml) have all those and much more. they are much more consistent and principled in their design, which makes things simpler to understand. for example, in all three languages above, expressions are much easier to understand because they always return a value. this makes code easier to reason about. this is not true in python. the languages i mentioned do have static typing but they have type inference. so you get the best of both worlds. you do need to type annotate at some points to clarify things, but this isn't a problem as it documents to both the user and compiler. given your above reasons, you owe it to yourself to learn an ml. there is the programming languages course on coursera by dan grossman, which uses sml in the first part, and the ocaml mooc just started where you still have time to register and complete it. https://www.coursera.org/learn/programming-languages https://www.coursera.org/learn/programming-languages https://www.fun-mooc.fr/courses/course-v1:parisdiderot+56002+session03/about https://www.fun-mooc.fr/courses/course-v1:parisdiderot+56002...
- pdonis 8y ago> f# (and also ocaml and sml) have all those and much more F# has curly braces. Also, as you say, it requires some type annotations. I see that F# has a REPL, but it seems bolted on as an afterthought instead of being an integral part of the language. (Also, it's not clear whether the REPL is available in Mono on Linux. I am allergic to Windows and anything built by Microsoft.) > expressions are much easier to understand because they always return a value. this makes code easier to reason about. this is not true in python Huh? Python expressions always return a value. Perhaps what you mean is that Python also has statements, which do not return a value, whereas these languages do not--everything is an expression, as in Lisp? > you owe it to yourself to learn an ml I don't owe it to myself to learn anything unless I decide to. I wasn't trying to convince anyone else to use Python; I was just giving reasons why I like Python. Please extend me the same courtesy when you talk about things you like about your favorite languages.
- pdonis 8y ago> i read an interview with hal abelson where he called python's lambda broken Can you give a link? I'd be interested to read it.
- DavidTNcl 8y ago"You have to contend with Python’s broken notion of lambda but other than that it’s not really that different" http://www.gigamonkeys.com/code-quarterly/2011/hal-abelson/ http://www.gigamonkeys.com/code-quarterly/2011/hal-abelson/
- nikofeyn 8y agosure. here you go. http://www.gigamonkeys.com/code-quarterly/2011/hal-abelson/ http://www.gigamonkeys.com/code-quarterly/2011/hal-abelson/ the paragraph he says it in is: > It’s just a different course. We could have done it in Scheme and I sort of wish we had. And for random reasons we didn’t. But the thing that ties it together—if you had fifteen seconds to describe the whole course—it’s still about abstraction and modularity. The beginning of that course is not very different from the beginning of 6.001 other than you do it in Python. But at that point, where you’re not building interpreters yet, you can pretty much do this stuff in Python. You have to contend with Python’s broken notion of lambda but other than that it’s not really that different. he mentions it as an aside really, but the overall interview itself is very good. abelson is a treat to listen to.
- pdonis 8y agoThanks for the link. The paragraph you quote makes me think he is comparing Python's lambda to Scheme's equivalent, which of course will make Python's lambda seem broken. IIRC the course was taught in Scheme at one time, but it switched to Python because it seemed easier for students to grasp the basics that way.
- dreamcompiler 8y agoIt's not just Scheme; in Common Lisp and Haskell and every other language that supports lambda, lambda is a first-class construct that is used all the time. Python's lambda feels like a war veteran that had its legs blown off. Best policy is probably just to pretend it's not in the language.
- detaro 8y agoI'm not sure what you mean by the first half of your comment. Both def and lambda create functions, and quoting from the article "Lambda expressions are just a special syntax for making functions. They can only have one statement in them and they return the result of that statement automatically.". def binds it to a name at the same time, which is remembered in the object (which AFAIK isn't really used for anything except maybe debugging tools), lambda returns an anonymous one. The resulting object can be passed around in both cases.
- nikofeyn 8y agoit's because i am not that deeply familiar with python and the article is not clear itself on this. what is he complaining about then if they are identical in what's returned? is it simply because the REPL returns <lambda> instead of the function name? why does the REPL do this? are they different in some subtle way? the point was in something like f#, lambda creates a function which can then be bound to a name if you want. if you do so, this is identical to the "normal" function definition because that is really just syntactic sugar for creating lambda functions and then binding it to a name.
- detaro 8y agoSince the objects are identical type, you could set a doc string and a name on a lambda (they're just properties of the object) and see them during program execution/on the REPL, might make sense for generated stuff like classes from an ORM?
- dragonwriter 8y ago> is it simply because the REPL returns <lambda> instead of the function name? why does the REPL do this? Because lambdas don't have function names.
- nikofeyn 8y agoi know that. in the example, he assigned the lambda to normalize_case.
- weliketocode 8y agoYour examples don't seem that great, to be frank. The lambda syntax isn't that different from the syntax for defining functions, unless you're referring to the fact that it's different than anonymous functions in other languages. I don't find the inability to pass around operators to be a hindrance, but the fact that getting into python requires understanding all of these dunder or magic methods is another story. However, on map, filter, & reduce, I agree with you completely. One of the worst aspects of python is the extensive use of bad practices, and ignoring functional programming principles is one of the top offenses.
- nikofeyn 8y ago> Your examples don't seem that great, to be frank. they weren't intended to be great or mind blowing. they were just examples to make the point that in a good language, it's clear what is going on. the operator thing is an extension of that. in f#, the "infixness" is just a syntax thing. the semantics is that they are functions and can be treated as such. it seems operators are something weird in python.
- sp332 8y agoGuido van Rossum was explicitly against functional programming (well, in the Python language anyway). It's an imperative, object-oriented language that eventually threw functional programmers a bone with map, reduce, and filter, and that's about it.
- eesmith 8y agoCould you elaborate further? I wasn't there then, but what you wrote doesn't agree with my understanding. Lambda, map, reduce, and filter were part of the Python 1.0 release. The actual commit date was Tue Oct 26 17:58:25 1993 +0000: commit 12d12c5faf4d770160b7975b54e8f9b12694e012 Author: Guido van Rossum <guido@python.org> Date: Tue Oct 26 17:58:25 1993 +0000 * compile.[ch]: support for lambda() * PROTO.h, mymalloc.h: added #ifdefs for TURBOC and GNUC. * allobjects.h: added #include "rangeobject.h" * Grammar: added lambda_input; relaxed syntax for exec. * bltinmodule.c: added bagof, map, reduce, lambda, xrange. * tupleobject.[ch]: added resizetuple(). * rangeobject.[ch]: new object type to speed up range operations (not convinced this is needed!!!) You can see the commit had its doubts about xrange, but said nothing negative of the functional programming aspects. Van Rossum described that history at https://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html https://python-history.blogspot.com/2009/04/origins-of-pytho... . I don't see anything which sounds like "throwing a bone", much less being "explicitly against functional programming" when that discussion occurred. My understanding is that he wasn't opposed to their inclusion initially but became negative towards them only years later.
- sp332 8y agoThanks, I'm probably misremembering some argument that I last heard about around 2000-2004, probably involving list comprehensions and why lambdas weren't more powerful.
- Roboprog 8y agoRe: use of map / filter type stuff. Yep. Had a coworker like that recently. Loved “simple” code, chock full of mutable data everywhere, where everything was written out a good 3 or 4 times longer than I would have liked to see it. I call that sort of “simple, explicit” (repetitive) code “My Summer Vacation” code, after a bit in an old Cheech and Chong skit where the highschool kids have to read their essays to the class.
- rjeli 8y agoSimple and explicit code? sounds easy to read and debug!
- djaychela 8y ago"i continue to not understand why anybody likes python the language." As someone who has had a lifetime of on-off relationships with attempting to become a competent programmer, (BASIC, assembler, C, Pascal, Visual Basic, C++ and others that I can no longer remember), Python is the only language that has helped me become anywhere near useful or proficient as a programmer. I've managed to build a couple of -genuinely useful- applications (one of which is being used daily in my girlfriend's school), which hasn't been the case for anything else. I've found that Python is simple enough to learn, and hasn't really been any kind of a limitation for me - this may be because of me, not the language - OK, I appreciate that I'm not going to be writing 3D games or real-time audio apps in it, but for what I've been trying to do (solve real-world problems), it's been amazing. I even programmed a 'play sound effects when you press a MIDI controller' system which I used at a show with 20,000 people attending this summer, replacing a massively over-complex (and expensive) audio environment with about 30 lines of Python combined with two libraries I spent an afternoon learning. That, for me, is why I like Python.
- paulddraper 8y ago> I'm not going to be writing 3D games or real-time audio apps in it, but for what I've been trying to do (solve real-world problems) TIL 3D games and real-time audio apps are not "real-world problems".
- thaumasiotes 8y agoI think the idea is that python is appropriate for solutions to some problems that are "real" problems (as opposed to being valuable purely as a toy) -- not that python is appropriate for solutions to EVERY "real" problem, and any problem that python would be a poor choice for isn't a "real" problem.
- djaychela 8y agoExactly! Looks like the 'deliberately take umbrage over a specific interpretation of what you've written' crew have arrived. Clearly I didn't mean 3D or audio apps aren't real world problems, I meant I can solve (some) real world problems with Python.
- a-nikolaev 8y agoI agree with you, I felt the same when reading the article. It feels that Python's design is deeply at fault here, it is actively harming people's perception of anonymous functions, which is the opposite of what a supposedly educational multi-paradigm-capable language should be doing.
- eesmith 8y agoIt also doesn't have tail-recursion or macros. There are many who also regard that lack as a deep design flaw. There never was a goal in Python development to support all programming paradigms. How do you distinguish between "design flaw" and "different design goal than what you want"?
- a-nikolaev 8y agoI think, it was an example of intentional hostile design (say, see this video https://www.youtube.com/watch?v=NWZLB8CyPbM https://www.youtube.com/watch?v=NWZLB8CyPbM for what I mean). All, seemingly for the sake of that "only-one-way-to-do-things" goal. EDIT: (Van Rossum's own explanation of why he thinks lambda's design is okay: https://www.artima.com/weblogs/viewpost.jsp?thread=147358 https://www.artima.com/weblogs/viewpost.jsp?thread=147358 )
- eesmith 8y agoDo you have any evidence for your hypothesis about hostile design? The phrase, by the way, is "one obvious way".
- a-nikolaev 8y agoGuido van Rossum said that many times that he does not like functional primitives. It is pretty well documented in his own writing that he had no intention of making functional programming very convenient in the language.
- FridgeSeal 8y agoGuido seemingly has a strong distaste for functional ideas, so anything that comes from that paradigm ends up getting an almost half-assed implementation. See also: map and filter being the only 2 other functions implemented and both of them being less performant than their imperative equivalents; outright denial of any attempt at TCO because "Guido doesn't like recursion".
- kbumsik 8y ago> outright denial of any attempt at TCO because "Guido doesn't like recursion". No, don’t ignore problems of TCO by saying “guys don’t like functional programimg”. Guido cleary states why he doesn’t like it: [1]. Even though TCO is one of the ES6 standard, TCO also is largely denied by JS implementors (Firefox, Chrome, and Edge devs) because of the similar reasons. As a result, Safari is the only browser that supports TCO. [2][3] And Rust team is not eager to introduce TCO [4]. [1]: http://neopythonic.blogspot.com/2009/04/tail-recursion-elimination.html http://neopythonic.blogspot.com/2009/04/tail-recursion-elimi... [2]: https://www.chromestatus.com/feature/5516876633341952 https://www.chromestatus.com/feature/5516876633341952 [3]: https://github.com/kangax/compat-table/issues/819 https://github.com/kangax/compat-table/issues/819 [4]: https://github.com/rust-lang/rfcs/pull/1888 https://github.com/rust-lang/rfcs/pull/1888
- steveklabnik 8y agoIt’s not that we’re not eager, it’s that it’s harder in a systems language and historically there’s been limitations in LLVM. We will sometimes optimize for TCO, that issue is that we can’t guarantee it just yet.