You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md
+76-12Lines changed: 76 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,51 +4,115 @@ Date: 2025-10-31
4
4
5
5
## Status
6
6
7
-
Accepted
7
+
Proposed
8
8
9
9
## Context
10
10
11
-
We have many Bash scripts, often they are inline scripts embedded in Dockerfiles.
12
-
This is hindering code reuse, and makes using good software engineering practices difficult.
11
+
We have many Bash scripts; often they are inline scripts embedded in Dockerfiles.
12
+
This is hindering code reuse and makes using good software engineering practices difficult.
13
13
14
14
The current team self-reported that they are comfortable with Python, Go, and (to a lesser degree) TypeScript.
15
15
Use these languages in preference to Bash.
16
16
17
17
## Decision
18
18
19
-
The team has agreed to use Python, Go, and Typescript, in this order.
19
+
The team has agreed to use Python, Go, and TypeScript, in this order.
20
20
21
21
For any new development, we should use the most appropriate language out of these.
22
22
Old code should be gradually migrated to one of the preferred languages.
23
23
24
-
Avoid using Bash for anything more complicated than a `RUN dnf install -y ... && dnf clean all`.
24
+
We should avoid using Bash for anything more complicated than a `RUN dnf install -y ... && dnf clean all`.
25
+
26
+
### Bash
27
+
28
+
Titus Winters presented about programming languages being [software-engineering-friendly](https://youtu.be/yA_wUiNuhSc&t=649) or unfriendly.
29
+
Bash was not mentioned but it should fall into the unfriendly category.
30
+
It does not have proper runtime types (everything in Bash is a string, or possibly an array of strings),
31
+
it does not even have proper value-returning functions!
32
+
33
+
There are efforts to level up Bash scripting, such as the `set -Eeuxo pipefail`, but it has
34
+
[problems of its own](https://www.reddit.com/r/bash/comments/mivbcm/comment/gt8harr/):
35
+
36
+
> `errexit`, `nounset` and `pipefail` are imperfect implementations of otherwise sane ideas, and unfortunately they often amount to being unreliable interfaces that are less familiar and less understood than simply living without them. It's perfectly fine to want them to work as advertised, and I think we all would like that, but they don't, so shouldn't be recommended so blindly, nor advertised as a "best practice"—they aren't.
37
+
38
+
There is the [bats](https://github.com/bats-core/bats-core) testing framework.
25
39
26
40
### Python
27
41
28
-
_The language of AI._
42
+
<spanstyle="color:green;">⊕</span> The semantics of Python are mostly familiar to the team members and they are comfortable using Python.
29
43
30
-
Pytest as the currently most popular test discovery and execution tool.
44
+
<spanstyle="color:green;">⊕</span> Pytest as the currently most popular test discovery and execution tool.
31
45
32
-
Rewriting Bash scripts to Python is verbose. Library to help with this is [sh](https://github.com/amoffat/sh) and others.
46
+
<spanstyle="color:red;">⊖</span> Rewriting Bash scripts to Python is verbose. Library to help with this is [sh](https://github.com/amoffat/sh) and others.
33
47
34
-
The indentation-based syntax is obnoxious, multiline lambdas are not available.
48
+
<spanstyle="color: red;">⊖</span> The indentation-based syntax is obnoxious, multiline lambdas are not available.
35
49
36
50
### Go
37
51
38
52
_90% Perfect, 100% of the time._[Brad Fitzpatrick, 2014](https://go.dev/talks/2014/gocon-tokyo.slide), [slide #36](https://go.dev/talks/2014/gocon-tokyo.slide#36)
39
53
40
-
Good performance, creates native executables, first class library support for dealing with Kubernetes.
54
+
<spanstyle="color:green;">⊕</span> Good performance,
55
+
creates native executables,
56
+
first-class library support for dealing with Kubernetes.
57
+
58
+
<spanstyle="color:green;">⊕</span> Often competes with Python in language choice debates,
59
+
vastly superior performance to Python and TypeScript both.
the language does not believe in programming in types (the way some typed functional languages or Rust do).
64
+
65
+
<spanstyle="color: red;">⊖</span> Has little syntactic sugar, already felt dated the year it came out.
41
66
42
67
### TypeScript
43
68
44
69
_The language of the web._
45
70
46
-
Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen.
71
+
<spanstyle="color:green;">⊕</span> Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen.
72
+
73
+
<spanstyle="color: gray;">🛈</span> We will consider using full-stack TypeScript in preference to having either a Python or Go backend to a TypeScript frontend.
74
+
75
+
<spanstyle="color: red;">⊖</span> It's still JavaScript underneath, so there is much inherited weirdness,
76
+
such as the `this` keyword being different depending on how a function is called.
77
+
78
+
## Typechecking
47
79
48
-
We will consider using full-stack TypeScript in preference to having either a Python or Go backend to a TypeScript frontend.
80
+
Static analyzability and specifically typechecking is (according to Winters)
81
+
an important step to achieving software-engineering friendliness.
82
+
83
+
The choice is between
84
+
85
+
* Pyrefly
86
+
* Pyright (or basedpyright)
87
+
* ty
88
+
89
+
Currently, the project is configured with Pyright, but with type checking disabled.
90
+
We should first fix the types with Pyright, gain experience, and then either decide not to use typed Python, or migrate off to one of the other options.
91
+
92
+
Pyrefly is more complete, whereas ty seems to be more vibrant and dynamic.
93
+
Either case, Python type annotations are language standard, so the core does not change,
94
+
but the checkers still have lots of implementation-specific behavior left to define themselves.
95
+
96
+
### Editor support for Python type checkers
97
+
98
+
VSCode support is pretty much given these days.
99
+
100
+
In IntelliJ world,
101
+
[version 2025.3+ is required for Python tools](https://www.jetbrains.com/help/pycharm/2025.3/lsp-tools.html)
102
+
support, as previous versions don't yet have
103
+
[LSP support built in](https://plugins.jetbrains.com/docs/intellij/language-server-protocol.html).
104
+
There is a
105
+
[plugin from Red Hat](https://github.com/redhat-developer/lsp4ij)
106
+
that adds LSP client support to IntelliJ, but I did not try to use it.
49
107
50
108
## Consequences
51
109
52
110
Less duplication of code due to easier maintenance, and testing of Python code, which should promote reuse.
53
111
54
112
Simple scripts will be more verbose in Python, but this is a trade-off we can make.
113
+
114
+
Obvious location to place shared code, sane `import` mechanism.
115
+
116
+
Allow for fearless refactoring <https://www.jamesshore.com/v2/blog/2005/merciless-refactoring>.
117
+
118
+
We will need to fight the ever-present tendency to overengineer, and instead we shall promote low-ceremony code.
0 commit comments