Note: This will be an ever growing list of quirks I experienced when writing substantial libraries and applications in various languages. If you have a specific language quirk you have experienced, feel free to reach out and explain.
The lack of generic function generators within the standard library forces many packages, and consequently many online services, to have code generation (prior to build) as an implementation detail. For example, many ORM’s and performant data structures have their methods generated. A lack of generics is a deliberate forcing function on Go developers, and by and large the most commonly known quirk by even non Go developers. To Go’s credit, there is some developer conveniences around such generation steps, with the language having build tools understand specific source file comments which call out to commands.
- Generating a Queue backed by a double linked list
- Code generation for Vector Implementation
- Generates an ORM tailored to a particular database schema. The equivalent of sqlalchemy.
- Generation of x86 Assembly
Every application thus has at its best many, many virtuously and positively combining dependencies. At its worst you have a massive interconnected and highly eclectic set of dependencies holding everything together.
Yo, ho, yo ho, the aysnc life for me…. and every rest endpoint you will ever make. This is what you get when you; keep the functional paradigm; want to do lots of little work in parallel; and are constrained by the single threaded nature of the language. Thus you must begin keeping “promises” everywhere, even when forced out of sight. If you don’t, you will risk facing sacrilege.
A lack of type-safety is also great, but also delays the learnings and experiences of those who would benefit from dependency injection (DI) and thinking hard of what interfaces should be created. Whole companies have learned the hard way why DI is useful, and many more will relearn the lessons from a few classics.
Also, I can’t forget the classic WAT.
The positional argument pattern is pervasive in css, and is a fundamental quirk within the language. This is a hard quirk on all new features added to CSS as it carries forward a hard to understand shorthand for every new feature, e.g. grids.
CSS is also beholden to how it can reach out and affect the dom, i.e. selectors, but its also beholden to serialization rules, i.e. escaping selectors. These are not really quirks, per se, but more constraints which when summed up, push developers to invent many ways of avoiding css, resulting being many ways of making your text another color.
Easy to use keyword arguments for methods and classes, combined with default args, makes everything so easy to get started. Python is arguably the lowest friction language for creating everything from simple scripts to full universe simulations. In such an environment many will visit those kinds of “Learn X in Y minutes” pages, but with python being such a long lived languages, with many many, interesting quirks, they should visit wtfpython instead. These are not exactly specific to python, all of the other languages mentioned have similar quirks.
What is a specific language quirk to Python, is the with statement. This statement allows the common
try...execpt...finally pattern which is pervasive across Python codebases needing to reach out and talk to resources with setup and cleanup.
The affect of
with is many Objects are implemented in an ad hoc fashion, including the special
__exit__() methods needed to use
with. Then each object is exported and added to an ever growing large collection of global singletons passed around the codebase. i.e. database handles, cache handles, and other resource management wrappers.