Skip to content

Commit 0c1b53f

Browse files
committed
add bash section, add bulets to lists, expand on python typechecking
1 parent e722d63 commit 0c1b53f

File tree

1 file changed

+76
-12
lines changed

1 file changed

+76
-12
lines changed

docs/architecture/decisions/0003-prefer-python-go-and-typescript-in-this-order.md

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,51 +4,115 @@ Date: 2025-10-31
44

55
## Status
66

7-
Accepted
7+
Proposed
88

99
## Context
1010

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.
1313

1414
The current team self-reported that they are comfortable with Python, Go, and (to a lesser degree) TypeScript.
1515
Use these languages in preference to Bash.
1616

1717
## Decision
1818

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.
2020

2121
For any new development, we should use the most appropriate language out of these.
2222
Old code should be gradually migrated to one of the preferred languages.
2323

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.
2539

2640
### Python
2741

28-
_The language of AI._
42+
<span style="color:green;">⊕</span> The semantics of Python are mostly familiar to the team members and they are comfortable using Python.
2943

30-
Pytest as the currently most popular test discovery and execution tool.
44+
<span style="color:green;">⊕</span> Pytest as the currently most popular test discovery and execution tool.
3145

32-
Rewriting Bash scripts to Python is verbose. Library to help with this is [sh](https://github.com/amoffat/sh) and others.
46+
<span style="color:red;">⊖</span> Rewriting Bash scripts to Python is verbose. Library to help with this is [sh](https://github.com/amoffat/sh) and others.
3347

34-
The indentation-based syntax is obnoxious, multiline lambdas are not available.
48+
<span style="color: red;">⊖</span> The indentation-based syntax is obnoxious, multiline lambdas are not available.
3549

3650
### Go
3751

3852
_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)
3953

40-
Good performance, creates native executables, first class library support for dealing with Kubernetes.
54+
<span style="color:green;">⊕</span> Good performance,
55+
creates native executables,
56+
first-class library support for dealing with Kubernetes.
57+
58+
<span style="color:green;">⊕</span> Often competes with Python in language choice debates,
59+
vastly superior performance to Python and TypeScript both.
60+
61+
<span style="color: red;">⊖</span> Requires compilation step,
62+
type system is not very expressive,
63+
the language does not believe in programming in types (the way some typed functional languages or Rust do).
64+
65+
<span style="color: red;">⊖</span> Has little syntactic sugar, already felt dated the year it came out.
4166

4267
### TypeScript
4368

4469
_The language of the web._
4570

46-
Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen.
71+
<span style="color:green;">⊕</span> Playwright has best support for TypeScript, other language bindings are a bit of a second class citizen.
72+
73+
<span style="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+
<span style="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
4779

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.
49107

50108
## Consequences
51109

52110
Less duplication of code due to easier maintenance, and testing of Python code, which should promote reuse.
53111

54112
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

Comments
 (0)