Programming Language Quirks

How different quirks within programming languages end up affecting the libraries and applications written in them.

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.

Go (golang)

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.

Javascript (browser side)

The disparate ways javascript must interact with the other browser standards, for example html, css, and browser api’s. These each have their own quirks but in the context of javascript, they force quirks onto apps written to them as well. If you have interactions with users, you have to consider not just the surface being touched (html) but also its appearance (css) and the different inputs (javascript mouse & keyboard apis). Each has a separate api and interaction, forcing all apps written to have large wrappers over each of the many technologies involved. E.g. React, emberjs, styled components, d3.js, etc.

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.

Javascript (node)

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.

CSS

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.

Python

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 _enter__() and __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.