In my experience, a well-designed Python project is just as maintainable, if not more so, as one in any other language, regardless of size...and that's coming from a full-time C++ developer. The fact it is an "interpreted language" (and, actually, that's a popular half-truth we spend a lot of time mopping up after) has no bearing on its practicality. In the nearly seven years I've worked in Python, I have found absolutely no feature of compiled languages that is not reasonably matched in Python.
I'll also say, Java has a lot of issues that negatively impact performance, maintainability, and clean coding practice. I spend more time than I'd like as a trainer unteaching terrible habits formed in Java programming. Practically speaking, it is harder by an order of magnitude to write good Java code than it is to write good Python code.
In short, Java has well-earned the derision it carries from every corner of the coding world besides its own fanbase. ;)
That said, I won't say anything about Scala, as I have never used it.
I would say that, for large projects where you really need a "true" compiled language, C++14 or C++17 should be towards the top of your list of languages to consider. The last two versions of the language are lightyears removed from the traditional C++ that so many know and hate.
I would really want to have that experience as well, but my experience was different, my main issue is that with dynamically typed languages when I see a function signature I have no idea what the arguments mean unless I can guess that correctly either by the arguments names or their documentation or context. While this may sound trivial, when me or my peers are faced with maintaining large projects created by other people and teams I have seen this creating maintenance problems and issues over and over again (many multiple team where people with different skills leave and join, large projects codebases, where the maintainer is not the one who wrote the code).
If I take an arbitrary function from github I might see this:
Now lets say I look only at the function signature and I ask:
What does the function return?
What is content_range?
What is resumed_from?
What is the data at stake?
What does the function do?
These are the most fundamental question I ask about every function or piece of code I read or edit, for a function it's input, it's output. The code does not give me hints other than docs and arg names, no entity verifies this for me as an explicit and a must have step.
Unless I look at the documentation which is free text and is not confirmed by anyone (such as compiler) I have to trust that the documentation is correct, examine internal code, ask someone, try the function. I don't want to do that, I want someone (in my case the compiler to do as much of that for me).
Without looking at documentation I cannot really know, again, assuming i'm maintaining a project different people wrote (that is the core of maintenance from my side of issues).
I would really love to be able to maintain such code written by others, but it's much more difficult without the compiler assisting me to know and confirm the most basic thing about each and every function in my code:
What is the input of the function, is it correct?
What is the output of the function, is it correct?
I really love python, I love R, I love scala/java, I love javascript, typescript, shell scripts, ... I try to use each for it's best use case, and again those are my personal view and experience, others might have different one, I wish there was one silver bullet, there are multiple, so i'm faced with using each bullet for the target I think would hit best and this is what I tried to express in my thoughts in the post.
Great summary of why I like static typing too. To be fair Python 3.5+ supports Type Hints which are a step in the right direction (however these are far from standard so most of your points still stand).
Exactly, I was going to mention that type hints are becoming rather standard for function arguments.
While I would say your concerns are valid, @tomerbendavid
, I would like to point out that Python is practically a paradigm all its own. You approach design from a different angle than you do from C-like languages; once you are used to this paradigm, none of the above issues continue to be factors. ;)
Of course, you can always just Systems Hungarian until you're used to static typing. ;)
I'd say one of the top ones is a blind dependency on the standard library, above and beyond many other languages. The language is structured in such a way that you basically have to rely on standard library elements whole-hog, where many other languages (including C++) would allow you to use parts-and-pieces as needed for your performance needs. Seeing as most of the standard library is deeply broken in terms of performance, this makes for some very bad messes.
Another is the terrible habit of deeply nesting multiple unnecessary namespaces. Almost every Java program I've seen has its source inside no less than six otherwise empty nested folders. Java coders often try to replicate this in C++ projects, and I have them go back and remove 85% of their namespaces.
I'll need to poke into the language again to remember a few of the others that are just beyond the reach of my immediate memory. When you do academic damage control from a language on a regular basis, you don't make a point to memorize its syntax and idiosyncrasies, for the sake of sanity. ;-)
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
In my experience, a well-designed Python project is just as maintainable, if not more so, as one in any other language, regardless of size...and that's coming from a full-time C++ developer. The fact it is an "interpreted language" (and, actually, that's a popular half-truth we spend a lot of time mopping up after) has no bearing on its practicality. In the nearly seven years I've worked in Python, I have found absolutely no feature of compiled languages that is not reasonably matched in Python.
I'll also say, Java has a lot of issues that negatively impact performance, maintainability, and clean coding practice. I spend more time than I'd like as a trainer unteaching terrible habits formed in Java programming. Practically speaking, it is harder by an order of magnitude to write good Java code than it is to write good Python code.
In short, Java has well-earned the derision it carries from every corner of the coding world besides its own fanbase. ;)
That said, I won't say anything about Scala, as I have never used it.
I would say that, for large projects where you really need a "true" compiled language, C++14 or C++17 should be towards the top of your list of languages to consider. The last two versions of the language are lightyears removed from the traditional C++ that so many know and hate.
I would really want to have that experience as well, but my experience was different, my main issue is that with dynamically typed languages when I see a function signature I have no idea what the arguments mean unless I can guess that correctly either by the arguments names or their documentation or context. While this may sound trivial, when me or my peers are faced with maintaining large projects created by other people and teams I have seen this creating maintenance problems and issues over and over again (many multiple team where people with different skills leave and join, large projects codebases, where the maintainer is not the one who wrote the code).
If I take an arbitrary function from github I might see this:
def parse_content_range(content_range, resumed_from):
github.com/jakubroztocil/httpie/bl...
Now lets say I look only at the function signature and I ask:
These are the most fundamental question I ask about every function or piece of code I read or edit, for a function it's input, it's output. The code does not give me hints other than docs and arg names, no entity verifies this for me as an explicit and a must have step.
Unless I look at the documentation which is free text and is not confirmed by anyone (such as compiler) I have to trust that the documentation is correct, examine internal code, ask someone, try the function. I don't want to do that, I want someone (in my case the compiler to do as much of that for me).
Without looking at documentation I cannot really know, again, assuming i'm maintaining a project different people wrote (that is the core of maintenance from my side of issues).
I would really love to be able to maintain such code written by others, but it's much more difficult without the compiler assisting me to know and confirm the most basic thing about each and every function in my code:
I really love python, I love R, I love scala/java, I love javascript, typescript, shell scripts, ... I try to use each for it's best use case, and again those are my personal view and experience, others might have different one, I wish there was one silver bullet, there are multiple, so i'm faced with using each bullet for the target I think would hit best and this is what I tried to express in my thoughts in the post.
Great summary of why I like static typing too. To be fair Python 3.5+ supports Type Hints which are a step in the right direction (however these are far from standard so most of your points still stand).
Exactly, I was going to mention that type hints are becoming rather standard for function arguments.
While I would say your concerns are valid, @tomerbendavid , I would like to point out that Python is practically a paradigm all its own. You approach design from a different angle than you do from C-like languages; once you are used to this paradigm, none of the above issues continue to be factors. ;)
Of course, you can always just Systems Hungarian until you're used to static typing. ;)
As a current Java dev who would like to be able to switch languages later I would love to hear what you think are the top bad Java programming habits?
I'd say one of the top ones is a blind dependency on the standard library, above and beyond many other languages. The language is structured in such a way that you basically have to rely on standard library elements whole-hog, where many other languages (including C++) would allow you to use parts-and-pieces as needed for your performance needs. Seeing as most of the standard library is deeply broken in terms of performance, this makes for some very bad messes.
Another is the terrible habit of deeply nesting multiple unnecessary namespaces. Almost every Java program I've seen has its source inside no less than six otherwise empty nested folders. Java coders often try to replicate this in C++ projects, and I have them go back and remove 85% of their namespaces.
I'll need to poke into the language again to remember a few of the others that are just beyond the reach of my immediate memory. When you do academic damage control from a language on a regular basis, you don't make a point to memorize its syntax and idiosyncrasies, for the sake of sanity. ;-)