Programming Language Quirks

November 10, 2019

As I have written scripts, libraries and applications in various programming languages over the years, I have noticed there are unique quirks of each language shaping the programs I write in them. Note, when I say quirk, I'm not talking about the well known features of a language, e.g. Go and its concurrency primatives, or javascript and its dynamic typing. Instead when I say quirk, I'm referring to quirks of a programming language which are either subtle enough to not be noticed until late into a project, or just taking for granted by most developers.

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.

R (R Project)

With so much statistical built ins... see birthday problem,

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, e.g. border: 2px solid red; or grid: auto-flow dense / 40px 40px 1fr; and is a fundamental quirk within the language, making most examples of css code hard to quickly understand or orient to what its doing. This is concise syntax isn't exactly forced, as there is declarations for each shorthand, but it is a large enough quirk, developers just accept it on all new features added to CSS, seegrids as one such example.

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, the result 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 global objects are implemented and exposed to the project in an ad hoc fashion. All it takes is an including of the special _enter__() and __exit__() methods needed to use with. From their its low friction and pretty hard to keep the object from being exported and added to an ever growing collection of global singletons passed around the codebase. E.g. database handles, cache handles, and other resource management wrappers.

TBD

Thanks for reading, my ever growing list of quirks I have noticed when writing substantial libraries and applications in various programming languages. If you have experienced a specific language quirk within one of these languages and want to share, feel free to reach out via email!


Matthew Clemens © 2022