9 ms·
Using it as my main language: Python (2.7). How the hell did this thing become so popular? I've used it for all sorts of stuff earlier, less complex than the o
by salex89 8y ago
Using it as my main language: Python (2.7). How the hell did this thing become so popular?
I've used it for all sorts of stuff earlier, less complex than the other. Scripts, devops, ETL... But then I got into a company that is using it for some quite serious stuff, a large codebase. Holly smokes this thing does not scale (in terms of development efficiency and quality) well. I swear at least 70% of our bugs is because of the language and half of the abstractions are there just to lessen the chance of some stupid human mistake.
Sorry, but I will not pick it ever again for even a side project.
- fierro 8y agoI think dynamically types languages are on their way out. There aren't many good arguments remaining in favor of them.
- ken 8y agoI don’t think that’s the problem. I wouldn’t use Python (especially 2.x), but I’d have no hesitation with using Common Lisp. It has lots of great features for programming in-the-large that Python simply lacks.
- yuchi 8y agoGenuinely asking: could you provide some specific example? What does CL has that Pythos doesn’t? (Disclaimer: i never worked on neither)
- chalst 8y agoIf I had to point to something, I would single out CL's powerful support for multiple dispatch. I'd hesitate to recommend CL to undisciplined programmers, because it is too easy to write code that works but you don't understand a week later.
- ken 8y agoMultiple dispatch is a big one. Also, macros, which are what (the view layer of) CLOS is built with. In most other object oriented languages, the language isn’t powerful enough to implement its own object system. Having the full power of function calls in all cases (named or anonymous) is incredibly helpful. I know the Python party line is “just use def” but adding a line here and a line there adds up fast. A syntax for function objects is also great. I’ll also call out the ability to use dynamic or lexical scoping on a per-variable basis. That has saved me hundreds of lines of work, and made an O(1) change actually an O(1) patch.
- ken 8y ago(I hammered out that answer right before I had to run on stage. A couple other big items I forgot:) A proper numeric tower. Python has complex numbers, but they don't seem well integrated (why is math.cos(1+2j) a TypeError?). Fractions are frequently very useful, too, and Python has them, in a library, but "import fractions; fractions.Fraction(1,2)" is so much more verbose than "1/2" that nobody seems to ever use them. Conditions! Lisp's debugger capabilities are amazing. And JWZ was right: sometimes you want to signal without throwing. Once you've used conditions, you'll have trouble going back to exceptions. They feel restrictive. (I've come to accept that in a language with immutable data types, like Clojure, exceptions make sense. Exceptions feel out of place, though, in a language with mutability.) Other big wins: keywords, multiple return values, FORMAT (printf on steroids), compile-time evaluation, a native compiler (and disassembler) with optional type declarations. Lisp is unique among the languages I've used in that it has lots of features that seem designed to make writing large programs easier, and the features are all (for the most part) incredibly cohesive.
- chalst 8y agoConditions, yes. If you have multiple dispatch, then building/supporting a numeric tower is natural. In your other reply you pointed out macros. They are a mixed blessing, easily misused. Other languages have them but use them more sparingly and making it harder to overlook their special status, which leads to better "code smell" in my opinion. Do take a look at Julia. It has learned deeply from CL and innovated further.
- chalst 8y agoI have a very high opinion of Julia's dynamic type system. Some static type systems are not very expressive, e.g., Elm, which encourages hacky workarounds. Julia's type system encourages specificity, which exposes problems early.
- SolarNet 8y agoThat's because it's a strong type system (as opposed to python's weak one where objects can change their shape anytime). Even calling it dynamic is a sort of lie since the compiler is always able to reason about the types it is given due to the way Julia's JIT compiler works. It's "dynamic" in the same way passing around `void*` (or `object`) is "static". That being said Julia's type system is definitely the way of the future in my opinion.
- jcbrand 8y agoPython is strongly typed. See here: https://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic%20language%20and%20also%20a%20strongly%20typed%20language https://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic... "objects can change their shape anytime" is a function of dynamic typing and is orthogonal to strong or weak typing.
- SolarNet 8y agoIn a dynamic language "strong" vs "weak" typing really depends on the standard library. All the examples in the given link - for example - focus on the addition function in the standard library. So here are some counter examples: Everything can be used as a bool. This was often used to check for None, but had some issues when used with - for example - datetimes which evaluated midnight as false. In part due to the fact the integer 0 evaluates to false. Changing type unexpectedly is the key example given in your link (`"foo" + 3` is `"foo3"`). Meanwhile in python `foo.method()` can change the type of the variable foo. Which is a level of fuckery commonly found in javascript. Let alone the fact that dynamic duck typing encourages weak typing over performing explicit conversions. This is embodied by "easier to ask forgiveness than permission" which says it's better to catch the type conversion exception than check if the type is an integer ahead of time. Which then leads to implementing javascript-esque add functions anyway. I'll grant you python is stronger than some other dynamic languages, but it is still at least half an order of magnitude weaker than Julia, which is strong in ways approaching Haskell.
- spricket 8y agoI agree, because type inference in some (Typescript) is good enough that there's almost no overhead. Back when it took twice as many lines with types it made sense. But the overhead in typescript is maybe 10%, worth it anymore? I don't think so
- chuckdries 8y agoI think we have a ways to go. Typescript's type system is very feature complete (which is a good thing, but it also means there's a lot to learn, and I feel like I have to think about type definitions more than I ever did with other languages), but also, fantastic libraries like Ramda have a lot of trouble with expressing their types with Typescript. It's a tough problem to solve, and I still use both, but I'm just saying we're not there yet.
- spricket 8y agoI agree that the type system is very complex. I've spent a lot of time wrapping my head around it and still get confused sometimes. Unfortunately Typescript's type system is largely driven by the need to represent anything you can do in JS, for library compatibility reasons. The main designer also wrote C# and Delphi. In a lot of ways, C#'s type system is better (less complex), but Typescript has the huge advantage of working with existing JS
- jononor 8y agoI think the dynamic/static typing dichotomy is on its way out (finally!). In dynamic languages optional/gradual typing is getting adopted (ex: Typescript/Flow for JS, Mypy for Python). In static languages type inference is getting standard (ex: Rust/Scala/Kotlin, auto in C++11).
- icebraining 8y agoCan you give an example of one such abstraction?
- anyfoo 8y agoI started using python 3 with mypy, which provides (optional) static typing, and my gosh has it reduced the time I spend looking for stupid problems by orders of magnitude. I got a somewhat direct comparison when I mypy-ified a small program where I used a lot of async and await (basically implementing own event loops and schedulers, it was interfacing very custom hardware that handled very different but interacting streams at once). So basically I did it because I was tired of not noticing mixing up "foo()" and "await foo()", but then the static typing continued to catch a myriad of other, unrelated problems that would have ruined my day way late (and often obscurely) at runtime. For small ("scripty") to moderate sized things, mypy absolutely recovered my faith in it. I also completely switched to python 3 after being in python 2 unicode hell just once. There are very good reasons for python 3.
- o10449366 8y agoAgreed. As part of the transition process from Python 2 to 3, I pushed for typing on all of the critical components. I had to fight the management a little on the commitment, but in the long run it's saved us a ton of time identifying and preventing bugs and its made the entire codebase much more cohesive.
- em-bee 8y agodoes the management agree with that assessment? these kind of changes are often hard to evaluate because ot is not easy to compare. did development really go faster because of types, or do we just think it did? i agree that typing saves time but i am struggling to produce evidence for that
- anyfoo 8y agoIt's not very hard to find the evidence before you move to static typing. Just think about this not uncommon scenario: "The program crashed two hours into testing because apparently, we somewhere set this element in this deep structure to an integer instead of a list, and are now trying to iterate over that integer. But we cannot easily fix it, because we don't know yet where and why we set it to an integer." The compiler would have immediately given you an error instead. So, collect all the errors that are, e.g.: - Addressing the wrong element in a tuple, - any problems arising from changing the type of something; not just the fundamental highest level type ("list" or "integer"), but small changes in its deeper structure as well, e.g. changing an integer deep in a complex structure to be another tuple instead, - "missed spots" when changing what parameters a function accepts; this overlaps with the former point if it still accepts the same arguments on the surface, but their types change (in obvious, or subtle "deep" ways), - any problems arising from nesting of promises and non-promise values, and many, many other problems where you can trivially conclude that the compiler would have spit out an error immediately, and explain to management how various multi-hour debugging session could have been resolved before even running your thing.
- 8bitsrule 8y agoWhen I looked at Python, it looked interesting. Then I found out that -white space is important-. I thought about what it might be like to worry about that, and decided -not for me-. When CPUs ran at 1 MHz, I wasn't so sure about FORTH with its RPN. But it ran a lot faster than interpreted BASIC, and was a lot faster to write than assembler. Once the world discovers the source of all its woes and goes back to wide-open, 8-bit systems, I'll go back to FORTH.
- baobrain 8y ago> Then I found out that -white space is important-. I hear this a lot and I think it's a misunderstood statement. Python does not care if you do not have a space in assignments or arithmetic or between commas or parentheses. What Python does care about is the indentation of the source code. The indentation is what guides the structure - which is already what we are doing with most languages that don't care about indentation! What I really mean to say is there are plenty of valid complaints with Python, but white space just is not one of them. If you are writing good code in a language with C-syntax you are doing just as much indentation.
- AlotOfReading 8y agoWhy should code in a REPL be indented correctly? What if you copy from your own terminal (which may only support spaces) to your codebase, which may be in tabs? It doesn't make sense for a language exclaiming the principle of we're all adults here to not allow you to schedule irrelevant formatting fixes yourself.
- ryl00 8y agoBut doesn't the whitespace issue gimp Python's lambda syntax? AFAIK you're limited to one expression or function call, to get around the fact that you can't just inline a completely new function (with its associated control flow structure). And what about one-liners, a la Perl? Stack Overflow answers seem to imply either embedding newlines in your string, or using semi-colons (as a Python newbie... you can use semi-colons?!)
- 8y ago
- tootie 8y agoI've mostly done Java in my career and I tend to stick to it (or Kotlin now). I've always said the power of java isn't in solving programming problems, it's in solving organizational problems. The killer feature that vaulted it to the top and still hasn't been beat is javadoc.
- chalst 8y agoWhy do you think javadoc is better than docstrings? There are docstring-based languages that encourage good practice and can produce what I regard as excellent integrated docs. E.g., Julia's Documenter: https://juliadocs.github.io/Documenter.jl/stable/ https://juliadocs.github.io/Documenter.jl/stable/
- ChristianGeek 8y agoThe killer feature that vaulted Java to the top was cross-platform compatibility (regardless of the flaws), including AWT and Swing. Source: Have been coding in Java since 1.0.
- dehrmann 8y agoNot javadoc the standard, but javadocs for the standard library. It explains behavior in much more detail than other languages' docs, so I'm rarely surprised.
- arbie 8y agoCouldn't agree enough. I have seen Perl (with automated PerlTidy on check-in) scale to levels I would never even attempt with Python.
- koyote 8y agoHah, I had the same thought when I first started using Python for some personal stuff many years ago. I enjoyed using it and it was quick to get some code out but I thought to myself "surely if you build anything large with this language it will be a massive pain to maintain". Fortunately(?), I never worked for a company that used it for a large codebase so I never found out if my assumption was correct or not.
- jononor 8y agoYou need a QA strategy to match the technology in use. No static type checking means many mistakes will need to be caught in another way. For instance with automated tests, or design-by-contracts. Which might also catch some things that static typing would not cover. In a non-trivial system with solid engineering, QA concerns quickly go beyond details like which programming language is used. Like how to QA entire systems, sub-system interactions, ensure low time from bug discovered in production to fix deployed, eliminating recurring sources of issues etc. But if the culture that caused the choice of a dynamic language is "oh its just so much easier and productive to not have to write types all the time!", then you are going to be in for some serious mess and pain in a larger system. That is not a technical problem with dynamic typing/language though :)
- jononor 8y agoAs another example, consider unsafe/safe like C/C++ versus Java/C#/Rust. Serious systems are built in C (cars, airplanes, medical devices) and it can be done OK - but it requires serious investment in QA, targeted at weaknesses of the language.
- koyote 8y agoThat's a very good point: different languages require different QA strategies (do statically typed languages require less unit tests?). My initial thought when working with Python wasn't from a bugs/QA point of view but merely looking at the productivity of a developer working on a large code-base. Things like accurate auto-complete, code discovery, architectural understanding, knowing what 'kind' of object a function returns and so on become more important once the codebase and the amount of engineers working on it increases.
- scottlocklin 8y agoI quit around 2.2, never looked back. Python was a breakthrough scripting language ... in the 90s.
- diminoten 8y agoRealistically, how could you know if it's still any good if you haven't used it since 2.2? It's basically a different language now.
- scottlocklin 8y agoThe same way everyone else does: fixing other people's broken code. It actually hasn't changed much since 2.2.
- diminoten 8y agoIt's changed fundamentally since 2.2... Also if you're fixing broken Python code, you're using Python, so no that doesn't really track.
- scottlocklin 8y agoYou know, sometimes people have to fix trashfires; that doesn't mean they'd start one. What fundamental changes do you see since 2.2? If you're talking about the object model; objects in python were garbage before and after 2.2, and as a paradigm, it's mostly useless bureaucracy. Bleeding edge 90s ideas.
- dehrmann 8y agoI've used it at in a few jobs. Once place, mostly a Java shop, used it almost exclusively in a system that had grown to the point that it'd be hard to replace. The most insightful comment I got about it was that it's not that Python doesn't scale in terms of service instances or performance--it doesn't scale with codebase size and onboarding new developers.
- cauthon 8y agoIs there a language that has a better (i.e. more user friendly and decently performant) implementation of iterators and stream processing?
- nanomonkey 8y agoClojure's stream processing, and sequence functions are worlds better than Python. Clojure's sequences can be lazily evaluated which allows for much more performant computation. And for stream processing you can't beat composable reducer functions. The user friendliness comes both with how uncomplicated it is to write them, but also how easy it is to process them in parallel (a nightmare in Python).
- simonh 8y agoHaving worked on Quartz, probably in the handful of biggest Python code bases on the planet, that's just not my experience at all. It scaled very well and was a fantastic environment to work in. It certainly wasn't ideal for every use case, but then what is?
- FraaJad 8y agoYou are using Python2.7 in 2019. there is your problem. I understand if you inherited/maintaining a legacy application, you may not have had a choice about 2.7, but if it's a significantly large project and you are not making any attempts to use Python3 (and many of the improvements that come with it, including optional typing as one commenter mentioned, don't blame language, unless you have a solution that is magically going to fix all the problems from a language that is pretty much in "maintainance-mode! please use the new version" mode).
- youwishboye 8y agoGrowing a Python codebase like you would a Java/C# one (i.e. with tons of classes, interfaces, factories etc.) is a sure way to pull your hair out. However, Python provides a bit of metaprogramming that could drastically reduce the number of LOC needed, should you write it in a Pythonic way. That is, experienced Python programmers could write concise and performant Python code in less or at worst equal time as experienced Java/C# programmers. But if you hire Java/C# devs to write Python code, I can see how you could arrive at your conclusion. Bonus video: https://www.youtube.com/watch?v=o9pEzgHorH0 https://www.youtube.com/watch?v=o9pEzgHorH0