As a Python programmer, it would be interesting to hear why you thing Python in unprincipled? I haven't felt that myself so curious to see what your thoughts are.
Not the person you replied to, I don't hate Python, it's not my favorite but it's my most used language.
Python is unprincipled in its design. It's a kitchen sink language. It has principles (PEP 20) but they explicitly eschew purity of design in favor of practicality, readability, and simplicity of implementation.
Python's type system is very flexible. You may see that as a plus, to me it feels all over the place. It has classes which you can turn into half-baked nominal typing with type annotations. You can mix-and-match interface inheritance and implementation inheritance with multiple inheritance.
You can do unholy things to the class system with metaclasses and the issubclass hook. I have seen it, in a half-million LOC project.
It has protocols, which are duck typing, which you can turn into half-baked structural typing with type annotations.
It is multi-paradigm and it's acceptable at all but not the best at any. If you want strictly OOP or functional you're better served elsewhere.
You can mix-and-match type systems and paradigms in a single codebase, which can be useful, but it's up to dev discipline to not turn the codebase into a horrible mishmash.
In comparison, I don't like writing Java, but I have to admit it limits the amount of damage undisciplined devs can do to a project.
even among dynamically typed languages, python is terrible. it has no real way to build up new types in a principled way, and you have to result to using (and abusing) the class system, which is hack after hack.
python also ignored and continued to ignore things that already existed in languages and advances. it also doesn't really like using data-type driven development. go ahead and search for "python records". you'll get nothing, and the best reference is a blog post (https://dbader.org/blog/records-structs-and-data-transfer-ob...) that leads you to a wide variety of solutions, all inconsistent with each other and not conventionally used. now search google and literally the top result for each query is the following:
another area that python doesn't take seriously is scoping. the scoping rules and exceptions are complex, and this makes the language very dangerous. i mentioned one in the other comment i linked. python has weird scoping stuff with lambdas. python even has a keyword that makes a locally bound variable available in the calling scope (https://docs.python.org/3/reference/simple_stmts.html#nonloc...). no thank you. this is absolutely terrible design, and yes, i have seen it in production code (not written by me). just search "python scoping" or "python nonlocal", and you'll come across people confused by a plethora of edge cases.
python is just complicated. it has no simple core. it is a huge lump of stuff. both f# and racket are definitely more complicated than python in that they have behavior and features far exceeding python. however, they are principled. in one way, they have very simple core languages such that if you ignore all the fancy stuff, you can still write beautiful, reliable code with the simply designed core language. as you move to the more complicated stuff, you utilized this simple core over and over to build software that is still understandable. it allows you to build predictable software.
another area of principles i look for in a language are why it was created and what are the motivations of its creator(s). f# was created to bring a functional language to .net to utilize .net's vast functionality and test .net's language making and support capability. the development originally started with haskell but transitioned to ocaml since the model matched better with .net. don syme is a very practical language designer and an actual computer scientist. here is a draft of a paper by him about the history of f# (https://fsharp.org/history/hopl-final/hopl-fsharp.pdf). it's a useful read. racket was created to extend scheme into a new language that fully adopted language-oriented programming (lop) and had supporting libraries for normal development. this means taking an extremely principled language and extending it to support a new paradigm of software development in a principled, controlled way. see the paper a programmable programming language (https://cacm.acm.org/magazines/2018/3/225475-a-programmable-...). the authors of racket are also computer scientists and care about robust software development. python was created by someone interested in esoteric languages (ABC) and in creating a systems scripting language as a hobby project. the creator resisted and continued to resist many already existing language designs and features (found in scheme and ML-dialects such as SML). for example, lambda, map, filter, and reduce only exist in python because he begrudgingly accepted patches that someone else did. another example of unprincipled-ness is the creator's seemingly proud declaration to use multi-line string literals as multi-line comments since python did not have and still does not have multi-line comment support (https://twitter.com/gvanrossum/status/112670605505077248).
these things alone make me wholly not interested in python. i want to use a language that was created for a reason and in a principled way that solves a problem that i am facing. i also feel i need to agree with the reasons and also the philosophy of the language designers. none of this exists for me in python.
Python is unprincipled in its design. It's a kitchen sink language. It has principles (PEP 20) but they explicitly eschew purity of design in favor of practicality, readability, and simplicity of implementation.
Python's type system is very flexible. You may see that as a plus, to me it feels all over the place. It has classes which you can turn into half-baked nominal typing with type annotations. You can mix-and-match interface inheritance and implementation inheritance with multiple inheritance.
You can do unholy things to the class system with metaclasses and the issubclass hook. I have seen it, in a half-million LOC project.
It has protocols, which are duck typing, which you can turn into half-baked structural typing with type annotations.
It is multi-paradigm and it's acceptable at all but not the best at any. If you want strictly OOP or functional you're better served elsewhere.
You can mix-and-match type systems and paradigms in a single codebase, which can be useful, but it's up to dev discipline to not turn the codebase into a horrible mishmash.
In comparison, I don't like writing Java, but I have to admit it limits the amount of damage undisciplined devs can do to a project.