Hacker News new | past | comments | ask | show | jobs | submit login

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.




"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.


> 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".


I 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.


Exactly! 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.


I'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.


it'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.


Just as in f#, Python's lambdas can be bound to a name. There's no real difference between a def and a lambda. You're complaining about some distinction that doesn't exist. You didn't even try to discover whether it does before complaining about it.


Modules and functions in Python have a __name__ attribute. If you've used Python for scripts, you've probably written `if __name__ == "__main__":` at some point, which is the module name for executed scripts, whereas imported modules get their proper name.

Similarly, Python basically keeps track of "proper" names for proper functions, but can't/won't do so for lambdas.


> 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.


i know that. in the example, he assigned the lambda to normalize_case.


Sure, but an object doesn't know what variable it is assigned to (and which variable name should it pick if there's multiple).

the def syntax merely sets the name property on the function object too, since it has a name to set available. As said in other comments, nice for interactive use, irrelevant otherwise.

    >>> normalize_case = lambda s: s.casefold()
    >>> normalize_case
    <function <lambda> at 0x034B04B0>
    >>> normalize_case.__qualname__ = "normalize_case"
    >>> normalize_case
    <function normalize_case at 0x034B04B0>
vs

    >>> def normalize_case(s):
	return s.casefold()

    >>> normalize_case
    <function normalize_case at 0x00594420>
    >>> normalize_case.__qualname__
    'normalize_case'


thank you for clarifying exactly what's going on. other than the __qualname__, in what other ways do the two different bindings differ from each other?

however, this still goes in the bucket of why i personally dislike python. this just seems sloppy and overly complicated.

for example, i tested this out myself.

  > test = lambda x : x*x
  > test
  => <function <lambda> at 0x7ff6221d76e0>
  > test.__qualname__
  Traceback (most recent call last):
    File "python", line 1, in <module>
  AttributeError: 'function' object has no attribute '__qualname__'
  > test.__qualname__ = "test"
  > test
  => <function <lambda> at 0x7ff6221d76e0>
so the repl still reports <lambda> instead of test. actually it turns out that even def doesn't seem to set the __qualname__ property, so i don't get the same thing as you (i am using repl.it which apparently uses python 2.7.10). however, using dir(test) showed that there is the func_name property.

  > def test2(x):
  >     return x*x
  > test2.__qualname__
  Traceback (most recent call last):
    File "python", line 1, in <module>
  AttributeError: 'function' object has no attribute '__qualname__'
  > test2.func_name
  => 'test2'
  > test.func_name
  => '<lambda>'
that seems to be the property that the repl reports, as it gets set by the lambda assignment and the def keyword to the function name. (i verified that by altering the func_name property manually.)

yet, somehow, people call python "simple".


Van Rossum in https://python-history.blogspot.com/2009/04/origins-of-pytho... comments that "lambda" was likely the wrong choice for a name, saying "the choice of terminology had many unintended consequences. For instance, users familiar with functional languages expected the semantics of lambda to match that of other languages. As a result, they found Python’s implementation to be sorely lacking in advanced features."

Perhaps it would help if you didn't think of "lambda" as defining a lambda function, but something more prosaic like "defexpr", and that Python doesn't have lambda functions at all?

As to your experiments, you have found one of the many differences between Python 2 and Python 3.

After researching F# for about 10 minutes, perhaps you might think of Python 2 as being like OCaml and Python 3 being like F# - they are two instances of the same language family, with a mutually compatible language subset, but many incompatibilities.


As you've discovered, the reported property had a different name in python2. The repl doesn't report a property, it asks the object to give a representative string (__repr__() function) and prints that. Other languages wanting to expose something like this would maybe hide it deeper in the interpreter or build it into each tool separately, Python chooses to make everything accessible from the language itself.

You've bitten onto a more or less internal detail (I've TA'ed a bunch of undergrad courses in Python, and it's firmly in the land of things students don't know if they don't discover it on their own) and use that and seemingly quite little grasp of how Python works to argue that it isn't simple, while of course languages you are more familiar with are better.


FYI, repl.it has Python3, you just need to select Python3 and not Python.

