WellKnownIdentifier.md
... ...
@@ -0,0 +1,171 @@
1
+# Well-known Identifier
2
+
3
+## Introduction
4
+
5
+Well-known Identifiers are predictable identifiers or location descriptors, by
6
+which humans or machines can find certain files, executables, services, or
7
+resources. They allow a human or computer to discover affordances within a given
8
+context, which expose a well-known interface, without the need of additional out
9
+of band information.
10
+
11
+The description of this pattern is inspired by [Well-Known Uniform Resource
12
+Identifiers](https://en.wikipedia.org/wiki/Well-known_URI), by recognizing that
13
+this is a more general pattern. Once you start looking for it you will discover
14
+it in very different kind of contexts.
15
+
16
+Some of the examples may seem trite and obvious, but we think it's useful to
17
+recognize the common pattern across different contexts, to consider why this
18
+pattern works (for technical and cultural reasons), and to consider in which
19
+other contexts this pattern could be applied but is not yet common practice.
20
+
21
+## Tensions
22
+
23
+Computer systems consist of many different software components. These components
24
+expose affordances, which can be used by other components, or by human
25
+operators. Examples of affordances are the awk interpreter, a HTTP endpoint, a
26
+function in a library, or the Linux kernel API. These are all resources the
27
+environment may offer to the programmer and their program.
28
+
29
+These affordances need to be discovered. The programmer can do so by consulting
30
+documentation, or using introspection facilities of the environment. The
31
+specifics can then be encoded inside the program. This however makes the program
32
+rigid and brittle. These specifics can and will change, or differ across
33
+contexts (systems), so instead we make them configurable, so the program makes
34
+fewer assumptions, and thus can be more easily adapted to a new context or
35
+environment.
36
+
37
+But this reduces convenience. Before the program "just worked" (within a narrow
38
+context), the new program can operate in a broader context, but only after
39
+appropriately configuring it. Thus a tension arises.
40
+
41
+Well-known identifiers resolve this tension by allowing the program/programmer
42
+to make certain assumptions safely, because there is an agreed upon convention
43
+for where to discover certain affordances.
44
+
45
+For the developer they resolve a tension between novelty and familiarity,
46
+allowing existing knowledge to transfer to new software, because new
47
+functionality is provided through a familiar interface.
48
+
49
+## Pattern Description
50
+
51
+Given a directory or namespace lookup system (file system paths, URL paths,
52
+namespaces of symbols and function, etc), if there is either a documented
53
+standard or a strong cultural convention that a certain type of affordance
54
+(abstract interface) is available under a specific identifier, then this forms a
55
+Well-known Identifier.
56
+
57
+Well-known Identifiers are resolved relatively to a given context, like the
58
+current filesystem, a HTTP origin, or the current classpath. In this sense they
59
+provide an abstraction. Each context can decide what to provide at that
60
+identifier (location), as long as what is provided implemements the expected
61
+interface or format.
62
+
63
+Well-known Identifiers are both a technical and a cultural pattern. Technically
64
+they complement the idea of "programming to an interface, not to an
65
+implementation". They answer the question of where to find, or how to access,
66
+the interface. They allow for service discovery, and form a type of
67
+[[ConventionOverConfiguration]].
68
+
69
+How "well-known" an identifier is is a sliding scale. Often only a subset of
70
+existing systems will use a well-known common name, while others use other
71
+arbitrarily chosen names, leading to unnecessary friction in terms of
72
+interoperability. It is the role of technology leaders to push for adoption of
73
+well-known identifiers within the projects they lead, as well as to recognize
74
+the potential of coining identifiers in new areas, and to advocate for their
75
+common use.
76
+
77
+Some well-known identifiers are standardized through standard bodies like the
78
+IETF or W3C, however the existence of a standard does not say anything about its
79
+adoption, neither does the lack of a standard imply a lack of common use.
80
+Ultimately adoption is a cultural problem, but the existance of a documented
81
+standard can certainly help in gaining adoption.
82
+
83
+## Examples
84
+
85
+On POSIX-compatible operating systems `/bin/sh` is a standard identifier. So is
86
+`/usr/bin/env`, but `/bin/bash` for instance is not. (Some systems use
87
+`/usr/bin/bash`). Note that even though these conventions have been common
88
+practice for decades, it is still possible to find UNIX style systems that don't
89
+adhere to them.
90
+
91
+On the web there are a number of well-known URIs standardized through RFC 8615,
92
+under the `/.well-known` path prefix, like `/.well-known/webfinger` or
93
+`/.well-known/caldav`. Another one is `robots.txt` defined in RFC 9309.
94
+
95
+There are standard TCP ports by which certain services can be found, like port
96
+80 for HTTP, 443 for HTTPS, or 25/587 for SMTP. In a sense they are also an
97
+application of this pattern.
98
+
99
+Certain JVM libraries and tools will look for their configuration on the
100
+classpath, for instance Logback tries to find a `logback.xml`. While this is an
101
+identifier that's specific to one tool, it's a mechanism that could be leveraged
102
+more generally.
103
+
104
+Similarly JVM system properties that are understood by mutiple libraries/tools
105
+seems to be an underutilized mechanisms.
106
+
107
+There are several commonly used well-known environment variables. Most software
108
+intended to run in a cloud environment understand the `PORT` variable to decide
109
+which HTTP port to run on. Most CI environments set the `CI` variable to signal
110
+that the code is being run on CI.
111
+
112
+## Use for Clojure tooling
113
+
114
+These standard identifiers are important for machines and programs, but they can
115
+also be important for humans. Gaiwan does a lot of projects, for clients and
116
+open-source, and we want people to feel comfortable going from one project to
117
+another. That's why we have our own set of standard identifiers that we set up
118
+on every project.
119
+
120
+- `bin/launchpad` - start development environment
121
+- `bin/kaocha` - run tests
122
+- `(user/go)` - start the application
123
+- `(user/browse)` - open the application in a browser
124
+
125
+Other common identifiers
126
+
127
+- `(user/reset)` - use tools.namespace to do a reset/reload of changed namespaces
128
+- `(user/reset-all)` - use tools.namespace to do a reset/reload of all namespaces
129
+- `(user/portal)` - launch the portal UI
130
+
131
+Some of these we have adopted based on earlier precedent in the Clojure
132
+ecosystem, some of these we have coined ourselves. In both cases we advocate for
133
+their adoption and use across the ecosystem.
134
+
135
+The first two, `bin/launchpad` and `bin/kaocha`, are worth highlighting. We
136
+strongly encourage anyone adopting these tools
137
+([Launchpad](https://github.com/lambdaisland/launchpad) and
138
+[Kaocha](https://github.com/lambdaisland/launchpad)), to create these two
139
+executables within their projects.
140
+
141
+We sometimes get questions about that. Why not use `clj -X:kaocha`, or `bb run
142
+launchpad`. The problem with these is that they are not general enough. Not
143
+every project uses Clojure CLI or Babashka. By having an executable path that is
144
+independent of the concrete tooling we create an abstraction. From the
145
+programmer's point of view they can invoke Kaocha the same way on any project.
146
+The same goes for tooling, like CI, which gets a standardized way to invoke
147
+Clojure tests.
148
+
149
+What goes into these executables can be adjusted to the needs of the project.
150
+Besides invoking the appropriate Clojure launcher, they can perform additional
151
+steps. For instance, it's common for `bin/kaocha` to run `npm install` when
152
+needed.
153
+
154
+In [[Gaiwan Corgi]] we have the key combination `,,` to evaluate a snippet
155
+that's stored in a register, and we set some registers so we can easily invoke
156
+some of the above.
157
+
158
+- `,,g` - runs `(user/go)`
159
+- `,,b` - runs `(user/browse)`
160
+- `,,p` - runs `(user/portal)` in clj
161
+- `,,P` - runs `(user/portal)` in cljs
162
+
163
+## Further reading
164
+
165
+- [Wikipedia: Well-known URI](https://en.wikipedia.org/wiki/Well-known_URI)
166
+
167
+## History
168
+
169
+### 2024-05-20
170
+
171
+- First public version (Arne Brasseur)