As far as I know, the __qualname__ property was introduced in Python3.3, so obviously you wouldn't see it in any Python 2 version.


Don't complain about design warts if you're using an old version. Python 2 is just a couple years from end-of-life, and that's after the support guarantee was extended.


i didn't choose python 2.7. it is what i have installed on my work computer because the three projects i have worked on at work that used python were all using python 2.7, and the projects were led by "python people". in a couple cases, it was me who got them to upgrade from 2.6 to at least 2.7, and i have tried communicating to people to use python3 if they insist on python. i wouldn't choose python for a new project unless i had to again help someone else's project.

python's version bifurcation problem is its problem, not mine. the problem exists.


Sure, just like how it's Microsoft's problem that Windows 98 still gets used in a few places.


Since 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?


> 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.


These are good reasons for why people might prefer python over other imperative languages, though basically all these points also apply to Haskell/OCaml/F#/etc., though some people would still say that a lot of things there look like line noise.

I think the GP's point was that functional languages give you similar benefits, but with more uniform and disciplined behavior of many language features. Why FP is not more widely used compared to imperative language is another topic though.


I can only speak for myself and I'm more interested in getting a job done. If that means my UI component uses class syntax, and my state and communications channels are functional reducers, so be it.

I love JS because it's flexible and doesn't lock me into a paradigm. I can be as strict as I want to be. In the end, I think it depends on how someone thinks about problems. I tend to bend my thinking depending on the type of problem and how I might optimally solve said problem. When I need something else (often for performance), I'll circle around at that point for that part.


f# (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.fun-mooc.fr/courses/course-v1:parisdiderot+56002...


> 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.


okay, f# has curly braces. but not in the sense of other C-like languages like c++, java, and c#. they are primarily used for sequence expressions and computation expressions like async.

> 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.)

well that first sentence is simply not true, and i don't know what gave you that impression. f#'s repl, f# interactive, is available on linux through mono and will soon be available through .net core. i can't help you being needlessly allergic to a major operating system or company. f# came out of microsoft research.

> Huh? Python expressions always return a value.

they do? take:

  def test(x):
    "something"
so what does

  test(2)
return?

> 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.

i don't know why you're upset. i am not for sure where i was discourteous. i didn't mean anything by my statement other than to check out the languages and courses (the coursera one is very good). if those are your reasons for python, i just thought you would honestly like an ML-based language. i just used "owe it to yourself" as an expression, which apparently came out wrong through text. of course you don't owe anyone anything. i was just making a suggestion.


> of course you don't owe anyone anything

Yes, and thanks for acknowledging that. But then the phrase "owe it to yourself" didn't really communicate your intent correctly, which is why I objected to it.


Replying to your reply of the child comment:

> i guess that is true in python3 but it is not in python 2.7.

No, it's always been there.

    >>> def f():
    ...     pass
    ...
    >>> f() is None
    True


>>> test(2) is None

True


i guess that is true in python3 but it is not in python 2.7.


False. You're just not familiar with how the REPL works.

    >>> None
    >>> print(None)
    None

In the future, you might want to refrain from strong criticism of a thing you're not familiar with. That habit leads to all sorts of -isms.


i do know how the repl works. i explicitly tried it out. i defined the function just as i said and ran

  test(2) is None
and got false. i just now went to try it out again at home and got true. i don't know what to tell you other than something must have got shadowed somewhere.


Here's what I get from the Python 3 REPL:

    peter@localhost:~$ python3
    Python 3.5.2 (default, Nov 23 2017, 16:37:01)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def test(x):
    ...     "something"
    ...
    >>> test(2) is None
    True
And Python 2:

    peter@localhost:~$ python
    Python 2.7.12 (default, Dec  4 2017, 14:50:18)
    [GCC 5.4.0 20160609] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> def test(x):
    ...     "something"
    ...
    >>> test(2) is None
    True
If you post such a transcript from your REPL session where you get False, it should be easier to tell what's different between your setup and mine (which is a stock Python install on Ubuntu 16.04).

However, there is another even more direct experiment you could have run at the Python REPL to see what Python expressions return: just type the expression directly at the REPL and see what it prints back at you. In Python 3:

    peter@ToshibaSatellite:~$ python3
    Python 3.5.2 (default, Nov 23 2017, 16:37:01)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> "something"
    'something'
And in Python 2:

    peter@ToshibaSatellite:~$ python
    Python 2.7.12 (default, Dec  4 2017, 14:50:18)
    [GCC 5.4.0 20160609] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> "something"
    'something'
So, in your test function above, the expression "something" does return itself; it just does it inside the function, and that return value then gets thrown away when the function exits, because you didn't return it from the function itself.


i know how to use the repl. i moved between computers during comments and wasn't able to inspect my repl session where it originally returned false. as i mentioned, i must have redefined something or shadowed something which caused confusion, and i just didn't realize it at the time.


Guido 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.


Could 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-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.


Thanks, 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.


Guido 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".


> 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-elimi...

[2]: https://www.chromestatus.com/feature/5516876633341952

[3]: https://github.com/kangax/compat-table/issues/819

[4]: https://github.com/rust-lang/rfcs/pull/1888


It’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.


One 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.


> 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.


In 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).


i 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.


I 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").


> 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.


Your 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.


> 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.


Re: 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.


Simple and explicit code? sounds easy to read and debug!


I 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.


It 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"?


I think, it was an example of intentional hostile design (say, see this video 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 )


Do you have any evidence for your hypothesis about hostile design?

The phrase, by the way, is "one obvious way".


Guido 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.


Amen, brother. I'm not proficient in Python, but from my (admittedly, limited) experience with it, it feels like programming with a straightjacket on.


It 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).


To 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.


I 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.


> 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.


> 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.


sure. here you go.

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.


Thanks 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.


> 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.

as explained in the interview, the course changed to python because the course itself changed. they basically killed off the old course and created new courses built around their new degree program structure. the new course hits a lot of different aspects of electrical, computer, and software engineering, many of which heavily use existing libraries, so they seemed to pick python for this.

in my opinion, they could have easily written libraries in another language, so i suspect there were some politics at MIT that lead to the decision to use python.


It'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.


> It's not just Scheme

Agreed. I only mentioned Scheme specifically because Abelson did in what was quoted.


Nobody 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.


I disagree... I came for the syntax and readability; I've stayed for the community.


I 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.


I 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.


If the local/ global scooping rules are hurting you that much, you are probably putting more state in module-level variables than is healthy.


It's not that: it's the hobbled function scope that doesn't handle nested functions the way I would expect and hope.


in my experience, the python ecosystem is a mess. yes, there are lots of libraries, but that is just one part of the ecosystem. for one, everyone uses a different distribution, whether it's anaconda, python(x,y), or just the default python install. this creates a lot of fragmentation, and it's hard to come into a project and fix the mess that's been created. then there's the 2.x vs 3.x issue that is still a problem. i have been introduced to three python projects at various times in my work, and all still used python 2.7 and even python 2.6. (these were projects that i helped out on and didn't create or own.) in each case, python made it quite difficult to even understand if you had setup the environment correctly.

but yes, there are lots of libraries. i think people need to take a stance and simply pull those libraries into other languages (which many are already) or simply realize that most are just wrappers around some other language library, which can be easily done in other languages as well.


You're right, it is a mess.

Don't get me wrong, there's a huge number of packages available and a lot of them are really quality and I have used the language a lot, but good gosh is the packaging a deployment a fucking disaster.

Environments are a 3rd party bolt on, that relies on hacking around with environment variables. There's no distinction between dev dependencies and actual, application dependencies. The packaging/deployment tool has gone through a bunch of different formats/styles and when it comes to deploying your code, you have nothing better than writing a bash script that automates your environment creation, activation and running of the packaging tool (you then just hope that Pip doesn't fail on some bizarre edge).


Python packaging has a lot of warts, but you can specify dev dependencies in extras_require. Also, you can just run a virtual environment's interpreter without "activating" the environment.


> Nobody really likes Python the language especially much

I beg to differ. I like Python the language. I also like Python the ecosystem.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: