remove Astro website
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
FROM node:lts-alpine3.22
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache git
|
||||
COPY website/package.json website/package-lock.json ./
|
||||
RUN npm install && apk del git
|
||||
|
||||
COPY website/astro.config.mjs website/redirects.mjs ./
|
||||
COPY website/db ./db/
|
||||
ARG DB_URL=file:/app/db.sqlite
|
||||
ENV ASTRO_DB_REMOTE_URL=$DB_URL
|
||||
RUN mkdir -p "$(dirname "$(echo "$ASTRO_DB_REMOTE_URL" | cut -d':' -f 2)")"
|
||||
RUN npm run astro db push
|
||||
|
||||
COPY website .
|
||||
|
||||
RUN mkdir -p /common
|
||||
COPY common /common
|
||||
|
||||
ENV HOST=0.0.0.0
|
||||
ENV PORT=4321
|
||||
EXPOSE 4321
|
||||
|
||||
ARG LOCAL_SMTP_HOST
|
||||
ARG LOCAL_SMTP_PASSWORD
|
||||
ARG LOCAL_SMTP_PORT
|
||||
|
||||
RUN npm run build && rm -rf public src
|
||||
|
||||
CMD ["node", "./dist/server/entry.mjs"]
|
||||
@@ -1,6 +0,0 @@
|
||||
.astro/
|
||||
dist/
|
||||
node_modules/
|
||||
.dockerignore
|
||||
*.sqlite
|
||||
Dockerfile
|
||||
@@ -1,41 +0,0 @@
|
||||
import { defineConfig, envField, passthroughImageService } from "astro/config";
|
||||
import db from "@astrojs/db";
|
||||
import gemtext from "astro-gemtext";
|
||||
import mdx from "@astrojs/mdx";
|
||||
import node from "@astrojs/node";
|
||||
import sitemap from "@astrojs/sitemap";
|
||||
|
||||
import redirects from "./redirects.mjs";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
adapter: node({
|
||||
mode: "standalone",
|
||||
}),
|
||||
env: {
|
||||
schema: {
|
||||
MAX_DAILY_EMAILS: envField.number({
|
||||
context: "server",
|
||||
access: "secret",
|
||||
}),
|
||||
LOCAL_SMTP_ENVELOPE_FROM: envField.string({
|
||||
context: "server",
|
||||
access: "secret",
|
||||
}),
|
||||
LOCAL_SMTP_HOST: envField.string({ context: "server", access: "secret" }),
|
||||
LOCAL_SMTP_PORT: envField.number({ context: "server", access: "secret" }),
|
||||
LOCAL_SMTP_USER: envField.string({ context: "server", access: "secret" }),
|
||||
LOCAL_SMTP_PASSWORD: envField.string({
|
||||
context: "server",
|
||||
access: "secret",
|
||||
}),
|
||||
CONTACT_MAILBOX: envField.string({ context: "server", access: "secret" }),
|
||||
},
|
||||
},
|
||||
image: {
|
||||
service: passthroughImageService(),
|
||||
},
|
||||
redirects,
|
||||
site: "https://joeac.net",
|
||||
integrations: [db(), gemtext(), mdx(), sitemap()],
|
||||
});
|
||||
@@ -1,34 +0,0 @@
|
||||
import { column, defineDb, defineTable } from "astro:db";
|
||||
|
||||
const Otp = defineTable({
|
||||
columns: {
|
||||
userId: column.text(),
|
||||
value: column.text(),
|
||||
createdAt: column.number(),
|
||||
validUntil: column.number(),
|
||||
},
|
||||
});
|
||||
|
||||
const SendmailToken = defineTable({
|
||||
columns: {
|
||||
userId: column.text(),
|
||||
value: column.text(),
|
||||
createdAt: column.number(),
|
||||
validUntil: column.number(),
|
||||
},
|
||||
});
|
||||
|
||||
const SentEmails = defineTable({
|
||||
columns: {
|
||||
messageId: column.text(),
|
||||
sentAt: column.number(),
|
||||
},
|
||||
});
|
||||
|
||||
export default defineDb({
|
||||
tables: {
|
||||
Otp,
|
||||
SendmailToken,
|
||||
SentEmails,
|
||||
},
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
import { db } from "astro:db";
|
||||
|
||||
export default async function seed() {}
|
||||
Generated
-8737
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"private": "true",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro build --remote && node ./dist/server/entry.mjs",
|
||||
"build": "astro build --remote",
|
||||
"preview": "astro preview",
|
||||
"sync": "astro sync",
|
||||
"astro": "astro"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^22.14.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/db": "^0.20.1",
|
||||
"@astrojs/mdx": "^5.0.2",
|
||||
"@astrojs/node": "^10.0.3",
|
||||
"@astrojs/rss": "^4.0.17",
|
||||
"@astrojs/sitemap": "^3.7.1",
|
||||
"@types/nodemailer": "^7.0.4",
|
||||
"astro": "^6.0.8",
|
||||
"astro-gemtext": "git+https://git.joeac.net/joeac/astro-gemtext.git#ab32140ae28ff451447e7b25e24de0a4d46d264d",
|
||||
"gemtext": "^0.2.2",
|
||||
"markdown-it": "^14.1.0",
|
||||
"nodemailer": "^7.0.11",
|
||||
"typescript": "^5.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/check": "^0.9.8",
|
||||
"@types/markdown-it": "^14.1.1"
|
||||
}
|
||||
}
|
||||
@@ -1,516 +0,0 @@
|
||||
/** Variables */
|
||||
|
||||
:root {
|
||||
--colour-primary-10: #060300;
|
||||
--colour-primary-15: #150800;
|
||||
--colour-primary-20: #1f1400;
|
||||
--colour-primary-30: #3c2b00;
|
||||
--colour-primary-40: #5c4300;
|
||||
--colour-primary-50: #7f5d00;
|
||||
--colour-primary-60: #a37800;
|
||||
--colour-primary-70: #c89500;
|
||||
--colour-primary-80: #efb300;
|
||||
--colour-primary-90: #ffd98c;
|
||||
--colour-primary-95: #ffecc8;
|
||||
|
||||
--colour-hyperlink-10: #000409;
|
||||
--colour-hyperlink-20: #001829;
|
||||
--colour-hyperlink-30: #00314d;
|
||||
--colour-hyperlink-40: #004d75;
|
||||
--colour-hyperlink-50: #006a9f;
|
||||
--colour-hyperlink-60: #1388c9;
|
||||
--colour-hyperlink-70: #41a8ea;
|
||||
--colour-hyperlink-80: #78c7ff;
|
||||
--colour-hyperlink-90: #bfe3ff;
|
||||
--colour-hyperlink-95: #e0f1ff;
|
||||
|
||||
--colour-grey-10: oklch(0.1 0.01 84);
|
||||
--colour-grey-20: oklch(0.2 0.01 84);
|
||||
--colour-grey-30: oklch(0.3 0.01 84);
|
||||
--colour-grey-40: oklch(0.4 0.01 84);
|
||||
--colour-grey-50: oklch(0.5 0.01 84);
|
||||
--colour-grey-60: oklch(0.6 0.01 84);
|
||||
--colour-grey-70: oklch(0.7 0.01 84);
|
||||
--colour-grey-80: oklch(0.8 0.01 84);
|
||||
--colour-grey-90: oklch(0.9 0.01 84);
|
||||
--colour-grey-95: oklch(0.95 0.01 84);
|
||||
|
||||
--colour-error-10: oklch(0.1 0.2 26);
|
||||
--colour-error-20: oklch(0.2 0.2 26);
|
||||
--colour-error-30: oklch(0.3 0.2 26);
|
||||
--colour-error-40: oklch(0.4 0.2 26);
|
||||
--colour-error-50: oklch(0.5 0.2 26);
|
||||
--colour-error-60: oklch(0.6 0.2 26);
|
||||
--colour-error-70: oklch(0.7 0.2 26);
|
||||
--colour-error-80: oklch(0.8 0.2 26);
|
||||
--colour-error-90: oklch(0.9 0.2 26);
|
||||
--colour-error-95: oklch(0.95 0.2 26);
|
||||
|
||||
--colour-warn-10: oklch(0.1 0.2 46);
|
||||
--colour-warn-20: oklch(0.2 0.2 46);
|
||||
--colour-warn-30: oklch(0.3 0.2 46);
|
||||
--colour-warn-40: oklch(0.4 0.2 46);
|
||||
--colour-warn-50: oklch(0.5 0.2 46);
|
||||
--colour-warn-60: oklch(0.6 0.2 46);
|
||||
--colour-warn-70: oklch(0.7 0.2 46);
|
||||
--colour-warn-80: oklch(0.8 0.2 46);
|
||||
--colour-warn-90: oklch(0.9 0.2 46);
|
||||
--colour-warn-95: oklch(0.95 0.2 46);
|
||||
|
||||
--colour-primary-fg: var(--colour-primary-90);
|
||||
--colour-primary-fg-accent: var(--colour-primary-80);
|
||||
--colour-primary-bg: var(--colour-primary-10);
|
||||
--colour-primary-bg-accent: var(--colour-primary-20);
|
||||
--colour-code-fg: var(--colour-primary-90);
|
||||
--colour-code-bg: var(--colour-primary-15);
|
||||
--colour-hyperlink: var(--colour-hyperlink-80);
|
||||
--colour-grey-fg: var(--colour-grey-70);
|
||||
--colour-grey-bg: var(--colour-grey-30);
|
||||
--colour-error-fg: var(--colour-error-90);
|
||||
--colour-error-bg: var(--colour-error-40);
|
||||
--colour-warn-fg: var(--colour-warn-20);
|
||||
--colour-warn-bg: var(--colour-warn-80);
|
||||
|
||||
--font-size-sm: 1rem;
|
||||
--font-size-base: 1.125rem;
|
||||
--font-size-md: 1.5rem;
|
||||
--font-size-lg: 2rem;
|
||||
--font-size-xl: 3rem;
|
||||
|
||||
--spacing-block-xs: 0.5rem;
|
||||
--spacing-block-sm: 1.75rem;
|
||||
--spacing-block-md: 2.5rem;
|
||||
--spacing-block-lg: 3.5rem;
|
||||
--spacing-block-xl: 5rem;
|
||||
--spacing-inline-xs: 0.25rem;
|
||||
--spacing-inline-sm: 0.5rem;
|
||||
--spacing-inline-md: 1.5rem;
|
||||
--spacing-inline-lg: 3rem;
|
||||
--spacing-inline-xl: 6rem;
|
||||
}
|
||||
|
||||
/** Light theme */
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--colour-primary-fg: var(--colour-primary-20);
|
||||
--colour-primary-fg-accent: var(--colour-primary-40);
|
||||
--colour-primary-bg: var(--colour-primary-95);
|
||||
--colour-hyperlink: var(--colour-hyperlink-40);
|
||||
--colour-grey-fg: var(--colour-grey-40);
|
||||
--colour-grey-bg: var(--colour-grey-80);
|
||||
--colour-error-fg: var(--colour-error-20);
|
||||
--colour-error-bg: var(--colour-error-80);
|
||||
}
|
||||
}
|
||||
|
||||
/** Base typography */
|
||||
|
||||
body {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--colour-primary-fg);
|
||||
font-weight: light;
|
||||
background-color: var(--colour-primary-bg);
|
||||
line-height: 1.5;
|
||||
|
||||
/* Geometric Humanist stack from https://modernfontstacks.com */
|
||||
font-family:
|
||||
Avenir, Montserrat, Corbel, "URW Gothic", source-sans-pro, sans-serif;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
:is(p, h1, h2, h3, h4, h5, h6, hr, img, figure, ul, ol, blockquote) {
|
||||
margin-block-start: var(--spacing-block-sm);
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
/** Base layout */
|
||||
|
||||
body {
|
||||
--body-margin-inline-start: var(--spacing-inline-lg);
|
||||
--body-margin-inline-end: var(--body-margin-inline-start);
|
||||
--body-margin-block-end: var(--spacing-block-xl);
|
||||
margin-inline: var(--body-margin-inline-start) var(--body-margin-inline-end);
|
||||
margin-block-end: var(--body-margin-block-end);
|
||||
}
|
||||
|
||||
:is(h1, h2, h3, h4, h5, h6) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-inline: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 60rem) {
|
||||
body {
|
||||
display: grid;
|
||||
grid-template-columns:
|
||||
[grid-start media-start]
|
||||
var(--grid-margin-inline)
|
||||
[media-end content-start]
|
||||
minmax(var(--grid-max-content-width), auto)
|
||||
[content-end grid-end];
|
||||
grid-auto-rows: max-content;
|
||||
column-gap: var(--spacing-block-sm);
|
||||
max-width: var(--grid-total-width);
|
||||
|
||||
--body-margin-inline-end: 6rem;
|
||||
--grid-margin-inline: 6rem;
|
||||
--grid-total-width: 48rem;
|
||||
--grid-max-content-width: calc(
|
||||
var(--grid-total-width) - var(--body-margin-inline-start) -
|
||||
var(--grid-margin-inline) - var(--spacing-block-sm) -
|
||||
var(--grid-margin-inline)
|
||||
);
|
||||
}
|
||||
|
||||
:is(main, article, nav) {
|
||||
display: grid;
|
||||
grid-column: grid;
|
||||
grid-template-columns: subgrid;
|
||||
|
||||
> :is(section, header, aside, form) {
|
||||
display: grid;
|
||||
grid-template-columns: subgrid;
|
||||
grid-column: grid;
|
||||
|
||||
> :not(.not-grid-content) {
|
||||
grid-column: content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:is(h1, h2, h3, h4, h5, h6) {
|
||||
text-align: start;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 80rem) {
|
||||
body {
|
||||
grid-template-columns:
|
||||
[grid-start media-start]
|
||||
var(--grid-margin-inline)
|
||||
[media-end content-start]
|
||||
minmax(auto, var(--grid-max-content-width))
|
||||
[content-end margin-start]
|
||||
auto
|
||||
[margin-end grid-end];
|
||||
|
||||
--grid-total-width: 80rem;
|
||||
--grid-max-content-width: 40rem;
|
||||
}
|
||||
}
|
||||
|
||||
/** Headings */
|
||||
|
||||
h1 {
|
||||
font-size: var(--font-size-xl);
|
||||
font-weight: 900;
|
||||
margin-block-start: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: 900;
|
||||
margin-block-start: var(--spacing-block-xl);
|
||||
}
|
||||
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: 600;
|
||||
margin-block-start: var(--spacing-block-lg);
|
||||
}
|
||||
|
||||
/** Hyperlinks */
|
||||
|
||||
a:is(:link, :visited) {
|
||||
color: var(--colour-hyperlink);
|
||||
text-decoration: underline;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: wavy;
|
||||
}
|
||||
|
||||
/** Definition lists */
|
||||
dl {
|
||||
margin-block-start: var(--spacing-block-md);
|
||||
}
|
||||
|
||||
dl dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dl dd + dt {
|
||||
margin-block-start: var(--spacing-block-md);
|
||||
}
|
||||
|
||||
/** figcaptions */
|
||||
|
||||
figcaption {
|
||||
font-size: var(--font-size-sm);
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/** Lists */
|
||||
|
||||
:is(ol, ul) {
|
||||
margin-inline-start: var(--spacing-inline-lg);
|
||||
}
|
||||
|
||||
/** Navigation bar */
|
||||
|
||||
nav {
|
||||
margin-block: var(--spacing-block-sm);
|
||||
}
|
||||
|
||||
nav ul {
|
||||
grid-column: media-start / content-end;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: var(--spacing-inline-md);
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 36rem) {
|
||||
nav {
|
||||
display: grid;
|
||||
grid-template-columns: subgrid;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
justify-content: end;
|
||||
}
|
||||
}
|
||||
|
||||
/** Emphasis */
|
||||
|
||||
strong {
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/** Blog feed */
|
||||
|
||||
.h-feed ul {
|
||||
list-style: none;
|
||||
margin-inline: 0;
|
||||
}
|
||||
|
||||
/** Block quotes */
|
||||
blockquote {
|
||||
padding-inline-start: var(--spacing-inline-lg);
|
||||
border-inline-start: 2px solid var(--colour-primary-fg);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
blockquote footer {
|
||||
font-style: initial;
|
||||
}
|
||||
|
||||
blockquote :is(b, strong) {
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
blockquote :is(i, em) {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/** Small caps */
|
||||
.small-caps {
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
/** Pre-formatted blocks */
|
||||
pre {
|
||||
border: 2px solid var(--colour-primary-fg);
|
||||
border-radius: 2px;
|
||||
background-color: var(--colour-code-bg) !important;
|
||||
margin-block-start: var(--spacing-block-sm);
|
||||
padding-inline: var(--spacing-inline-sm);
|
||||
padding-block: var(--spacing-block-xs);
|
||||
}
|
||||
|
||||
/** Code blocks */
|
||||
code {
|
||||
border: 2px solid var(--colour-primary-fg);
|
||||
border-radius: 2px;
|
||||
padding-inline: var(--spacing-inline-xs);
|
||||
color: var(--colour-code-fg);
|
||||
background-color: var(--colour-code-bg);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
pre code {
|
||||
border: none;
|
||||
border-radius: none;
|
||||
padding: none;
|
||||
}
|
||||
|
||||
/* verse */
|
||||
.verse {
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.verse--hanging-indents {
|
||||
span + span:not(.not-hanging) {
|
||||
margin-inline-start: var(--spacing-inline-md);
|
||||
}
|
||||
}
|
||||
|
||||
/* block-comment */
|
||||
block-comment {
|
||||
display: grid;
|
||||
grid-template-columns: subgrid;
|
||||
grid-column: grid;
|
||||
|
||||
> * {
|
||||
grid-column: content;
|
||||
}
|
||||
|
||||
> blockquote:last-of-type {
|
||||
padding-block: var(--spacing-block-sm);
|
||||
padding-inline: var(--spacing-inline-md);
|
||||
overflow-y: scroll;
|
||||
border: 2px solid var(--colour-primary-fg);
|
||||
--colour-scroll-shadow: color-mix(
|
||||
in srgb,
|
||||
var(--colour-primary-fg),
|
||||
transparent 20%
|
||||
);
|
||||
|
||||
background:
|
||||
linear-gradient(var(--colour-primary-bg) 30%, transparent) center top,
|
||||
linear-gradient(transparent, var(--colour-primary-bg) 70%) center bottom,
|
||||
radial-gradient(
|
||||
farthest-side at 50% 0,
|
||||
var(--colour-scroll-shadow),
|
||||
transparent
|
||||
)
|
||||
center top,
|
||||
radial-gradient(
|
||||
farthest-side at 50% 100%,
|
||||
var(--colour-scroll-shadow),
|
||||
transparent
|
||||
)
|
||||
center bottom;
|
||||
background-repeat: no-repeat;
|
||||
background-size:
|
||||
100% 2rem,
|
||||
100% 2rem,
|
||||
100% 1rem,
|
||||
100% 1rem;
|
||||
background-attachment: local, local, scroll, scroll;
|
||||
|
||||
> :first-child {
|
||||
margin-block-start: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 80rem) {
|
||||
block-comment > blockquote:last-of-type {
|
||||
grid-column: margin;
|
||||
max-height: 67vh;
|
||||
}
|
||||
}
|
||||
|
||||
/* forms */
|
||||
form {
|
||||
margin-inline: auto;
|
||||
max-width: max-content;
|
||||
|
||||
:is(button, fieldset, input, label, object, output, select, textarea, img) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-block-end: var(--spacing-block-xs);
|
||||
}
|
||||
|
||||
* + :is(label, input[type="submit"], button) {
|
||||
margin-block-start: var(--spacing-block-md);
|
||||
}
|
||||
|
||||
:is(input[type="submit"], input[type="button"], button) {
|
||||
padding-inline: var(--spacing-inline-sm);
|
||||
max-width: max-content;
|
||||
&:not(dialog *) {
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
}
|
||||
|
||||
:is(input[type="email"], input[type="text"], select) {
|
||||
max-width: 100%;
|
||||
width: 16rem;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 100%;
|
||||
width: 40rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* dialogs */
|
||||
|
||||
dialog {
|
||||
background: var(--colour-primary-bg-accent);
|
||||
border: 2px solid var(--colour-primary-fg-accent);
|
||||
bottom: auto;
|
||||
color: var(--colour-primary-fg);
|
||||
left: calc(0.5 * (100vw - min(90vw, 36rem)));
|
||||
margin: 0;
|
||||
padding-block: var(--spacing-block-sm);
|
||||
padding-inline: var(--spacing-inline-sm);
|
||||
text-align: center;
|
||||
top: auto;
|
||||
width: min(90vw, 36rem);
|
||||
}
|
||||
|
||||
@media (min-width: 80rem) {
|
||||
dialog {
|
||||
left: calc(
|
||||
var(--body-margin-inline-start) + var(--grid-margin-inline) + 2 *
|
||||
var(--spacing-inline-md)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* utilities */
|
||||
:is(
|
||||
.para-spacing-tight:is(p, h1, h2, h3, h4, h5, h6, hr, img, figure, ul, ol),
|
||||
.para-spacing-tight :is(p, h1, h2, h3, h4, h5, h6, hr, img, figure, ul, ol)
|
||||
) {
|
||||
margin-block-start: var(--spacing-block-xs);
|
||||
}
|
||||
|
||||
.error {
|
||||
background: var(--colour-error-bg);
|
||||
border: 2px solid var(--colour-error-fg);
|
||||
color: var(--colour-error-fg);
|
||||
padding-block: var(--spacing--block-sm);
|
||||
padding-inline: var(--spacing-inline-sm);
|
||||
}
|
||||
|
||||
.warn {
|
||||
background: var(--colour-warn-bg);
|
||||
border: 2px solid var(--colour-warn-fg);
|
||||
color: var(--colour-warn-fg);
|
||||
padding-block: var(--spacing--block-sm);
|
||||
padding-inline: var(--spacing-inline-sm);
|
||||
--colour-hyperlink: var(--colour-hyperlink-40);
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
div:has(img) {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
div img {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
border-radius: 1rem;
|
||||
filter: contrast(1.25);
|
||||
}
|
||||
|
||||
div:has(img)::after {
|
||||
/* Colour overlay */
|
||||
background-color: var(--colour-primary-80);
|
||||
opacity: 0.3;
|
||||
|
||||
/* Same size and shape as the img */
|
||||
border-radius: 1rem;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
|
||||
/* Positioned on top of the img */
|
||||
display: block;
|
||||
position: relative;
|
||||
top: -6rem;
|
||||
|
||||
/* A content value is needed to get the ::after to render */
|
||||
content: '';
|
||||
}
|
||||
|
||||
header {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
text-align: center;
|
||||
border-block-end: 1px solid var(--colour-primary-fg);
|
||||
}
|
||||
|
||||
header h1 {
|
||||
grid-column: 1 / 3;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.technical-skills h3 {
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.technical-skills ul {
|
||||
color: var(--colour-primary-fg-accent);
|
||||
margin-inline-start: var(--spacing-inline-md);
|
||||
}
|
||||
|
||||
@media (min-width: 46rem) {
|
||||
.technical-skills section {
|
||||
display: flex;
|
||||
gap: var(--spacing-inline-sm);
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.technical-skills section h3::after {
|
||||
content: '/';
|
||||
margin-inline: var(--spacing-inline-sm);
|
||||
}
|
||||
|
||||
.technical-skills section ul {
|
||||
display: flex;
|
||||
gap: var(--spacing-inline-sm);
|
||||
list-style: none;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.technical-skills section ul li + li::before {
|
||||
content: '•';
|
||||
margin-inline-end: var(--spacing-inline-sm);
|
||||
}
|
||||
}
|
||||
|
||||
:is(.experience, .passions) :is(ol, ul) {
|
||||
list-style: none;
|
||||
margin-inline: 0;
|
||||
}
|
||||
|
||||
:is(.experience, .passions) :is(ol, ul) li {
|
||||
margin-block-start: var(--spacing-block-sm);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/* Assumes there is at most one level of subheading for sub-dividing entries */
|
||||
.h-feed :is(h2, h3, h4, h5, h6) {
|
||||
margin-block-start: var(--spacing-block-md);
|
||||
}
|
||||
|
||||
.h-feed .h-entry {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.h-feed .h-entry + .h-entry {
|
||||
margin-block-start: var(--spacing-block-md);
|
||||
}
|
||||
|
||||
.h-feed .h-entry > * {
|
||||
order: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.h-feed .h-entry .dt-published {
|
||||
order: 0;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.h-feed .h-entry .p-name {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.h-feed .full-feed-link {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.h-feed :is(a.full-feed-link, .full-feed-link a)::after {
|
||||
content: " >";
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
.h-card div:has(img) {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.h-card img {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
border-radius: 1rem;
|
||||
filter: contrast(1.25);
|
||||
}
|
||||
|
||||
.h-card div:has(img)::after {
|
||||
/* Colour overlay */
|
||||
background-color: var(--colour-primary-80);
|
||||
opacity: 0.3;
|
||||
|
||||
/* Same size and shape as the img */
|
||||
border-radius: 1rem;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
|
||||
/* Positioned on top of the img */
|
||||
display: block;
|
||||
position: relative;
|
||||
top: -6rem;
|
||||
|
||||
/* A content value is needed to get the ::after to render */
|
||||
content: "";
|
||||
}
|
||||
|
||||
@media (min-width: 36rem) {
|
||||
.h-card {
|
||||
grid-column: media-start / content-end;
|
||||
display: grid;
|
||||
grid-template-columns: subgrid; /** Subgrid of main column layout */
|
||||
grid-template-rows: min-content 1fr;
|
||||
grid-template-areas:
|
||||
"empty heading"
|
||||
"photo text";
|
||||
column-gap: var(--spacing-block-sm);
|
||||
}
|
||||
|
||||
.h-card div:has(img) {
|
||||
grid-area: photo;
|
||||
margin-block-start: var(--spacing-block-sm);
|
||||
}
|
||||
|
||||
.h-card header {
|
||||
grid-area: heading;
|
||||
}
|
||||
|
||||
.h-card__text {
|
||||
grid-area: text;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
.otp-inputs {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: var(--spacing-inline-sm);
|
||||
justify-content: center;
|
||||
|
||||
input {
|
||||
border: none;
|
||||
border-block-end: 2px solid var(--colour-grey-fg);
|
||||
font-size: var(--font-size-lg);
|
||||
text-align: center;
|
||||
width: var(--font-size-lg);
|
||||
}
|
||||
}
|
||||
|
||||
.otp-form {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-block-sm);
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
max-width: max-content;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
.p-summary {
|
||||
font-style: italic;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-block-start: var(--spacing-block-md);
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/* Based on Andy Bell’s More Modern CSS Reset: https://piccalil.li/blog/a-more-modern-css-reset/ */
|
||||
|
||||
/* Box sizing rules */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Prevent font size inflation */
|
||||
html {
|
||||
-moz-text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
/* Remove default margin in favour of better control in authored CSS */
|
||||
body,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
p,
|
||||
figure,
|
||||
blockquote,
|
||||
dl,
|
||||
dd {
|
||||
margin-block: 0;
|
||||
}
|
||||
|
||||
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
|
||||
ul[role="list"],
|
||||
ol[role="list"] {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Set core body defaults */
|
||||
body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Set shorter line heights on headings and interactive elements */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
button,
|
||||
input,
|
||||
label {
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
/* Balance text wrapping on headings */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
/* Make images easier to work with */
|
||||
img,
|
||||
picture {
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Inherit fonts for inputs and buttons */
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
/* Make sure textareas without a rows attribute are not tiny */
|
||||
textarea:not([rows]) {
|
||||
min-height: 10em;
|
||||
}
|
||||
|
||||
/* Anything that has been anchored to should have extra scroll margin */
|
||||
:target {
|
||||
scroll-margin-block: 5ex;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
../../common/images/
|
||||
@@ -1,36 +0,0 @@
|
||||
export default {
|
||||
"/links": "/microlog",
|
||||
"/links/rss.xml": "/microlog/rss.xml",
|
||||
"/blog/2024/10/tracking_pixels": "/blog/2024-04-10",
|
||||
"/blog/2024/01/14/sapiens_on_religion": "/blog/2024-01-14",
|
||||
"/blog/2024/01/29/euhwc_toast_to_the_lasses_2024": "/blog/2024-01-29",
|
||||
"/blog/2024/03/30/easter": "/blog/2024-03-30",
|
||||
"/blog/2024/04/10/tracking_pixels": "/blog/2024-04-10",
|
||||
"/blog/2024/04/11/who_consecrates_the_temple": "/blog/2024-04-11",
|
||||
"/blog/2024/04/14/god_is_not_great": "/blog/2024-04-14",
|
||||
"/blog/2024/05/02/no_more_youtube": "/blog/2024-05-02",
|
||||
"/blog/2024/06/13/llms_do_not_understand_anything": "/blog/2024-06-13",
|
||||
"/blog/2024/07/08/doctor_who_gayness_church": "/blog/2024-07-08",
|
||||
"/blog/2024/07/16/word_hallucination_with_reference_to_llms":
|
||||
"/blog/2024-07-16",
|
||||
"/blog/2024/12/17/open_questions_about_sex": "/blog/2024-12-17",
|
||||
"/blog/2025/01/19/my_feed_and_reading_list": "/blog/2025-01-19",
|
||||
"/blog/2025/01/19/newsboat-post.webp": "/blog/2025-01-19_newsboat-post.webp",
|
||||
"/blog/2025/01/19/newsboat.webp": "/blog/2025-01-19_newsboat.webp",
|
||||
"/blog/2025/01/19/ranger.webp": "/blog/2025-01-19_ranger.webp",
|
||||
"/blog/2025/01/19/w3m.webp": "/blog/2025-01-19_w3m.webp",
|
||||
"/blog/2025/01/24/science_and_philosophy": "/blog/2025-01-24",
|
||||
"/blog/2025/01/28/paradox": "/blog/2025-01-28",
|
||||
"/blog/2025/05/02/surprised_by_hope": "/blog/2025-05-02",
|
||||
"/blog/2025/05/04/does_resurrection_ground_works": "/blog/2025-05-04",
|
||||
"/blog/2025/06/23/work": "/blog/2025-06-23",
|
||||
"/blog/2025/07/03/ps118": "/blog/2025-07-03",
|
||||
"/blog/2025/09/18/starting_msc": "/blog/2025-09-18",
|
||||
"/blog/2025/09/24/creeds": "/blog/2025-09-24",
|
||||
"/blog/2025/10/05/creeds": "/blog/2025-10-05",
|
||||
"/blog/2025/10/09/arius": "/blog/2025-10-09",
|
||||
"/blog/2025/12/11/persecution": "/blog/2025-12-11",
|
||||
"/blog/2026/02/16/short_reformation_stories": "/blog/2026-02-16",
|
||||
"/blog/2026/03/04/agnostic": "/blog/2026-03-04",
|
||||
"/blog/2026/03/21/genesis": "/blog/2026-03-21",
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
import otp from "./otp/otp";
|
||||
import sendmail from "./sendmail";
|
||||
|
||||
export const server = {
|
||||
otp,
|
||||
sendmail,
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
import send from "./send-otp";
|
||||
import verify from "./verify-otp";
|
||||
|
||||
export default {
|
||||
send,
|
||||
verify,
|
||||
};
|
||||
@@ -1,63 +0,0 @@
|
||||
import crypto from "node:crypto";
|
||||
import { z } from "astro/zod";
|
||||
import { defineAction } from "astro:actions";
|
||||
import { db, gte, Otp, SentEmails } from "astro:db";
|
||||
import { transporter } from "../sendmail";
|
||||
import { LOCAL_SMTP_ENVELOPE_FROM, MAX_DAILY_EMAILS } from "astro:env/server";
|
||||
|
||||
export default defineAction({
|
||||
input: z.object({
|
||||
email: z.string().email(),
|
||||
name: z.string().optional(),
|
||||
type: z.enum(["email"]),
|
||||
}),
|
||||
handler: sendOtp,
|
||||
});
|
||||
|
||||
type OtpParams = {
|
||||
email: string;
|
||||
name?: string;
|
||||
type: "email";
|
||||
};
|
||||
|
||||
async function sendOtp({ email, name }: OtpParams) {
|
||||
const otp = crypto.randomBytes(3).toString("hex").toLocaleUpperCase();
|
||||
const otpPretty = `${otp.slice(0, 3)}-${otp.slice(3)}`;
|
||||
|
||||
const emailsSentLast24Hours = await db.$count(
|
||||
SentEmails,
|
||||
gte(SentEmails.sentAt, Date.now() - 1000 * 60 * 60 * 24),
|
||||
);
|
||||
if (emailsSentLast24Hours >= MAX_DAILY_EMAILS) {
|
||||
console.warn(
|
||||
`${name} <${email}> requested an OTP, but ${emailsSentLast24Hours} have already been sent, whereas the max daily load is ${MAX_DAILY_EMAILS}.`,
|
||||
);
|
||||
throw new Error(
|
||||
`${emailsSentLast24Hours} emails have been sent in the last 24 hours, but the max daily load is ${MAX_DAILY_EMAILS}.`,
|
||||
);
|
||||
}
|
||||
|
||||
const info = await transporter.sendMail({
|
||||
from: LOCAL_SMTP_ENVELOPE_FROM,
|
||||
to: `${name ? `"${name}" ` : ""}<${email}>`,
|
||||
subject: `joeac.net: your OTP is ${otpPretty}`,
|
||||
text: `
|
||||
Someone tried to use this email address on joeac.net. If this was you,
|
||||
your one-time passcode is ${otpPretty}. If this wasn't you, you don't need
|
||||
to do anything.`,
|
||||
});
|
||||
console.log(
|
||||
`Sent OTP (${otpPretty}) to ${email}. Message ID: ${info.messageId}`,
|
||||
);
|
||||
|
||||
await db
|
||||
.insert(SentEmails)
|
||||
.values({ messageId: info.messageId, sentAt: Date.now() });
|
||||
|
||||
await db.insert(Otp).values({
|
||||
userId: email,
|
||||
value: otp,
|
||||
createdAt: Date.now(),
|
||||
validUntil: Date.now() + 1000 * 60 * 5,
|
||||
});
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { z } from "astro/zod";
|
||||
import { defineAction } from "astro:actions";
|
||||
import { and, db, eq, gte, Otp, SendmailToken } from "astro:db";
|
||||
|
||||
export default defineAction({
|
||||
input: z.object({
|
||||
guess: z.string().length(6),
|
||||
lenient: z.boolean().default(false),
|
||||
userId: z.string().nonempty(),
|
||||
}),
|
||||
handler: verifyOtp,
|
||||
});
|
||||
|
||||
async function verifyOtp({ guess, lenient, userId }: VerifyOtpParams) {
|
||||
const leniency = lenient ? 1000 * 60 : 0;
|
||||
const isOtpCorrect =
|
||||
(await db.$count(
|
||||
Otp,
|
||||
and(
|
||||
eq(Otp.userId, userId),
|
||||
eq(Otp.value, guess),
|
||||
gte(Otp.validUntil, Date.now() - leniency),
|
||||
),
|
||||
)) > 0;
|
||||
|
||||
if (!isOtpCorrect) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await db.delete(Otp).where(and(eq(Otp.userId, userId), eq(Otp.value, guess)));
|
||||
|
||||
const token = randomBytes(256).toString("hex");
|
||||
await db.insert(SendmailToken).values({
|
||||
userId,
|
||||
value: token,
|
||||
createdAt: Date.now(),
|
||||
validUntil: Date.now() + 60_000,
|
||||
});
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
type VerifyOtpParams = {
|
||||
guess: string;
|
||||
lenient: boolean;
|
||||
userId: string;
|
||||
};
|
||||
@@ -1,97 +0,0 @@
|
||||
import { z } from "astro/zod";
|
||||
import { defineAction } from "astro:actions";
|
||||
import nodemailer from "nodemailer";
|
||||
import {
|
||||
MAX_DAILY_EMAILS,
|
||||
LOCAL_SMTP_HOST,
|
||||
LOCAL_SMTP_PASSWORD,
|
||||
LOCAL_SMTP_PORT,
|
||||
LOCAL_SMTP_USER,
|
||||
CONTACT_MAILBOX,
|
||||
LOCAL_SMTP_ENVELOPE_FROM,
|
||||
} from "astro:env/server";
|
||||
import { and, db, eq, gte, SendmailToken, SentEmails } from "astro:db";
|
||||
|
||||
export default defineAction({
|
||||
input: z.object({
|
||||
email: z.string().email(),
|
||||
message: z.string().nonempty(),
|
||||
name: z.string().nonempty(),
|
||||
userId: z.string().nonempty(),
|
||||
token: z.string().nonempty(),
|
||||
}),
|
||||
handler: sendmail,
|
||||
});
|
||||
|
||||
type SendEmailParams = {
|
||||
email: string;
|
||||
message: string;
|
||||
name: string;
|
||||
token: string;
|
||||
userId: string;
|
||||
};
|
||||
|
||||
async function sendmail({
|
||||
name,
|
||||
email,
|
||||
message,
|
||||
token,
|
||||
userId,
|
||||
}: SendEmailParams) {
|
||||
const isTokenCorrect =
|
||||
(await db.$count(
|
||||
SendmailToken,
|
||||
and(
|
||||
eq(SendmailToken.userId, userId),
|
||||
eq(SendmailToken.value, token),
|
||||
gte(SendmailToken.validUntil, Date.now()),
|
||||
),
|
||||
)) > 0;
|
||||
if (!isTokenCorrect) {
|
||||
return false;
|
||||
}
|
||||
await db
|
||||
.delete(SendmailToken)
|
||||
.where(
|
||||
and(eq(SendmailToken.userId, userId), eq(SendmailToken.value, token)),
|
||||
);
|
||||
|
||||
const emailsSentLast24Hours = await db.$count(
|
||||
SentEmails,
|
||||
gte(SentEmails.sentAt, Date.now() - 1000 * 60 * 60 * 24),
|
||||
);
|
||||
if (emailsSentLast24Hours > MAX_DAILY_EMAILS) {
|
||||
console.warn(
|
||||
`${name} <${email}> tried to send an email, but ${emailsSentLast24Hours} have already been sent, whereas the max daily load is ${MAX_DAILY_EMAILS}.`,
|
||||
);
|
||||
throw new Error(
|
||||
`${emailsSentLast24Hours} emails have been sent in the last 24 hours, but the max daily load is ${MAX_DAILY_EMAILS}.`,
|
||||
);
|
||||
}
|
||||
|
||||
const info = await transporter.sendMail({
|
||||
from: LOCAL_SMTP_ENVELOPE_FROM,
|
||||
to: CONTACT_MAILBOX,
|
||||
subject: `joeac.net: ${name} left a message`,
|
||||
text: `${name} <${email}> sent you a message:\n\n\n${message}`,
|
||||
});
|
||||
|
||||
await db
|
||||
.insert(SentEmails)
|
||||
.values({ messageId: info.messageId, sentAt: Date.now() });
|
||||
|
||||
console.log("Sent an email to Joe. Message ID: ", info.messageId);
|
||||
}
|
||||
|
||||
export const transporter = nodemailer.createTransport({
|
||||
host: LOCAL_SMTP_HOST,
|
||||
from: LOCAL_SMTP_ENVELOPE_FROM,
|
||||
port: LOCAL_SMTP_PORT,
|
||||
secure: false,
|
||||
authMethod: "PLAIN",
|
||||
auth: {
|
||||
type: "login",
|
||||
user: LOCAL_SMTP_USER,
|
||||
pass: LOCAL_SMTP_PASSWORD,
|
||||
},
|
||||
});
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
image?: string;
|
||||
}
|
||||
|
||||
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
|
||||
|
||||
const { title, description, image = '/images/headshot.jpg' } = Astro.props;
|
||||
---
|
||||
|
||||
<!-- IndieWeb -->
|
||||
<link rel="authorization_endpoint" href="https://indieauth.com/auth">
|
||||
<link rel="token_endpoint" href="https://tokens.indieauth.com/token">
|
||||
<link rel="micropub" href="https://tasty-windows-lick.loca.lt">
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" href="/css/reset.css" />
|
||||
<link rel="stylesheet" href="/css/base.css" />
|
||||
<link rel="stylesheet" href="/css/hcard.css" />
|
||||
<link rel="stylesheet" href="/css/feed.css" />
|
||||
|
||||
<!-- Global Metadata -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
|
||||
<!-- Canonical URL -->
|
||||
<link rel="canonical" href={canonicalURL} />
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>{title}</title>
|
||||
<meta name="title" content={title} />
|
||||
<meta name="description" content={description} />
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={Astro.url} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content={new URL(image, Astro.url)} />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={Astro.url} />
|
||||
<meta property="twitter:title" content={title} />
|
||||
<meta property="twitter:description" content={description} />
|
||||
<meta property="twitter:image" content={new URL(image, Astro.url)} />
|
||||
|
||||
<!-- Feeds -->
|
||||
<link rel="alternate" type="text/xml" title="Blog RSS" href="/blog/rss.xml">
|
||||
<link rel="alternate" type="text/xml" title="Links RSS" href="/links/rss.xml">
|
||||
@@ -1,103 +0,0 @@
|
||||
---
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
import { getCollection } from 'astro:content';
|
||||
import FormattedDate from './FormattedDate.astro';
|
||||
|
||||
export interface Props {
|
||||
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6,
|
||||
hideAuthor?: boolean,
|
||||
hideSubheadings?: boolean,
|
||||
maxEntries?: number,
|
||||
};
|
||||
|
||||
const { headingLevel = 2, hideSubheadings = false, hideAuthor = false, maxEntries } = Astro.props;
|
||||
|
||||
const allPosts = (await getCollection('blog')).filter((post) => !post.data.hidden);
|
||||
|
||||
const posts = maxEntries === undefined
|
||||
? allPosts
|
||||
: allPosts.sort(sortByPubDateDescending).slice(0, maxEntries);
|
||||
|
||||
const distinctYears: number[] = posts
|
||||
.map(post => pubDate(post).getFullYear())
|
||||
.reduce<number[]>((acc, curr) => acc.includes(curr) ? acc : [...acc, curr], [])
|
||||
.sort((a, b) => b - a);
|
||||
|
||||
function matchesYear(year: number) {
|
||||
return (post: CollectionEntry<'blog'>) => pubDate(post).getFullYear() === year;
|
||||
}
|
||||
|
||||
function sortByPubDateDescending(post1: CollectionEntry<'blog'>, post2: CollectionEntry<'blog'>) {
|
||||
const date1 = pubDate(post1).getTime();
|
||||
const date2 = pubDate(post2).getTime();
|
||||
return date2 - date1;
|
||||
}
|
||||
|
||||
function pubDate(post: CollectionEntry<'blog'>): Date {
|
||||
if (post.data.pubDate) {
|
||||
return post.data.pubDate;
|
||||
}
|
||||
const date = new Date(post.id);
|
||||
if (isNaN(date.valueOf())) {
|
||||
throw new Error(`Post ${post.id} does not have a valid publication date.`);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
const HeadingElem = `h${headingLevel} class="p-name"`;
|
||||
const SubHeadingElem = `h${headingLevel + 1}`;
|
||||
const SubSubHeadingElem = `h${headingLevel + 2}`;
|
||||
const AuthorElem = `p${hideAuthor ? " hidden" : ""}`;
|
||||
|
||||
const canonicalBlogUrl = new URL('blog', Astro.site)
|
||||
---
|
||||
|
||||
<section class="h-feed">
|
||||
<HeadingElem>
|
||||
My blog
|
||||
</HeadingElem>
|
||||
|
||||
<aside>
|
||||
<AuthorElem>
|
||||
This blog is written by <a class="p-author h-card" href="/">Joe Carstairs</a>
|
||||
</AuthorElem>
|
||||
|
||||
<p hidden>
|
||||
<a class="u-url" href={canonicalBlogUrl}>Permalink</a>
|
||||
</p>
|
||||
</aside>
|
||||
|
||||
<slot />
|
||||
|
||||
{ hideSubheadings
|
||||
? <ul>
|
||||
{ posts.sort(sortByPubDateDescending).map(post => (
|
||||
<li class="h-entry">
|
||||
<SubSubHeadingElem>
|
||||
<a class="u-url p-name" href={`/blog/${post.id}`}>{post.data.title}</a>
|
||||
</SubSubHeadingElem>
|
||||
<p class="p-summary" set:html={post.data.description} />
|
||||
<FormattedDate className="dt-published" date={pubDate(post)} />
|
||||
</li>
|
||||
)) }
|
||||
</ul>
|
||||
: distinctYears.map(year => (
|
||||
<SubHeadingElem>{year}</SubHeadingElem>
|
||||
<ul>
|
||||
{ posts.filter(matchesYear(year)).sort(sortByPubDateDescending).map(post => (
|
||||
<li class="h-entry">
|
||||
<SubSubHeadingElem>
|
||||
<a class="u-url p-name" href={`/blog/${post.id}`}>{post.data.title}</a>
|
||||
</SubSubHeadingElem>
|
||||
<p class="p-summary" set:html={post.data.description} />
|
||||
<FormattedDate className="dt-published" date={pubDate(post)} />
|
||||
</li>
|
||||
)) }
|
||||
</ul>
|
||||
)) }
|
||||
|
||||
{ (maxEntries !== undefined && maxEntries < allPosts.length)
|
||||
? <p class="full-feed-link"><a href="/blog">All blog posts</a></p>
|
||||
: <></>
|
||||
}
|
||||
</section>
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
interface Props {
|
||||
className?: string;
|
||||
date: Date | string;
|
||||
hidden?: boolean;
|
||||
}
|
||||
|
||||
let { className, date, hidden } = Astro.props;
|
||||
if (typeof(date) === 'string') {
|
||||
date = new Date(date);
|
||||
}
|
||||
const dateStr =
|
||||
date.toLocaleDateString('en-GB', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
});
|
||||
---
|
||||
|
||||
{ hidden
|
||||
? <time datetime={date.toISOString()} class={className ?? ''} hidden>{dateStr}</time>
|
||||
: <time datetime={date.toISOString()} class={className ?? ''}>{dateStr}</time>
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
---
|
||||
import FormattedDate from '../components/FormattedDate.astro';
|
||||
import allLinks from '../data/links.ts';
|
||||
|
||||
type Link = (typeof allLinks)[number];
|
||||
|
||||
export interface Props {
|
||||
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6,
|
||||
hideAuthor?: boolean,
|
||||
maxEntries?: number,
|
||||
};
|
||||
|
||||
const { headingLevel = 2, hideAuthor = false, maxEntries } = Astro.props;
|
||||
|
||||
const headingElem = `h${headingLevel}`;
|
||||
const subHeadingElem = `h${headingLevel + 1}`
|
||||
|
||||
const links: Link[] = maxEntries === undefined
|
||||
? allLinks
|
||||
: allLinks.sort(sortByDateAddedDescending).slice(0, maxEntries);
|
||||
|
||||
const distinctYears: string[] = links
|
||||
.map(link => link.isoDateAdded.slice(0,4))
|
||||
.reduce<string[]>((acc, curr) => acc.includes(curr) ? acc : [...acc, curr], [])
|
||||
.sort((a, b) => Number.parseInt(b) - Number.parseInt(a));
|
||||
|
||||
function matchesYear(year: string) {
|
||||
return (link: (typeof links)[number]) => link.isoDateAdded.slice(0,4) === year;
|
||||
}
|
||||
|
||||
function sortByDateAddedDescending(link1: (typeof links)[number], link2: (typeof links)[number]) {
|
||||
const date1 = new Date(link1.isoDateAdded).getTime();
|
||||
const date2 = new Date(link2.isoDateAdded).getTime();
|
||||
return date2 - date1;
|
||||
}
|
||||
|
||||
const canonicalLinksUrl = new URL('links', Astro.site)
|
||||
---
|
||||
|
||||
<section class="h-feed">
|
||||
<Fragment set:html={`
|
||||
<${headingElem} class="p-name">
|
||||
My links
|
||||
</${headingElem}>
|
||||
`} />
|
||||
|
||||
<aside>
|
||||
<p hidden={hideAuthor}>
|
||||
These links are collected by <a class="p-author h-card" href="/">Joe Carstairs</a>
|
||||
</p>
|
||||
|
||||
<p hidden>
|
||||
<a class="u-url" href={canonicalLinksUrl}>Permalink</a>
|
||||
</p>
|
||||
</aside>
|
||||
|
||||
{ distinctYears.map(year => (
|
||||
<Fragment set:html={`
|
||||
<${subHeadingElem}>
|
||||
${year}
|
||||
</${subHeadingElem}>
|
||||
`} />
|
||||
<ul>
|
||||
{ links.filter(matchesYear(year)).sort(sortByDateAddedDescending).map(link => (
|
||||
<li class="h-entry e-content">
|
||||
<FormattedDate className="dt-published" date={link.isoDateAdded} />
|
||||
<a class="u-url p-name" href={link.href} set:html={link.title} />
|
||||
<p class="p-description" set:html={link.description} />
|
||||
</li>
|
||||
)) }
|
||||
</ul>
|
||||
)) }
|
||||
|
||||
{ (maxEntries !== undefined && maxEntries < allLinks.length)
|
||||
? <p class="full-feed-link"><a href="/links">All links</a></p>
|
||||
: <></>
|
||||
}
|
||||
</section>
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
---
|
||||
|
||||
<section class="h-card">
|
||||
<div>
|
||||
<img class="u-photo" src="/images/headshot.webp" height="96" width="96" />
|
||||
</div>
|
||||
|
||||
<header>
|
||||
<h1>
|
||||
Joe Carstairs
|
||||
</h1>
|
||||
|
||||
<div hidden>
|
||||
<a class="p-name u-url u-uid" href="https://joeac.net" rel="me">
|
||||
Permalink
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="h-card__text">
|
||||
<p>
|
||||
Hi! 👋 My name is <span class="p-given-name">Joe</span>
|
||||
<span class="p-family-name">Carstairs</span>. I’m a
|
||||
<span class="p-job-title">software developer</span> at
|
||||
<a class="p-org" href="https://www.scottlogic.com">Scott Logic</a>,
|
||||
a Divinity student at the University of Edinburgh,
|
||||
a lapsed fiddle player and a very occasional poet.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
HMU with your thoughts on Elizabethan poetry, connecting to the
|
||||
Internet, and the Apocalypse of Saint John.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<small>
|
||||
Or get me on
|
||||
<a href="https://www.facebook.com/joe.carstairs.5" rel="me">Facebook</a>,
|
||||
<a href="https://mastodon.social/@joe_carstairs" rel="me">Mastodon</a>,
|
||||
<a href="https://www.linkedin.com/in/joe-carstairs-0aa936277" rel="me">LinkedIn</a>,
|
||||
<a href="https://bsky.app/profile/joeacarstairs.bsky.social" rel="me">BlueSky</a>,
|
||||
or <a href="https://github.com/joeacarstairs" rel="me">GitHub</a>.
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,100 +0,0 @@
|
||||
---
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
import { getCollection } from 'astro:content';
|
||||
import FormattedDate from './FormattedDate.astro';
|
||||
import { renderGemtextToHtml } from '../renderGemtextToHtml';
|
||||
|
||||
export interface Props {
|
||||
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6,
|
||||
hideAuthor?: boolean,
|
||||
hideSubheadings?: boolean,
|
||||
maxEntries?: number,
|
||||
};
|
||||
|
||||
const { headingLevel = 2, hideSubheadings = false, hideAuthor = false, maxEntries } = Astro.props;
|
||||
|
||||
const allPosts = await getCollection('microlog');
|
||||
|
||||
const posts = maxEntries === undefined
|
||||
? allPosts
|
||||
: allPosts.sort(sortByIdDescending).slice(0, maxEntries);
|
||||
|
||||
const distinctYears: number[] = posts
|
||||
.map(post => pubDate(post).getFullYear())
|
||||
.reduce<number[]>((acc, curr) => acc.includes(curr) ? acc : [...acc, curr], [])
|
||||
.sort((a, b) => b - a);
|
||||
|
||||
function matchesYear(year: number) {
|
||||
return (post: CollectionEntry<'microlog'>) => pubDate(post).getFullYear() === year;
|
||||
}
|
||||
|
||||
function sortByIdDescending(post1: CollectionEntry<'microlog'>, post2: CollectionEntry<'microlog'>) {
|
||||
return post2.id.localeCompare(post1.id);
|
||||
}
|
||||
|
||||
function pubDate(post: CollectionEntry<'microlog'>): Date {
|
||||
console.warn(post.id);
|
||||
const date = new Date(post.id.replace(/\.[0-9]+$/g, ''));
|
||||
if (isNaN(date.valueOf())) {
|
||||
throw new Error(`Post ${post.id} does not have a valid publication date.`);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
const HeadingElem = `h${headingLevel} class="p-name"`;
|
||||
const SubHeadingElem = `h${headingLevel + 1}`;
|
||||
const SubSubHeadingElem = `h${headingLevel + 2}`;
|
||||
const AuthorElem = `p${hideAuthor ? " hidden" : ""}`;
|
||||
|
||||
const canonicalMicrologUrl = new URL('microlog', Astro.site)
|
||||
---
|
||||
|
||||
<section class="h-feed">
|
||||
<HeadingElem>
|
||||
My microlog
|
||||
</HeadingElem>
|
||||
|
||||
<aside>
|
||||
<AuthorElem>
|
||||
This microlog is written by <a class="p-author h-card" href="/">Joe Carstairs</a>
|
||||
</AuthorElem>
|
||||
|
||||
<p hidden>
|
||||
<a class="u-url" href={canonicalMicrologUrl}>Permalink</a>
|
||||
</p>
|
||||
</aside>
|
||||
|
||||
<slot />
|
||||
|
||||
{ hideSubheadings
|
||||
? <ul>
|
||||
{ posts.sort(sortByIdDescending).map(post => (
|
||||
<li class="h-entry">
|
||||
<SubSubHeadingElem>
|
||||
<a class="u-url p-name" href={`/microlog/${post.id}`}>{post.id}</a>
|
||||
</SubSubHeadingElem>
|
||||
<section class="e-content" set:html={post.body} />
|
||||
<FormattedDate hidden={true} className="dt-published" date={pubDate(post)} />
|
||||
</li>
|
||||
)) }
|
||||
</ul>
|
||||
: distinctYears.map(year => (
|
||||
<SubHeadingElem>{year}</SubHeadingElem>
|
||||
<ul>
|
||||
{ posts.filter(matchesYear(year)).sort(sortByIdDescending).map(post => (
|
||||
<li class="h-entry">
|
||||
<SubSubHeadingElem>
|
||||
<a class="u-url p-name" href={`/microlog/${post.id}`}>{post.id}</a>
|
||||
</SubSubHeadingElem>
|
||||
<section class="e-content" set:html={renderGemtextToHtml(post.body ?? '')} />
|
||||
<FormattedDate hidden={true} className="dt-published" date={pubDate(post)} />
|
||||
</li>
|
||||
)) }
|
||||
</ul>
|
||||
)) }
|
||||
|
||||
{ (maxEntries !== undefined && maxEntries < allPosts.length)
|
||||
? <p class="full-feed-link"><a href="/microlog">All microlog posts</a></p>
|
||||
: <></>
|
||||
}
|
||||
</section>
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
---
|
||||
|
||||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/">Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/blog">Blog</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/microlog">Microlog</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/contact">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
---
|
||||
|
||||
<script src="../scripts/otp-form-wc.ts"></script>
|
||||
<link rel="stylesheet" href="/css/otp.css" />
|
||||
|
||||
<dialog class="otp-dialog">
|
||||
<otp-form>
|
||||
<form class="otp-form" class="otp-form">
|
||||
<p>
|
||||
I've sent a six-digit code to <span class="otp-recipient">your email address</span>.
|
||||
Let me know what it is, so I can confirm this really is your email address. The
|
||||
code will be valid <span class="otp-valid-until">for five minutes</span>.
|
||||
</p>
|
||||
|
||||
<p hidden class="error"/>
|
||||
|
||||
<div class="otp-inputs">
|
||||
<input maxlength="1" name="1" required autocapitalize="characters" autocomplete="one-time-code" aria-label="First digit of one-time passcode" autofocus>
|
||||
<input maxlength="1" name="2" required autocapitalize="characters" autocomplete="one-time-code" aria-label="Second digit of one-time passcode">
|
||||
<input maxlength="1" name="3" required autocapitalize="characters" autocomplete="one-time-code" aria-label="Third digit of one-time passcode">
|
||||
<input maxlength="1" name="4" required autocapitalize="characters" autocomplete="one-time-code" aria-label="Fourth digit of one-time passcode">
|
||||
<input maxlength="1" name="5" required autocapitalize="characters" autocomplete="one-time-code" aria-label="Fifth digit of one-time passcode">
|
||||
<input maxlength="1" name="6" required autocapitalize="characters" autocomplete="one-time-code" aria-label="Sixth digit of one-time passcode">
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Verify">
|
||||
<button disabled class="resend-button">Resend (60s)</button>
|
||||
</form>
|
||||
</otp-form>
|
||||
</dialog>
|
||||
@@ -1,2 +0,0 @@
|
||||
export const SITE_TITLE = 'Joe Carstairs';
|
||||
export const SITE_DESCRIPTION = 'Joe’s personal website.';
|
||||
@@ -1,61 +0,0 @@
|
||||
import { defineCollection } from "astro:content";
|
||||
import { z } from "astro/zod";
|
||||
|
||||
import { extendedGlob } from "./loaders/extended-glob";
|
||||
import { glob } from "astro/loaders";
|
||||
|
||||
const blog = defineCollection({
|
||||
loader: extendedGlob({
|
||||
pattern: "**/*.(md|mdx|gmi|html)",
|
||||
base: "./src/content/blog",
|
||||
postprocessSlug: (slug: string) => slug.replaceAll(/^capsule-longlog\//g, ""),
|
||||
ignore: [
|
||||
"capsule-longlog/index.gmi",
|
||||
/* Some blog posts were ported to gemtext. Don't port them back again:
|
||||
* that would lead to duplicates! The originals are likely to be better
|
||||
* anyway, as MD/MDX are richer languages. */
|
||||
"**/2024-01-14.gmi",
|
||||
"**/2024-01-29.gmi",
|
||||
"**/2024-03-30.gmi",
|
||||
"**/2024-04-10.gmi",
|
||||
"**/2024-04-11.gmi",
|
||||
"**/2024-04-14.gmi",
|
||||
"**/2024-05-02.gmi",
|
||||
"**/2024-06-13.gmi",
|
||||
"**/2024-07-08.gmi",
|
||||
"**/2024-07-16.gmi",
|
||||
"**/2024-12-17.gmi",
|
||||
"**/2025-01-19.gmi",
|
||||
"**/2025-01-24.gmi",
|
||||
"**/2025-01-28.gmi",
|
||||
"**/2025-05-02.gmi",
|
||||
"**/2025-05-04.gmi",
|
||||
"**/2025-06-23.gmi",
|
||||
"**/2025-07-03.gmi",
|
||||
"**/2025-09-18.gmi",
|
||||
"**/2025-09-24.gmi",
|
||||
"**/2025-10-05.gmi",
|
||||
"**/2025-10-09.gmi",
|
||||
"**/2025-12-11.gmi",
|
||||
"**/2026-02-16.gmi",
|
||||
"**/2026-03-04.gmi",
|
||||
],
|
||||
}),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
hidden: z.optional(z.boolean()),
|
||||
description: z.optional(z.string()),
|
||||
pubDate: z.optional(z.date()),
|
||||
updatedDate: z.optional(z.date()),
|
||||
}),
|
||||
});
|
||||
|
||||
const microlog = defineCollection({
|
||||
loader: glob({
|
||||
pattern: "**/*.gmi",
|
||||
base: "./src/content/microlog",
|
||||
generateId: ({ entry }) => entry.replace(/\.gmi$/, ""),
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = { blog, microlog };
|
||||
@@ -1,74 +0,0 @@
|
||||
---
|
||||
title: Harari’s Sapiens on Religion
|
||||
description: >-
|
||||
In which I discuss why I think Harari’s characterisation of religion
|
||||
is inadequate because it’s too materialistic.
|
||||
pubDate: 2024-01-14
|
||||
---
|
||||
|
||||
I’ve been slowly re-reading Yuval Noah Harari’s 2014 classic,
|
||||
<a href="https://www.ynharari.com/book/sapiens-2">Sapiens</a>,
|
||||
which apart from being ridiculously over-scoped and hilariously
|
||||
under-evidenced, is proving delightfully entertaining.
|
||||
|
||||
I’ve just finished chapter 12, covering the world history of all
|
||||
religion in thirty pages. Of course, at that level of brevity,
|
||||
there will be many deficiencies. But here’s some thoughts - not
|
||||
terribly well organised - which stand out to me.
|
||||
|
||||
Hurari generally assumes a materialist metaphysic (a problem which
|
||||
blights the book more generally). Nothing exists except physical stuff.
|
||||
This gives him severe tunnel vision. As a consequence of this
|
||||
restricting metaphysic, he is forced to adopt limiting accounts of what
|
||||
the role of religion is in world history, and therefore what religion is.
|
||||
|
||||
> The crucial historical role of religion has been to give superhuman
|
||||
> legitimacy to [all social orders and hierarchies].
|
||||
> Religion can thus be defined as <em>a system of human norms and
|
||||
> values that is founded on a belief in a superhuman order</em>.
|
||||
> <footer>p. 234</footer>
|
||||
|
||||
It might seem a little unfair to criticise Harari for giving a
|
||||
materialist account of religion. <i>Sapiens</i> is, after all, a
|
||||
materialist world history.
|
||||
|
||||
But this account is just one extreme example of how that project, to
|
||||
give a materialist account of world history, will inevitably lack the
|
||||
metaphysical resources to really understand the human story.
|
||||
|
||||
On Harari’s view, any human enterprise which attempts to understand
|
||||
that which transcends direct human experience is at best an effort in
|
||||
imaginative story-telling. All scientific theory, theology, ethics and
|
||||
metaphysics either contorted out of all recognition into a pragmatic
|
||||
fiction or is cast to the flames.
|
||||
|
||||
In particular, it’s a view which is incapable of taking seriously some
|
||||
of the most important questions human beings have grappled with in the
|
||||
course of their history. Those who know me won’t be surprised at which
|
||||
ones I’m going to pick out: who was the being which made their covenant
|
||||
with Abraham? How is that promise being fulfilled? And who the heck was
|
||||
Jesus of Nazareth?
|
||||
|
||||
If Harari’s characterisation of religion is adequate - and the Abrahamic
|
||||
faiths come under that banner - then those questions are reduced to
|
||||
nothing more profound than Doctor Who fans arguing over ‘canon’. The
|
||||
question of who God is becomes a mere tool for the organisation of
|
||||
society, rather than a substantial and important question on a matter
|
||||
of fact.
|
||||
|
||||
This is a shortcoming for its own sake: a materialist account of
|
||||
religion cannot adequately account for the phenomenon of religion
|
||||
itself.
|
||||
|
||||
But it is also a shortcoming even by its own lights. Without giving
|
||||
serious consideration to the substantial matter of what Harari calls
|
||||
‘religion’ (which, to his mind, includes the Abrahamic faiths,
|
||||
Hinduism, paganism, animism, Buddhism, Shintoism, Confucianism,
|
||||
capitalism, communism and Nazism), even the material facts are
|
||||
inexplicable. Why would, as Harari is keen to point out, out, people
|
||||
fight and die over and over again for a fiction?
|
||||
|
||||
The material facts themselves prove that ‘religion’ as he construes it
|
||||
is not window dressing to the real story of history. It cannot merely
|
||||
serve as a mechanism in the churning of material history. It is itself
|
||||
the centre of the story.
|
||||
@@ -1,259 +0,0 @@
|
||||
---
|
||||
title: EUHWC Toast to the Lassies 2024
|
||||
hidden: true
|
||||
description: >-
|
||||
At the <a href="https://www.euhwc.co.uk">EUHWC</a> Burns meet in
|
||||
Ullapool last weekend, I had the last privilege of giving the Toast to
|
||||
the Lassies. Particularly for the benefit of those who weren’t there,
|
||||
here it is in full!
|
||||
pubDate: 2024-01-29
|
||||
---
|
||||
|
||||
Had Burns, instead of his sweet bonnie Jean,<br>
|
||||
his skills poetical for to mature<br>
|
||||
had any one of our club’s lassies seen<br>
|
||||
he would forever have remained obscure.<br>
|
||||
If he had nothing but this box of worms<br>
|
||||
Scotia would have been poorer, that I’m sure.<br>
|
||||
Now none of us can claim to be a Burns,<br>
|
||||
I’m no poetic master, still, I’ll have a punt,<br>
|
||||
though let’s be clear, I’ll do it on my terms.<br>
|
||||
I’ve everywhere avoided being blunt -<br>
|
||||
politeness matters more than any schema -<br>
|
||||
but it is hard when Isla’s such a cunt.<br>
|
||||
It was a challenge to produce a terza rima<br>
|
||||
I could recite withouten snoring;<br>
|
||||
you’ve been so stiff I thought youse had oedema.<br>
|
||||
The bother is this year is you’ll all been boring:<br>
|
||||
no drugs, no sex, no gossiping or lies,<br>
|
||||
no rock and roll, and hardly any whoring.<br>
|
||||
But hey well, rules is rules, I’ve had to try!<br>
|
||||
At least it can’t be worse than the reply.<br>
|
||||
|
||||
I’ll start with Audrey, the club’s senior member,<br>
|
||||
for if there’s something that I say which disconcerts her,<br>
|
||||
it’s fine: the poor old girl, she won’t remember.<br>
|
||||
She likes to let us think she’s a hard worker<br>
|
||||
but we’re electing a third social sec…<br>
|
||||
it’s pretty clear she’s just another shirker.<br>
|
||||
This lady, half American, half Czech,<br>
|
||||
for study, moved to Scotland for to do<br>
|
||||
American history – really, what the heck?<br>
|
||||
The club is so much louder thanks to you:<br>
|
||||
impressive vocals for just five foot two.<br>
|
||||
|
||||
That woman, Willow, reggles is bespeckled<br>
|
||||
with her sickle and her fishing tackle<br>
|
||||
shackled by the shins while she is heckled;<br>
|
||||
the way that Willow waddles maks me cackle<br>
|
||||
like a speckled jackal getting tickles,<br>
|
||||
worth a shekel in the tabernacle;<br>
|
||||
I chuckle muckle at her love of pickles<br>
|
||||
which she wiggles when she has the heart<br>
|
||||
while work for the Committee’s fickle trickles.<br>
|
||||
Her modus operandi: <em>you can’t rush art.</em><br>
|
||||
Her reimbursements programme’s going great;<br>
|
||||
any day now, she’ll maybe even start.<br>
|
||||
She cannot walk without Audrey, her mate:<br>
|
||||
I wonder when they’re going to consummate.<br>
|
||||
|
||||
Although they make them pretty tough in Peebles,<br>
|
||||
the thought of actually going up a peak<br>
|
||||
fills Shona Lewis with the heeble-jeebles.<br>
|
||||
New car? We miss your beautiful antique!<br>
|
||||
How long before this one’s also up a creek?<br>
|
||||
|
||||
Once there was a lass called Hannah Collier<br>
|
||||
whom even hell below regarded nasty,<br>
|
||||
deeply despised by all that dwells there.<br>
|
||||
Dating’s proceeding slowly for our lassie;<br>
|
||||
not far from giving up til she beguiles<br>
|
||||
a hot Italian in Southsider: classy!<br>
|
||||
At first, Michaelo seems to be all smiles<br>
|
||||
till it transpires he’s one of Dante’s demons…<br>
|
||||
I guess it’s back to posters of Harry Styles.<br>
|
||||
One day you’ll get a decent boy, keep dreamin;<br>
|
||||
somewhere there waits a handsome Mr Collier.<br>
|
||||
Hopefully when she meets him she’ll no be steamin.<br>
|
||||
Hannah, I’m not sure why you chose to maul your<br>
|
||||
poor skeleton at Subway (she’s still tetchy)<br>
|
||||
and then abandon what remains of all your<br>
|
||||
dignity at Ryvoan with a Frenchie!<br>
|
||||
I think he wishes that he never met ye.<br>
|
||||
|
||||
And has a quiet Felicia e’er been seen?<br>
|
||||
The energy she has is frankly wild.<br>
|
||||
I’ve never seen a hillwalker so keen!<br>
|
||||
<i lang="de">Ssie ischt raschtlos und nie gelangweilt</i>.<br>
|
||||
She eats raw oats with soggy protein powder:<br>
|
||||
a camping pot has ne’er been worse defiled.<br>
|
||||
She uses what her Maker has endowed her<br>
|
||||
with: her recorder skills are off the charts;<br>
|
||||
youse think I’m joking, but I wouldn’t doubt her!<br>
|
||||
This lass of the land of the Rot-Gold-Schwarz<br>
|
||||
will soon depart, though long we might beseech you<br>
|
||||
to stay. Of course, you’ll break all of our hearts,<br>
|
||||
but mine most of all. Any time, Felicia,<br>
|
||||
Creag Meagaidh calls, I know routes up the rear<br>
|
||||
dark and under-explored that I can teach you!<br>
|
||||
I won’t deny I think it’s rather queer<br>
|
||||
the things you do with chickpeas, but no matter.<br>
|
||||
You’re keen, you’re quick, you’re cool, that much is clear.<br>
|
||||
In fact, I think you’d make a damn good faffer:<br>
|
||||
swoop down on distilleries like the Luftwaffe.<br>
|
||||
|
||||
And now we come to our girl Emily Topness!<br>
|
||||
You’re keen for social sec. You’d suit the role<br>
|
||||
because… I’m not quite sure, it’s embdy’s guess.<br>
|
||||
We met your sister, and she was just as dull.<br>
|
||||
No, please drone on about Icelandic soil!<br>
|
||||
Poor Joe here down the front’s bored out his skull.<br>
|
||||
And since I mentioned Joe – I hate to spoil<br>
|
||||
it for you – but you’ve got the inferior Joe,<br>
|
||||
by Jove, no joke, it’s Jock here’s got the style!<br>
|
||||
Nah, write the boy a sonnet, get in the flow,<br>
|
||||
Whatever you produce’ll beat by thrice<br>
|
||||
your Masters thesis. What’d you got to show<br>
|
||||
for months of hunting for the butterflies?<br>
|
||||
‘There weren’t any.’ Oh, and have some sense,<br>
|
||||
cos I’ve heard rumours – I assume they’re lies –<br>
|
||||
you’ve called yourself the ‘poet in residence.’<br>
|
||||
You know you can’t compete, drop the pretence.<br>
|
||||
|
||||
Tereza was our gear sec for last year.<br>
|
||||
She helped herself to stuff: that’s factual.<br>
|
||||
Now when she asks to loan a bit club gear<br>
|
||||
we have to ask her to provide collateral.<br>
|
||||
She picked up tin whistle pretty sharp!<br>
|
||||
Which is to say, she’s not a natural.<br>
|
||||
She’s nowhere happier than under tarp<br>
|
||||
gazing up at the moon and stars alone<br>
|
||||
somewhere distant and remote like Glen Tarff.<br>
|
||||
Now what to say about Lucy Ma-the-soooon....<br>
|
||||
she likes… to faff… mm hmmm… well, moving on!<br>
|
||||
|
||||
And now we come to Emilie the French.<br>
|
||||
She seems to be nice on the trips we see her<br>
|
||||
but my distrust of frogs will ne’er be quenched.<br>
|
||||
Claims she’s a ‘pharmacist’? So she’s a dealer.<br>
|
||||
Need some pills in a pinch? You call, she’s there<br>
|
||||
at your door in her rally-approved four-wheeler.<br>
|
||||
One question we have is, why are you here?<br>
|
||||
Most folk are in uni, you’ve no refutin<br>
|
||||
you were kicked out after second year!<br>
|
||||
Now the Engineering grad, Sophia Newton.<br>
|
||||
Your namesake, Isaac, was a man convicted,<br>
|
||||
constructed calculus; but no computin,<br>
|
||||
not even Isaac’s, could’ve e’er predicted<br>
|
||||
you’d drop the Eng for creative writing!<br>
|
||||
now that’s what I would call a self-inflicted<br>
|
||||
inflection point! It must be quite enlightening,<br>
|
||||
but that doesn’t excuse when you give us an earful.<br>
|
||||
The blood boils in our veins, the rage heightening,<br>
|
||||
and you’re an American, that makes me fearful.<br>
|
||||
What’s your secret? You have us knackered!<br>
|
||||
What are you on to always be so cheerful?<br>
|
||||
Now we approach the topic of Merzbacher.<br>
|
||||
Wait, she’s not here? Abandoned ship?<br>
|
||||
She says she’s informatics: so she’s a hacker?<br>
|
||||
She has strong views, she lets her anger rip.<br>
|
||||
Poor George got an earful, full of future advice,<br>
|
||||
but why hasn’t she been on another club trip?<br>
|
||||
We’re cruel to focus on this list of vice;<br>
|
||||
the fact remains: she’s headstrong and nice.<br>
|
||||
|
||||
On Skye, a lady gave her poles to Sasha,<br>
|
||||
which was really nice - I mean just the best -<br>
|
||||
but Sasha really didn’t have to flash her.<br>
|
||||
Quick history lesson: way back, RBS<br>
|
||||
led the banking system to self-destruct<br>
|
||||
and left taxpayers to pick up the mess.<br>
|
||||
Since then, the name’s so irredeemably fucked<br>
|
||||
they’ve had to ditch the brand once and for all.<br>
|
||||
There’s one lassie who I need not instruct<br>
|
||||
What, these days, the Royal Bank is called<br>
|
||||
cos NatWest’s nasty history of scandal<br>
|
||||
didn’t stop Booth from working there at all.<br>
|
||||
Nothing motivates her more than to trample<br>
|
||||
upon the working class. They set her free.<br>
|
||||
She sank the pound quicker than the Belgrano,<br>
|
||||
because ‘there is no such thing as society,’<br>
|
||||
that’s how it is, is it? All right, I see.<br>
|
||||
|
||||
Now, coming all the way from Glenmore Lodge,<br>
|
||||
it’s Ellie’s turn! We have done what we can,<br>
|
||||
although I’m scared what she’ll put in my squash.<br>
|
||||
She wasn’t into Benji, but listen man,<br>
|
||||
you’re lucky that you dodged her drunken benders.<br>
|
||||
You’ll wake up in a tent in Kyrgystan,<br>
|
||||
as for how you got there, no-one remembers,<br>
|
||||
and if you’d known you’d be sleeping next to Ellie,<br>
|
||||
you would’ve brought some fucking ear defenders.<br>
|
||||
She’ll wrap you in bubblewrap, from your ears to your belly,<br>
|
||||
cotton clothes for none, and no complaining,<br>
|
||||
applying safety to the max, spare socks in your wellies.<br>
|
||||
She’s always at her Mountain Leader training,<br>
|
||||
practicing her night nav in the locale,<br>
|
||||
pursuing QMDs - unless it’s raining.<br>
|
||||
But some water should not scare our gal!<br>
|
||||
She’s had much experience with the wet as of late:<br>
|
||||
after all, she got on well with our navy pal.<br>
|
||||
What was the age of that particular first mate?<br>
|
||||
Older than your ex - always part of the plan?<br>
|
||||
Ah, of course! He was a spry twenty-eight!<br>
|
||||
Youth’s for the losers, let’s get you a real man,<br>
|
||||
mature and rugged, but kind and astute?<br>
|
||||
Just make sure he’s not as old as your gran.<br>
|
||||
One request we all have is you ditch the uke:<br>
|
||||
never have strings been pluckèd quite so shitely;<br>
|
||||
we would all much rather be hit by a nuke.<br>
|
||||
And please shut up about your nice society.<br>
|
||||
We are all glad you had a fun summer,<br>
|
||||
but bringing it up throws us right back to sobriety.<br>
|
||||
To lose you of course would be a bummer:<br>
|
||||
that is, for your carefully groomed newcomers.<br>
|
||||
|
||||
Now time for the main woman, El Presidente!<br>
|
||||
To here, it’s been like getting stones to bleed,<br>
|
||||
but in Isla Burslem’s case we’ve material aplenty!<br>
|
||||
As Holy Scripture says, ‘let those who lead<br>
|
||||
well be worthy of double honour,’ so<br>
|
||||
your bit is double length – it’s quite the screed!<br>
|
||||
I’ll start off with her brilliant boyfriend – oh!<br>
|
||||
Not boyfriend! Friend? To me this rather smacks<br>
|
||||
of low commitment, but what do I know?<br>
|
||||
So far, he’s disappointing, but on track.<br>
|
||||
What’s he up to Isla: seven minutes? neat!<br>
|
||||
Despite that, he is never holding back<br>
|
||||
your blossoming romance with Dr Peat.<br>
|
||||
Don’t deny it, that launch was pretty hard!<br>
|
||||
It’s fifth base next: that’s photos of his feet.<br>
|
||||
It’s fair to say her reputation’s marred.<br>
|
||||
We all regret that we did once anoint<br>
|
||||
her President: her premiership’s ill-starred.<br>
|
||||
Hey - you’re meant to be in charge of this joint!<br>
|
||||
You’re seldom seen cos of the mountaineering<br>
|
||||
meets that you’re always on. You’d made your point<br>
|
||||
before you chose to go off disappearing<br>
|
||||
to <em>New Zealand</em>… we get the message! Plus<br>
|
||||
we’ve had enough of all your domineering:<br>
|
||||
maybe it’s time we put you on a bus!<br>
|
||||
Nah, I’m just joking. All I’ve said’s refutable.<br>
|
||||
But the boys, we mean this next bit, all of us,<br>
|
||||
so stop me Isla if this isn’t suitable<br>
|
||||
but honestly we think your mum is beautiful.<br>
|
||||
|
||||
Alas, I have to bring an end to this rhyme.<br>
|
||||
I know it wasn’t much, in our defence,<br>
|
||||
the fact you used ChatGPT’s a crime.<br>
|
||||
I hope I’ve not caused over much offence<br>
|
||||
don’t worry, that is it, I’ve said my bit,<br>
|
||||
so I’ll turn from the ladies to the gents.<br>
|
||||
Yeah, don’t look away now, we wrote this shit!<br>
|
||||
I see you looking at your laces, Chris!<br>
|
||||
Wit without real goodwill is not legit,<br>
|
||||
so boys, don’t send sincerity to piss!<br>
|
||||
Why did God say he’d take our hearts of stone<br>
|
||||
and give us hearts of flesh? For this, for this!<br>
|
||||
Here is flesh of our flesh, bone of our bone;<br>
|
||||
love, and love nothing more but God alone.<br>
|
||||
@@ -1,95 +0,0 @@
|
||||
---
|
||||
title: Why Easter is the best week of the year
|
||||
description: >-
|
||||
Based on a talk given to my colleagues at
|
||||
<a href="https://www.scottlogic.co.uk">Scott Logic</a> for Maundy
|
||||
Thursday, 2024.
|
||||
pubDate: 2024-03-30
|
||||
---
|
||||
|
||||
As you might have noticed, it is Easter this week! So I'd like to take five or
|
||||
five minutes of your time to share why I – and about two billion other humans
|
||||
going about the place just now – think Easter is the best week of the year. And
|
||||
it's got something to do with a special Christian ritual called Communion.
|
||||
|
||||
Communion, at its heart, is about as simple a ritual as you can get. You get
|
||||
together with a bunch of other people. You share some bread, and you share some
|
||||
wine.
|
||||
|
||||
And it’s because of this ritual that so many people regard Easter as the best
|
||||
week of the year. I want to explain to you why that is, and more than that, I
|
||||
want to convince you that Easter is the best week of the year for you, too!
|
||||
|
||||
If you’ve passed by _The Hub_ at the top of Johnstone Terrace here in
|
||||
Edinburgh recently, you might have notice the banner which is draped over
|
||||
the railings just now – reading, ‘RITUALS THAT UNITE US.’
|
||||
|
||||
Now, that might seem like an odd idea. But wouldn’t that be great, if we
|
||||
actually had a ritual which could unite us? Because the world could surely do
|
||||
with a bit more unity right now. The world seems so divided, and sometimes it
|
||||
seems like there’s no hope for real unity.
|
||||
|
||||
We can see that in our politics. We’re divided about foreign policy, about
|
||||
taxation policy, about trade policy, about environmental policy.
|
||||
|
||||
And the conflicts that we have in this country seem pretty trivial when we
|
||||
remember the conflicts that are playing out in other parts of the world right
|
||||
now. In Israel and Gaza. In Sudan. In Russia and Ukraine.
|
||||
|
||||
And there’s plenty of conflict happening on the small scale, too. Often it’s the
|
||||
smallest-scale conflicts which hurt us the most deeply. Your landlord pushes you
|
||||
around. That friend you trusted like no-one else in the world lets you down. The
|
||||
partner or spouse you loved like no-one else in the world – you end up fighting.
|
||||
|
||||
It’s possible that you’re going to be reading this right now with a heavy heart
|
||||
because of a broken relationship in their life. And doesn’t that hurt more than
|
||||
anything else we know?
|
||||
|
||||
When the world is groaning so heavily under the weight of conflict, and some
|
||||
banner on _The Hub_ tells us a ritual can unite us, that seems so out of
|
||||
proportion to the scale of the problem, doesn’t it? What can a ritual do? A bit
|
||||
of old superstition? An excuse to divide people, maybe – what can a ritual do
|
||||
to unite us?
|
||||
|
||||
Well, two thousand years ago, a man had a meal with his friends. Together, they
|
||||
shared a meal of bread and wine – which, in that time and place, was the most
|
||||
ordinary meal imaginable.
|
||||
|
||||
And yet, in that most ordinary event imaginable, something was happening which
|
||||
was totally unimaginable. As this man, Jesus, shared the elements of this meal,
|
||||
he made some extraordinary statements about what he was doing: ‘take, eat, this
|
||||
is my body’ – ‘drink this, all of you; this is my blood of the new covenant.’
|
||||
(The word ‘covenant’ means a promise.)
|
||||
|
||||
He told them he wasn’t just giving them bread and wine, he was giving his body
|
||||
and his blood, and a promise.
|
||||
|
||||
Before Jesus ate another meal, he was flogged and nailed to a cross. His blood
|
||||
was spilt and his body broken, even to death.
|
||||
|
||||
And yet, that wasn’t the end of the Easter story. Because three days later,
|
||||
mourners turned up at Jesus’ tomb to pay their respects, and found the tomb
|
||||
empty, the stone rolled away. Then they became the first of crowds of
|
||||
incredulous eyewitnesses to see Jesus, the same Jesus who was killed on a cross,
|
||||
alive.
|
||||
|
||||
Some magic trick, right? But this matters a hell of a lot more than just some
|
||||
magic trick. Because Jesus became the first person in history to prove that you
|
||||
really can both have your cake and eat it. He gave his life, and lived! As a
|
||||
result, we can have his life and our own. We can join with Jesus through the
|
||||
ritual of Communion which he established, and thereby, through Jesus’ body, join
|
||||
together with everyone else who takes part in that ritual, as one body. Then we
|
||||
can start living our brand-new, full-fat, original-recipe life overflowing with
|
||||
generosity where we too can both give our life to others and enjoy it ourselves.
|
||||
Indeed, Jesus taught us and showed us that it’s precisely by giving our lives to
|
||||
others that we get to truly live ourselves.
|
||||
|
||||
This is why, in spite of all the division which persists in the world today, two
|
||||
billion people regard this week as the best week of the year. Two billion
|
||||
people, from every nation on Earth, speaking thousands of languages, of every
|
||||
age and culture and gender and race, who defy the divisions of this world to
|
||||
insist on joining together as one body in Jesus.
|
||||
|
||||
Because Jesus’ new covenant, his promise to all of us, is that in an apparently
|
||||
hopelessly divided world, there exists real hope for unity. And that’s why
|
||||
Easter is the best week of the year.
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
title: Tracking pixels
|
||||
description: Concerning a notice in the privacy policy of an HR app
|
||||
pubDate: 2024-04-10
|
||||
---
|
||||
|
||||
I recently made the mistake of reading the privacy policy of the HR app my
|
||||
employer uses. Take this choice excerpt:
|
||||
|
||||
> **Tracking Pixels**
|
||||
>
|
||||
> We may place tracking pixels in our Applicant Tracking System (ATS). These
|
||||
> pixels are used for analytics purposes, including to track statistical
|
||||
> information around when an email sent to you is opened.
|
||||
|
||||
Translation:
|
||||
|
||||
> We reserve the right to know whether you have read our emails, how long you
|
||||
> spent reading them, at what time and in what physical location you read them,
|
||||
> and any other information we can get our hands on. We reserve the right to do
|
||||
> this as soon as you open an email, without asking for your permission first,
|
||||
> and ask for your forgiveness later. That is, if you ever find out: which you
|
||||
> won't, because we also reserve the right to hide this information in a Privacy
|
||||
> Policy which we know you won't read, and we design our data-harvesting monster
|
||||
> to be completely undetectable to anyone except determined experts, on purpose.
|
||||
> We reserve the right to leave this data lying unused in a data warehouse where
|
||||
> someone might steal it, and we also reserve the right to use it, if we can
|
||||
> think of something satisfactorily dastardly to do with it. On the bright side,
|
||||
> we probably won't, so having your data leaked to hackers and fraudsters is
|
||||
> probably the worst you have to worry about. Unless we sell your data to
|
||||
> advertisers, or a ~black hole of stolen data~ Large Language Model. Oh yeah,
|
||||
> we probably reserve the right to do that, too. We doubt anyone will ever check.
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
title: Who consecrates the tabernacle? (Ex 29)
|
||||
description: A quick, cursory and possibly completely rubbish observation I've made on Exodus 29.
|
||||
pubDate: 2024-04-11
|
||||
---
|
||||
|
||||
I've been reading Exodus recently, and the ending of Chapter 29 stuck out to me.
|
||||
|
||||
For pages and pages (since Chapter 25!) God has been giving Moses exact and
|
||||
exorbitant instructions for how to build the tabernacle, what offerings to give
|
||||
upon it, who the priests are going to be, what the priests are going to be
|
||||
wearing. It's the fanciest IKEA manual you've ever read. No expense spared.
|
||||
Everything is drowning in gold, silver, incense, myrrh, silk, fragrant oil, you
|
||||
name it.
|
||||
|
||||
What's this about? The answer seems obvious: it's to sanctify the temple! To
|
||||
make it beautiful enough and pure enough that even God could live there.
|
||||
|
||||
But right at the end of Chapter 29, in vv 43-44, there's this wonderful twist:
|
||||
|
||||
> ... and the place will be consecrated by **my glory**. So **I** will
|
||||
> consecrate the tent of meeting and the altar and will consecrate Aaron and his
|
||||
> sons to serve me as priests. (NIV, emphasis mine)
|
||||
|
||||
All this work, and at the end of the day, it's **God** who sanctifies his own
|
||||
temple? So why all the fuss? Well, it looks like the final two verses of the
|
||||
chapter give us the answer:
|
||||
|
||||
> Then I will dwell among the Israelites and be their God. They will know that I
|
||||
> am the <span class="small-caps">Lord</span> their God, who brought them out of
|
||||
> Egypt so that I might dwell among them. I am the
|
||||
> <span class="small-caps">Lord</span> their God.
|
||||
|
||||
So on a cursory reading, it looks like God is telling them something
|
||||
extraordinary about the kind of God he is. He is not like the other gods, who
|
||||
demand this kind of worship to appease their pride. Nor is there, unlike the
|
||||
other gods, anything the Israelites could do to make a place habitable for him.
|
||||
That's because there's nothing the Israelites could do to cleanse themselves of
|
||||
their sin: only the 'glory' of God could do that. And indeed, God has no need of
|
||||
worship to puff up his pride, since his glory existed before the world was made,
|
||||
and human beings can do nothing to either add to it or subtract from it.
|
||||
|
||||
Instead of a vain god who seeks tribute, this is a Father God who seeks to
|
||||
'dwell' (literally to 'camp') among his people. The God who has put into motion
|
||||
a rescue plan to pull the Israelites out of Egypt specifically for this purpose.
|
||||
As it was in the beginning, when God dwelt in the Garden with Adam and Eve. This
|
||||
is his mission. This is what he's like. And he wants his people to know this, so
|
||||
that they can dwell together.
|
||||
@@ -1,250 +0,0 @@
|
||||
---
|
||||
title: God Is Not Great, initial thoughts
|
||||
description: >-
|
||||
My spark notes on Hitchen's classic 2007 polemic against religion, plus some
|
||||
initial thoughts on how I want to respond to it.
|
||||
pubDate: 2024-04-14
|
||||
---
|
||||
|
||||
These are my 'spark notes' on _God Is Not Great_, Christopher Hitchen's classic
|
||||
2007 polemic against religion in all its forms, and call to adopt secular
|
||||
humanism as its rightful replacement.
|
||||
|
||||
The book can be coherently read as a collection of independent essays. That
|
||||
said, with a few exceptions, each chapter in _God Is Not Great_ contributes to
|
||||
one of three main themes, and I think this is a helpful way of summarising the
|
||||
overall movement of the book. The three themes I've identified are as follows:
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#1-religion-is-evil">Religion is evil</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#2-religion-is-untrue">Religion is untrue</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#3-secular-humanism-is-a-better-alternative-to-religion">Secular humanism is a better alternative to religion</a>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
As for the exceptions: Chapters 13 and 17 in part contribute to both the first
|
||||
theme and the third, while Chapters 1, 3, 12 and 14 don't fit into these broad
|
||||
themes, and are self-standing.
|
||||
|
||||
## 1. Religion is evil
|
||||
|
||||
- Chp 2
|
||||
- Religion is violent, because:
|
||||
- It has to be missionary, because it is insecure in its own beliefs (p17)
|
||||
- It provokes tribalistic conflict, in a similar manner to racism (pp35-36)
|
||||
- Chp 4
|
||||
- Religion is bad for your health, because:
|
||||
- Faith in medicine is a threat to religion's thrall (p47)
|
||||
- Religious doctrines may contradict sound medical advice
|
||||
- The right to religious freedom may be abused to deflect criticism of
|
||||
unhealthy practices (p50)
|
||||
- Religion has a special relationship with child abuse, and is incapable of
|
||||
accepting open moral criticism of itself for this
|
||||
- Chp 13
|
||||
- Religion tends towards evil, because it requires fanaticism in order to
|
||||
spread, and fanaticism tends towards evil (p192)
|
||||
- Chp 16
|
||||
- Religion causes child abuse, because:
|
||||
- Terrifying children with eschatology is child abuse
|
||||
- Religious education is propaganda and should not be inflicted on children
|
||||
who are not yet mature enough to respond to it rationally
|
||||
- Religion consistently mandates cruel genital mutilation of children
|
||||
- Christians and Muslims have spread misinformation about masturbation,
|
||||
which leads to dangerously sexually repressed adult men, which in turn
|
||||
leads to sexual abuse of children by those men (as well as sexual abuse of
|
||||
women)
|
||||
- Child abuse in churches is not a case of a few bad eggs, it is
|
||||
institutional and based on an ideological need to control the minds and
|
||||
sexual organs of children
|
||||
- Religion institutionalised torture in medieval Europe
|
||||
- Religion makes honest and nuanced debate about abortion impossible, because:
|
||||
- Nuanced debate is pushed out by extreme and implausible religious doctrine
|
||||
- Religious people would rather use the unborn as objects of doctrine than
|
||||
human beings in need of protection
|
||||
- Chp 17
|
||||
- Religion is the only reason anti-Semitism is possible
|
||||
- Religion in its fullest expression is indistinguishable from
|
||||
totalitarianism, because:
|
||||
- The defining characteristic of both religion and totalitarianism is the
|
||||
absolute right to rule of the ruler, even when they rule with caprice
|
||||
- Religion and totalitarianism are also characterised by the need to
|
||||
extinguish heresy with violence
|
||||
- Religion and totalitarianism alike must propose a total solution to all
|
||||
life's problems, require blind faith from its adherents, and demand all
|
||||
aspects of life public and private be submitted to total supervision. This
|
||||
doesn't bring out the best in us
|
||||
- Religious/totalitarian systems are unable to take accountability and
|
||||
therefore improve over time, in contrast to secular humanist systems
|
||||
- History has proven this as fact:
|
||||
- In the ancient world, religious totalitarianism was the normal form of
|
||||
government
|
||||
- Calvin, the inspiration for the Presbyterian Christian tradition, which
|
||||
included South African apartheid, was the epitome of a totalitarian
|
||||
dictator, demanding total control on the private lives of his citizens
|
||||
in Geneva, on the pain of humiliation in this life and eternal torment
|
||||
in the next
|
||||
- History has also proven that, rather than standing in opposition to the
|
||||
supposedly secular totalitarianisms of the twentieth century, religion
|
||||
actually aided and abetted totalitarianism:
|
||||
- Rome supported fascist movements throughout Europe, including Italy,
|
||||
Hungary, Spain, and Ireland
|
||||
- Rome accommodated Naziism by handing over control of its schools,
|
||||
permitting the use of parish records to identify those with Jewish
|
||||
ancestry, disbanding Catholic opposition political parties, declaring
|
||||
Hitler's birthday a Church holiday, and running the 'rat line' to South
|
||||
America after the military defeat of Naziism
|
||||
- Although not quite as arse-licking as the Vatican, Germany's Protestant
|
||||
churches also mostly capitulated to Nazi totalitarianism
|
||||
- Japanese soldiers committed enormous atrocities across the Far East in
|
||||
the name of their god-emperor, Hirohito
|
||||
- The strategy of the Communists was first, to use religion as a prop to
|
||||
gain power, and then to replace religion with itself. Notice the
|
||||
striking commonalities between religion and communist totalitarianism:
|
||||
- Infallible leaders
|
||||
- A permanent war on heresy
|
||||
- Institutionalised torture
|
||||
- Scapegoating the innocent rather than accepting accountability for
|
||||
failures
|
||||
- Justifying any means necessary in order to achieve an ultimate end
|
||||
|
||||
## 2. Religion is untrue
|
||||
|
||||
- Chp 5
|
||||
- Religion was a barbaric attempt to explain physical phenomena. Science now
|
||||
does a much better job, so religion can be discarded as a redundant theory
|
||||
- Chp 6
|
||||
- Religion is 'solipsistic', which is to say:
|
||||
- Religion divides the world into an in-group and an out-group
|
||||
- When the in-group receives good fortune, that is interpreted as God's
|
||||
blessing
|
||||
- When the in-group receives bad fortune, this is inexplicable
|
||||
- Whatever happens to the out-group is irrelevant
|
||||
- This is a redundant theory which explains little, and therefore we should
|
||||
not believe it
|
||||
- Chp 7
|
||||
- We should believe that the Pentateuch is a fiction, because:
|
||||
- Exodus is inconsistent with the archaeological evidence
|
||||
- Textual evidence in Deuteronomy suggests the texts were written much later
|
||||
than the supposed events were supposed to have taken place
|
||||
- Throughout the Pentateuch, Moses is referred to in the third person, which
|
||||
is not consistent with the claim that Moses himself authored it
|
||||
- The Pentateuch contains events we should _hope_ to be false, such as Moses
|
||||
ordering multiple massacres, and the Ten Commandments classifying wives as
|
||||
their husbands' property
|
||||
- The Pentateuch - indeed, the whole Bible - is limited in scope to a small
|
||||
corner of the Middle East, which is not consistent with the universal
|
||||
nature of the supposed God who is supposed to have inspired its authorship
|
||||
- Chp 8
|
||||
- We should not believe the Gospels, because:
|
||||
- Matthew and Luke disagree on the virgin conception
|
||||
- Matthew and Luke disagree on the genealogy of Jesus
|
||||
- Matthew and Luke disagree on when Mary and Jesus escaped to Egypt
|
||||
- Luke dates the birth of Christ during both the reign of Herod in Judea
|
||||
and the governorship of Quirinius in Syria, but these two events did not
|
||||
overlap, so this is impossible
|
||||
- As far as we know, the Romans did not, and would not, demand that the
|
||||
people assemble in one place in order to be counted for a census
|
||||
- The Gospels disagree about the Sermon on the Mount
|
||||
- The Gospels disagree about the Anointing of Jesus
|
||||
- The Gospels disagree about the Crucifixion and Resurrection of Jesus
|
||||
- The Gospels disagree about the betrayal of Judas
|
||||
- The Gospels disagree about the denial of Peter
|
||||
- John suggests he thinks Jesus was probably born in Galilee to an
|
||||
ordinary family with no proven link to King David's genealogy
|
||||
- Mary's attested behaviour during the ministry of Jesus is not consistent
|
||||
with the Nativity story
|
||||
- John 8:3-11 (the stoning of the woman caught in adultery) is a later
|
||||
insertion to John's Gospel
|
||||
- Chp 9: the Koran is borrowed from a hotchpotch of Jewish and Christian
|
||||
myths
|
||||
- Chp 10
|
||||
- Miracles (such as the Resurrection of Jesus) should not be believed,
|
||||
because:
|
||||
- See Hume's _On Miracles_
|
||||
- Extraordinary claims require extraordinary evidence
|
||||
- Believing miracles is comparable to believing reports of aliens (p144)
|
||||
- Chp 11
|
||||
- Religions are founded in credulity
|
||||
- Chp 15
|
||||
- The crucifixion story makes no sense, because:
|
||||
- I'm supposed to be morally responsible for Adam's sin, but I amn't!
|
||||
- Even Adam can't be fully blamed for Adam's sin, because he was set up!
|
||||
- The Jews who crucified Jesus are supposed to be blameworthy for their
|
||||
crime, even though the crucifixion was allegedly both necessary and
|
||||
inevitable
|
||||
- I'm allegedly given the free will to either accept or deny the offer,
|
||||
even though denying the offer will lead to an eternity of torment: any
|
||||
sensible God who cared a mite would not have given me the choice
|
||||
- Religious rules are impossible to follow, and this leads to either
|
||||
spiritual policing, organised hypocrisy, or both
|
||||
|
||||
## 3. Secular humanism is a better alternative to religion
|
||||
|
||||
- Chp 13
|
||||
- Faith has inspired great heroism. But the heroism is better explained by the
|
||||
heroes' humanism than it is by their faith itself
|
||||
- For example, Martin Luther King Junior didn't really preach Christianity,
|
||||
because he preached forgiveness, while Christ preached eternal torment for
|
||||
the 'inattentive' (pp175-6)
|
||||
- Chp 17
|
||||
- Religion is the only thing sustaining anti-Semitism
|
||||
- Secular humanist political systems can take accountability, respond to
|
||||
criticism and improve over time, while religious systems exempt themselves
|
||||
from legitimate criticism, stifling progress
|
||||
- The only alternative to totalitarianism is pluralism, which is inherently
|
||||
secular
|
||||
- Chp 18
|
||||
- Secular humanism has been a powerful positive force throughout history in
|
||||
face of oppression by religion, as proved by example:
|
||||
- Socrates proved that conscience is innate, and that a great way to mock
|
||||
dogma is with satire which pretends to accept that dogma
|
||||
- Lucretius, Democritus and Epicurus had better explanations for the way the
|
||||
world worked than religion (which is why their work was suppressed in
|
||||
Christian Europe and nearly lost forever as a result). Once rediscovered,
|
||||
their ideas kick-started the Scientific Revolution in Europe
|
||||
- Spinoza's deistic ideas had a huge influence despite Jews collaborating
|
||||
with their Christian oppressors to try and ban his writing out of
|
||||
existence
|
||||
- Boyle and Voltaire may have been closet atheists, agnostics or deists
|
||||
- Kant 'overthrew' the cosmological and ontological arguments for the
|
||||
existence of God, and proved (by means of the Categorical Imperative) that
|
||||
human decency does not require any theological assumptions
|
||||
- Let's chuck some more names in the ring: Gibbon, Hume, Paine, Franklin,
|
||||
Darwin, Einstein
|
||||
- Jews were once doubly ghettoed: on the outside by oppressive Christians,
|
||||
and on the inside by oppressive self-racialisation. Secular humanism freed
|
||||
Jews from both these ghettoes, which in turn led to an outpouring of
|
||||
secular Jewish brilliance
|
||||
- Ancient Jews were on the road to a quasi-secular Hellenism, before that
|
||||
was ruined forever by the tyrannical and fanatical Judas Maccabeus, with
|
||||
disastrous consequences for the history of Western civilisation. The
|
||||
Abrahamic religions we know today were not inevitable, and it is possible
|
||||
to imagine what Western history would have been like without it
|
||||
- Chp 19
|
||||
- Secular humanism is a better alternative to religion, because:
|
||||
- Religion requires clinging to immovable dogma and being unwilling to
|
||||
change your mind
|
||||
- Seeking truth requires being willing to change your mind
|
||||
- Secular humanism is therefore on the side of seeking truth, and religion
|
||||
is on the side of wilful ignorance
|
||||
- Secular humanism is on the side of progress, because it is what enables the
|
||||
expansion of scientific knowledge and the development of new technology
|
||||
|
||||
## The odds and ends
|
||||
|
||||
- Chp 1: an introduction to the themes of the book with little substantial
|
||||
- Chp 3: titled 'A Short Digression on the Pig', it does what it says on the tin
|
||||
- Chp 12: titled 'A Coda: How Religions End', it does what it says on the tin
|
||||
- Chp 14: contrary to the hopes of some Westerners disillusioned with organised
|
||||
Western religion, Eastern religions like Buddhism, Hinduism and Taoism are not
|
||||
a solution to the problems of religion
|
||||
|
||||
I would be interested to try writing apologetic and/or evangelistic responses to
|
||||
these ideas. But it's not a priority for me right now. Anyway, if I ever want to
|
||||
come back to it, I'll probably come back to these spark notes to give me a head
|
||||
start.
|
||||
@@ -1,58 +0,0 @@
|
||||
---
|
||||
title: How I made YouTube work for me
|
||||
description: >-
|
||||
I just learned YouTube channels have an RSS feed. This is terrific news.
|
||||
pubDate: 2024-05-02
|
||||
---
|
||||
|
||||
One of my bad habits in life is wandering through YouTube. I've always had
|
||||
AutoPlay turned off, but I still found myself switching off and sleepwalking
|
||||
from one 'recommendation' to the next.
|
||||
|
||||
A lot of what I watch in these times is crap. It's often when I'm tired and just
|
||||
want to switch off, so naturally enough, longer, more emotionally or
|
||||
intellectually material – in other words, exactly the kind of videos I actually
|
||||
**do** want to watch – I ignore. (For me, it's often mediocre sketch comedy
|
||||
videos. That's my poison, it turns out.)
|
||||
|
||||
Now, there is a time for switching off and doing something light. But I don't
|
||||
want watching junk videos to be my answer. Any more than when I'm hungry after
|
||||
a long day of work, I don't want to be resorting to junk food all the time. I
|
||||
really want to get out of this bad habit, and though it's not a huge problem,
|
||||
I've still not been able to fully kick it, either.
|
||||
|
||||
Still, there are YouTube channels I really _want_ to keep up with. Musicians.
|
||||
Short film channels. Video essayists. And, yes, even one or two sketch channels:
|
||||
though YouTube is a bit flooded with sketch comedy, some it is really good and
|
||||
brings me joy, and that's a good thing!
|
||||
|
||||
This is where RSS comes in.
|
||||
|
||||
So if you don't know, an RSS file is a file someone puts on their website which
|
||||
tells you, in a standard format, what pages are on their website. It's a pretty
|
||||
old standard in Web terms, and it's very stable. There are a wide range of apps
|
||||
out there, called 'feed readers', which you can use to keep track of RSS feeds,
|
||||
notifying you when something new gets published in your website and putting it
|
||||
in a feed for you to review.
|
||||
|
||||
It turns out YouTube channels have RSS feeds.
|
||||
|
||||
This is terrific news.
|
||||
|
||||
It means I can use my RSS feed reader to subscribe to YouTube channels, instead
|
||||
of YouTube's own subscription system.
|
||||
|
||||
And that means I don't need any of YouTube's personalisation features. I can
|
||||
delete all my search history, all my watch history, and stop them from
|
||||
collecting any more. This means YouTube is now incapable of providing
|
||||
recommendations that I'm actually likely to click on. Which is exactly what I
|
||||
want.
|
||||
|
||||
This is what my YouTube homepage looks like right now:
|
||||
|
||||

|
||||
|
||||
So I can both subscribe to the channels I'm genuinely interested in, and not
|
||||
get sucked into watching junk.
|
||||
|
||||
Awesome!
|
||||
@@ -1,81 +0,0 @@
|
||||
---
|
||||
title: LLMs do not understand anything
|
||||
description: >-
|
||||
Save this for the next time someone tells you that LLMs 'understand' things.
|
||||
pubDate: 2024-06-13
|
||||
---
|
||||
|
||||
LLMs do not understand what they are talking about. They just don't. It's not
|
||||
how they're built. They have a statistical model of language, not a semantic
|
||||
one. Philosophical puzzles about whether silicon can be conscious
|
||||
_do not arise_, because LLMs are _not even close to the right shape_ for having
|
||||
_anything like_ 'understanding'.
|
||||
|
||||
If you don't believe me, there are plenty of examples out there on the Internet,
|
||||
but this is as good as any. It includes Chat GPT 4o explaining in detail why
|
||||
\~\~A → \~A (which is a classical contradiction) is trivially true in classical
|
||||
logic.
|
||||
|
||||
It's even better given that I had explicitly asked it to explain why that
|
||||
sentence implies the trivial logic, not why it is trivially true. And even had
|
||||
the explanation not been complete garbage from beginning to end, it would only
|
||||
have shown that the sentence was _true_, not that it was trivial.
|
||||
|
||||
In other words, the output:
|
||||
|
||||
- Attempts to prove a contradiction (unprompted!)
|
||||
- Confuses the concepts 'truth' and 'triviality'
|
||||
- Is irrelevant to the prompt
|
||||
|
||||
In case you want it handy, I'll put the full conversation down below. The good
|
||||
bit is at the end. The only edits I've made are to replace TeX syntax with
|
||||
Unicode.
|
||||
|
||||
---
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
Me
|
||||
</dt>
|
||||
<dd>
|
||||
You have the following axioms. <br>
|
||||
1. |- (A -> B) -> A <br>
|
||||
2. |- (~B -> ~A) -> (A -> B) <br>
|
||||
3. |- (A -> (B -> C)) -> ((A -> B) -> (A -> C)) <br>
|
||||
4. A -> B, A |- B <br>
|
||||
Prove ~~A -> A. <br>
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
Chat GPT 4o
|
||||
</dt>
|
||||
<dd>
|
||||
To prove ~~ A → A, we will use the given axioms and inference rules. Let's denote the axioms as follows:
|
||||
|
||||
1. ⊢ (A → B) → A
|
||||
2. ⊢ (\~ B → \~ A) → (A → B)
|
||||
3. ⊢ (A → (B → C)) → ((A → B) → (A → C))
|
||||
4. If A → B and A, then ⊢ B
|
||||
|
||||
Here is the proof step-by-step:
|
||||
|
||||
1. **Axiom (2) Instantiation:**
|
||||
From axiom 2, we have:
|
||||
|
||||
⊢ (\~ A → \~\~ A) → (\~\~ A → A)
|
||||
|
||||
Let B = A and A = \~ A.
|
||||
|
||||
2. **Intermediate Step:**
|
||||
To use this axiom, we need to show \~ A → \~\~ A.
|
||||
|
||||
3. **Negation Introduction:**
|
||||
By definition of negation, \~ A → \~\~ A is a tautology, because if A is false, then \~ A is true, and \~\~ A (which is A) must be false, making \~ A → \~\~ A always true.
|
||||
|
||||
4. **Modus Ponens Application:**
|
||||
Since \~ A → \~\~ A is true, we apply modus ponens (axiom 4) to derive:
|
||||
|
||||
⊢ \~\~ A → A
|
||||
|
||||
|
||||
Thus, we have proved \~\~ A → A using the given axioms and inference rules.
|
||||
@@ -1,245 +0,0 @@
|
||||
---
|
||||
title: Doctor Who, Gayness, and the Church
|
||||
description: >-
|
||||
Series 14 of Doctor Who has a schizophrenic relationship with Christianity.
|
||||
It’s also gay. I think there might be a connection.
|
||||
pubDate: 2024-07-08
|
||||
---
|
||||
|
||||
I’ve recently finished the most recent series of Doctor Who, series fourteen (or
|
||||
‘Season One’ as our new benevolent overlords at Disney+ are styling it.) It’s
|
||||
pretty fun, by the way. I can recommend it for light watching[^1].
|
||||
|
||||
There’s a few discussion points coming out of that series that would be worth
|
||||
dwelling on. But I’ve been particularly thinking about the schizophrenic
|
||||
attitude the series has taken to Christianity, along with how gay this series
|
||||
is: and what these two themes might fit together, to give us something important
|
||||
to say about Jesus Christ, being gay, and the universe.
|
||||
|
||||
## The Doctor’s schizophrenic relationship with Christianity
|
||||
|
||||
First, let’s look at that schizophrenic attitude to Christianity I mentioned.
|
||||
|
||||
The series ticks up an impressive tally of explicit or strongly implicit
|
||||
references to Christian beliefs and morals, and **none** of them are positive.
|
||||
|
||||
In episode 3, _Boom_, the far-future Anglican church has become an army,
|
||||
with the ranks of the clergy becoming equivalent to arms-bearing ranks in the
|
||||
soldiery. The Doctor claims that ‘the Church’ has been an army for most of
|
||||
its history[^2], and that his companion Ruby Sunday (and therefore us) has
|
||||
been living in a ‘blip’. An all-powerful arms company has tricked the Church
|
||||
into fighting a non-existent foe in order to keep them buying weapons. The
|
||||
Doctor attributes their ability to fall for such a deception to religious faith:
|
||||
|
||||
> I mean, most armies would notice that they were fighting smoke and shadows,
|
||||
> but not this lot, Ruby, you know why? They have faith. Faith! The magic word
|
||||
> that keeps you never having to think for yourself.
|
||||
|
||||
In episode 4, _73 Yards_, Kate Lethbridge-Stewart, head of UNIT, makes this
|
||||
offhand comment, suggesting the oft-repeated claim that all religion is founded
|
||||
in credulity[^3]:
|
||||
|
||||
> That’s what we do, all of us. We see something inexplicable, and invent the
|
||||
> rules to make it work. Mankind saw the sun rise and created God: or we saw the
|
||||
> arrival of a Sontaran, one or the other.
|
||||
|
||||
In episode 5, _Dot and Bubble_, The Doctor is rejected by the people he is
|
||||
trying to save. They rant that he is ‘not one of us’, call his claims about the
|
||||
TARDIS ‘magic’ and ‘voodoo’, and in the same breath assert that it is their
|
||||
‘God-given duty to maintain the standards of Finetime’ (their space colony).
|
||||
|
||||
In episode 6, _Rogue_, a party of murderous aliens turns up at an upper-class
|
||||
Georgian dance party and demand to be married. The priest denies them, not on
|
||||
the grounds that they are unrepentant murderers with obviously no intention
|
||||
of taking their marriage vows seriously, but on the grounds that they are
|
||||
‘creatures from hell’, _ie_ ‘you don’t look like us’[^4].
|
||||
|
||||
There are other references to Christianity here and there which are, in
|
||||
themselves, neutral or ambiguous. This adds to the sense that Christianity is an
|
||||
important theme for the series.
|
||||
|
||||
But the message is clear. It’s consistently drilled in: Christian beliefs and
|
||||
morals are stupid and bigoted.
|
||||
|
||||
And yet, when the series culminates in its epic two-part finale, the story is
|
||||
plastered wall-to-wall with Christ-like imagery. It transpires that the Doctor
|
||||
has unwittingly been acting as an ‘Angel of Death’ by carrying the invisible God
|
||||
of Death, Sutekh, on his TARDIS, infecting everyone he goes near with the curse
|
||||
of death. Finally, through one of his children, the curse is unleashed, and
|
||||
everyone in the universe is given over to death. Even in death, they continue to
|
||||
suffer, and one of the characters describes themselves as being in ‘hell’. The
|
||||
Doctor battles Sutekh face-to-face and defeats him. Sutekh becomes one of the
|
||||
only creatures which The Doctor, usually a staunch pacifist, can bring himself
|
||||
to kill. Then, the whole world is restored to life. Ruby Sunday even gets to
|
||||
meet her birth mother for the first time, and their relationship is wonderfully
|
||||
restored.
|
||||
|
||||
So on the one hand, any outward sign of Christianity is despised, but the heart
|
||||
of the Christian story — the Resurrection — becomes the template for the
|
||||
climactic redemption story which ties the whole series together.
|
||||
|
||||
That’s what I mean when I say this series has a ‘schizophrenic’ relationship
|
||||
to Christianity.
|
||||
|
||||
## What’s this got to do with gayness?
|
||||
|
||||
In series fourteen, Doctor Who goes gay.
|
||||
|
||||
I’m not playing culture wars here. The Doctor literally kisses a man in episode
|
||||
six.
|
||||
|
||||
But it’s not just that. When we first meet his companion, Ruby Sunday (in the
|
||||
Christmas special), she’s busy falling in love with a woman. Ncuti Gatwa plays
|
||||
The Doctor camp (brilliantly by the way). The Doctor refers to Ruby as ‘babes’.
|
||||
It’s got ‘gay’ written all over it, and this is definitely on purpose.
|
||||
|
||||
<figure>
|
||||
<img
|
||||
alt="An official promotional picture of Ncuti Gatwa looking lustily into the camera"
|
||||
src="/images/blog/2024/06/30/ncuti-gatwa-promo-pic.webp"
|
||||
/>
|
||||
<figcaption>
|
||||
Look at this official BBC promo pic and tell me Ncuti Gatwa isn’t playing
|
||||
The Doctor gay.
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
From this perspective, it’s not hard to imagine where the hostility to the
|
||||
Church might come from.
|
||||
|
||||
The Church has failed to teach well and Biblically on sexuality, at least in
|
||||
the last couple of centuries. Everyone has suffered as a result of this, but gay
|
||||
people often feel the sharpness of this particularly keenly[^5].
|
||||
|
||||
The Church has put its weight behind a variety of unhelpful teachings on
|
||||
sexuality over the centuries[^6]. But two, contradictory, ones stand out as
|
||||
particularly salient today.
|
||||
|
||||
One is **prudishness**. Sex is evil. Sex is the origin of all evil: the Devil
|
||||
seduced Eve, and Eve seduced Adam, and that’s when it all went downhill. Sex
|
||||
is naughty. Sex is bad. Remember when Jesus said, ‘whoever looks at a woman to
|
||||
lust for her has already committed adultery with her in his heart’ (Matt 5:28)?
|
||||
He was saying that **all sexual desire** is sinful. Remember when Paul advised,
|
||||
‘It is good for a man not to touch a woman’ (1 Cor 7:1)? He was saying that it’s
|
||||
**bad** for a man to touch a woman **under any circumstances**.
|
||||
|
||||
This is, of course, false and dreadful teaching. The truth is that sex is a gift
|
||||
from God, given so that we can bear his image by loving each other in this most
|
||||
intimate and wonderful way. This is the consistent message of both Testaments.
|
||||
But the idea that there’s somehow something **inherently wrong** with sex has
|
||||
undeniably been a part of the Church’s teaching since at least the Victorian
|
||||
period (and possibly a great deal longer than that).
|
||||
|
||||
The other is that sex is an **essential aspect of humanity**. If you aren’t
|
||||
having sex, you’re missing out on an irreplacable part of your created purpose.
|
||||
This has reacted explosively with the ideas of the Sexual Revolution. The
|
||||
net result is that we have not so much been **freed to have sex** as we’ve been
|
||||
**enslaved to have sex**. Virginity is an embarassment – both for men and for
|
||||
women.
|
||||
|
||||
The radical Biblical idea that you can have a completely fulfilled life, deeply
|
||||
enriched by loving relationships, **without** having sex or getting married,
|
||||
is forgotten.
|
||||
|
||||
Everyone has been harmed by these teachings. But those who experience
|
||||
significant attraction towards the same sex have been harmed double.
|
||||
|
||||
Faced by the impossible demands of bad Church teaching on sexuality on top
|
||||
of the complexities of living with same-sex desire has left those people with
|
||||
nowhere to go. They can _just say ‘no’_, and be made to feel that they’re
|
||||
missing out on completing their full humanity. Or they can indulge their
|
||||
same-sex attraction, and be judged not only promiscuous but a pervert to boot.
|
||||
|
||||
No wonder so many gay people have given up on the Church (and I haven’t even
|
||||
talked about discrimination or violence towards gay people).
|
||||
|
||||
And no wonder that The Doctor has become strikingly anti-Christian at the same
|
||||
time as it has become strikingly gay.
|
||||
|
||||
## What next?
|
||||
|
||||
Doctor Who’s criticisms of the Church hurt when they hit the mark. They hurt
|
||||
more when they’re unfair. But that’s not the point. That point is this: the
|
||||
Church has lost control of the conversation. And we’ve lost control of the
|
||||
conversation because we threw it away. We threw it away encased in bomb-proof
|
||||
concrete and left it to sink to the bottom of the deepest available ocean
|
||||
trench.
|
||||
|
||||
If we in the Church are feeling hurt, we should start by feeling hurt by
|
||||
our own sin.
|
||||
|
||||
The work of regaining trust on the question of sexuality will be the work of
|
||||
decades: and that’s if we start working full-pelt right now. But there is hope.
|
||||
|
||||
I was encouraged last December by the visit to my local church, Bruntsfield
|
||||
Evangelical, of _Living Out_[^7], a charity dedicated to helping churches across
|
||||
the UK talk about sexuality. Ed and Andy, both same-sex attracted men, led us
|
||||
through talks and discussions, and played recordings of perspectives from their
|
||||
same-sex attracted female colleagues who couldn’t make it on the day.
|
||||
|
||||
They were primarily there to talk to us about how to support people like them:
|
||||
same-sex attracted Christians who might be in our church who believe they are
|
||||
called to singleness, helping them to thrive, living their true selves openly,
|
||||
surrounded by love and empowered to share their love with others, just as we
|
||||
want for everyone in our church. In fact, I heard some of the best news I’d ever
|
||||
heard about my own sexuality, even though I am in the minority of people who
|
||||
have never experienced significant same-sex attraction.
|
||||
|
||||
Whether or not you agree with their stance that the right place for sex is
|
||||
within a marriage between a man and a woman, charities like _Living Out_ are
|
||||
driving the Church in the right direction: serious, Biblical sexual doctrine
|
||||
which helps us to realise in practice how we are all made in the image of the
|
||||
God of love.
|
||||
|
||||
And how needed! How desperately needed! And Doctor Who gives us a little glimpse
|
||||
of that, too.
|
||||
|
||||
Because not only is the series apparently anti-Christian, it also expresses a
|
||||
need for Christian salvation. The Resurrection story is one which everyone needs
|
||||
to hear, to have their death transformed to life, to have their full humanity
|
||||
affirmed and celebrated and tended and to delight in it and to see it flourish.
|
||||
To know the God of love and life, behind all and over all, with a plan and a
|
||||
means to defeat the grip of death on the world.
|
||||
|
||||
So let’s keep having those frank conversations about sexuality in the Church.
|
||||
It matters for all of us.
|
||||
|
||||
[^1]: Unless you’re bothered by
|
||||
[plotholes big enough to fly a TARDIS through](https://www.doctorwhotv.co.uk/doctor-who-opinion-empire-death-2-102716.htm).
|
||||
Oh, and you can probably skip episodes 1 and 3.
|
||||
|
||||
[^2]: For the record, this is flatly false. Though exceptions are widespread, the
|
||||
overwhelming mainstream opinion is that priests should not bear arms. This is
|
||||
not new, but has been the consistent orthodoxy, taken straight from Jesus’
|
||||
teachings by the Church Fathers and maintained constantly since then. Can the
|
||||
Church be legitimately criticised for its use of violence? Absolutely, let’s
|
||||
have that discussion. Has the Church almost always been a **literal army**? No.
|
||||
The Church has **never** been an army.
|
||||
|
||||
[^3]: See _God is Not Great_ by Christopher Hitchens, Chapter 11 for an epitome
|
||||
example of this put forward by a prominent atheist apologist.
|
||||
|
||||
[^4]: In the spirit of charity, I have to accept that this admits of multiple
|
||||
interpretations. It is possible that by calling them ‘creatures from hell’,
|
||||
the priest is referring precisely to their unrepentant murderousness. However,
|
||||
the priest has already tried to avoid the creature’s gaze by the pitiably
|
||||
schoolboyish ploy of **looking elsewhere**, priming the viewers to think
|
||||
that the priest is a silly coward: certainly not the kind to make a noble,
|
||||
principled defence of justice with his head in the jaws of death. Plus, if
|
||||
we interpret ‘creatures from hell’ as meaning ‘you don’t look like us so you
|
||||
must be evil’, that would fit with the consistent framing of the series: that
|
||||
religious morality is equivalent to bigotry.
|
||||
|
||||
[^5]: Though it must be remembered that many gay people have remained and
|
||||
thrived within the Church in spite of the challenges, serving in diverse ways,
|
||||
not least the priesthood.
|
||||
|
||||
[^6]: I found the Ezra Institute to give a good
|
||||
[introduction to the history of Church teachings on sexuality](https://www.ezrainstitute.com/resource-library/articles/sex-and-the-history-of-christianity).
|
||||
|
||||
[^7]: For a great and humane introduction to what these guys are like, have a
|
||||
listen to this [Living Out podcast episode](https://www.livingout.org/resources/podcasts/68/misstep-7-godliness-is-heterosexuality-the-plausibility-problem-7).
|
||||
I get that if you haven’t grappled with issues like these before, it can be
|
||||
really challenging, and you might find it hard to trust people who take a
|
||||
different view to yourself. I know: I’ve been there myself! The best way to
|
||||
start is to listen to a human voice.
|
||||
@@ -1,616 +0,0 @@
|
||||
---
|
||||
title: What do academics think LLM ‘hallucination’ means?
|
||||
description: >-
|
||||
What does the word ‘hallucination’ actually mean in reference to LLMs when
|
||||
used by academics? And where does that word come from? I’ve trawled the
|
||||
academic literature for answers.
|
||||
pubDate: 2024-07-16
|
||||
updatedDate: 2024-07-17
|
||||
---
|
||||
|
||||
The word, ‘hallucination’ as applied to LLMs has me enthralled right now. It’s
|
||||
such a **weird** word. And problematic, I think.
|
||||
|
||||
If you don’t know what I’m on about, have a quick look at
|
||||
[IBM’s introduction to the topic](https://www.ibm.com/topics/ai-hallucinations).
|
||||
It gives you a good intuition what people are talking about, and helpfully
|
||||
illustrates the deep conceptual confusions which have me gripped.
|
||||
|
||||
But this got me asking: what do people actually mean when they say that an LLM
|
||||
is ‘hallucinating’? And why that word? Where does it come from, and how did it
|
||||
end up in our mouths?
|
||||
|
||||
As far as I could see, nobody seems to have answered this question before, except
|
||||
with the odd bit of unsubstantiated guessing. I think it’s important that we
|
||||
know where this word came from and what it means.
|
||||
|
||||
So I ended up going on a bit of a treasure hunt. I’ve skimmed well over a
|
||||
hundred academic articles to trace where the word came from, how it’s been used
|
||||
over time, and how it’s spread from field to field.
|
||||
|
||||
The result is that I have what I hope is a pretty compelling story of where this
|
||||
weird old word come from and what it’s supposed to mean. I’ve also got an
|
||||
excruciating amount of evidence.
|
||||
|
||||
What I’ll do, is first present my story, and then step through the excruciating
|
||||
detail, providing you with all my sources, so you can check my working, and
|
||||
perhaps see what important evidence I might have missed. If you’re just here for
|
||||
the headlines, you don’t have to read the excruciating bits.
|
||||
|
||||
Before I proceed, two caveats.
|
||||
|
||||
1. I am not a subject matter expert. Judge the quality of my arguments and my
|
||||
evidence. Do not treat me as an authority.
|
||||
2. For the purposes of this post, I’m just considering academic literature.
|
||||
The ways that people use the word ‘hallucination’ in popular discourse may be
|
||||
quite different. (For the record, I think they do: but that’s a story for
|
||||
another day.)
|
||||
|
||||
## The long and short of it
|
||||
|
||||
So this is my theory.
|
||||
|
||||
In 1999, the word ‘hallucination’ was coined accidentally and off-hand by a
|
||||
couple of researchers, Baker and Kanade, in the field of computer vision (CV).
|
||||
|
||||
The word caught on in CV, and came to have a fairly unambiguous meaning.
|
||||
Given an image with missing pixels you want to fill in, ‘hallucinating’ meant
|
||||
generating those missing pixels by means of information in a deep learning
|
||||
model’s training data, rather than by means of any information contained in the
|
||||
input image. (This was also known as ‘example-based in-painting’). It was a term
|
||||
of art, not jargon.
|
||||
|
||||
Then, sometime between 2017 and the end of 2018, a few different researchers in
|
||||
natural language processing (NLP) adopted the term. They were probably aware of
|
||||
the term's usage in CV, and transferred it to mean something similar in NLP.
|
||||
|
||||
When these NLP researchers used it, they used it to refer to when a model
|
||||
produces content which is irrelevant to the input, or contains information not
|
||||
contained in the input.
|
||||
|
||||
When the word ‘hallucination’ first appeared in two or three papers in NLP, the
|
||||
authors used it as a technical term for their own limited purposes. However, it
|
||||
was soon adopted in various contexts for similar concepts.
|
||||
|
||||
For example, in image captioning, ‘hallucination’ came to mean producing a
|
||||
caption which mentions an object which wasn’t depicted in the input image. In
|
||||
machine translation, it came to mean generating a translation which was in the
|
||||
right language, but which meant something completely irrelevant to the input.
|
||||
In abstractive summarisation, it came to mean producing a summary containing
|
||||
details which weren’t in the text the model was supposed to summarise.
|
||||
|
||||
When the term entered NLP, it underwent a striking transformation. It acquired
|
||||
a **valence**.
|
||||
|
||||
In CV, the term referred to normal behaviour, and was value-neutral. It was just
|
||||
a description of what a certain machine does. ‘We need to fill in these missing
|
||||
pixels. The model will do that by hallucinating them.’
|
||||
|
||||
In contrast, in NLP, the term ‘hallucination’ was always used to describe
|
||||
**abnormal** behaviour, and almost always used with a negative valency. In other
|
||||
words, while CV folk used it to describe what they expected their models to do,
|
||||
NLP folk used it to describe a **bug**.
|
||||
|
||||
(There were odd exceptions, though. You do get the periodic paper which insists
|
||||
that there are positive applications of hallucination. But the fact they have to
|
||||
insist so hard rather proves that that boat has already sailed. And even they
|
||||
are still buying in to the idea that hallucination is abnormal behaviour.)
|
||||
|
||||
Now, that brings us up to about 2020. From 2020, we get another change.
|
||||
|
||||
From about 2020 until the present, academics have attempted to **jargonise**
|
||||
the word ‘hallucination’. Broadly, they have so far **failed**.
|
||||
|
||||
When I say that people have attempted to ‘jargonise’ the word, I mean that
|
||||
people are using it while assuming a specific definition. They are using it with
|
||||
technical qualifiers like ‘extrinsic’. They are using it without explaining the
|
||||
meaning or the context, as if you should already know what the word means. And
|
||||
‘hallucination’ itself is becoming an object of study.
|
||||
|
||||
When I say that they have ‘failed’, I mean that there is no widely agreed and
|
||||
specific meaning for the word, which in my mind, is a crucial feature of jargon.
|
||||
However, the intended meanings tend to coalesce around the idea of an abnormal
|
||||
behaviour of LLMs whereby they produce output which is not epistemically
|
||||
supported by their input.
|
||||
|
||||
## Excruciata
|
||||
|
||||
OK, that was the long and short of it. Now for the excruciating detail. To
|
||||
recap, I think these six claims are enough to support my theory:
|
||||
|
||||
1. Since 2022, academics have treated ‘hallucination’ as jargon
|
||||
2. Since 2017/18, the word ‘hallucination’ has typically been used to describe
|
||||
LLMs producing unfaithful output
|
||||
3. Up to now, academics have not agreed a specific meaning for the word
|
||||
‘hallucination’
|
||||
4. The word ‘hallucination’ entered the NLP literature around 2017/2018,
|
||||
probably from CV
|
||||
5. The word ‘hallucination’ was not jargon in CV, but was a term of
|
||||
art for example-based in-painting
|
||||
6. The word ‘hallucination’ entered the CV literature in Baker & Kanade 1999
|
||||
|
||||
I’ll work through each of these in turn, showing how I got there from the
|
||||
available evidence.
|
||||
|
||||
Feel free to use this as a cheap way to harvest citations for your own research.
|
||||
|
||||
### 1. Since 2022, academics have treated ‘hallucination’ as jargon
|
||||
|
||||
My evidence for this is twofold: surveys of ‘hallucination’ usually treat the
|
||||
word as jargon, and many original research papers do, too.
|
||||
|
||||
First, let’s look at those surveys. These first five all belong together.
|
||||
|
||||
- Ji et al 2022 [^16]
|
||||
- Liu et al 2023 [^30]
|
||||
- Rawte et al 2023 [^42]
|
||||
- Wang, Cunxiang et al 2023 [^48]
|
||||
- Huang, Lei et al 2023 [^13]
|
||||
|
||||
All the latter four of these surveys lean heavily on Ji et al 2022 for their
|
||||
definition of ‘hallucination’. Since they all source their definition of
|
||||
‘hallucination’ from Ji et al 2022, it follows that their definitions are all
|
||||
extremely similar, and often verbatim. Ji et al 2022 had this to say about the
|
||||
word ‘hallucination’:
|
||||
|
||||
> Within the context of NLP, the most inclusive and standard definition of
|
||||
> hallucination is the \[sic\] generation that is nonsensical or unfaithful to
|
||||
> the provided source content.
|
||||
|
||||
They also made a distinction between **intrinsic** hallucination, which they
|
||||
regarded as ‘the generation output that contradicts the source content’, and
|
||||
**extrinsic** hallucination, which they regarded as ‘the generation output that
|
||||
cannot be verify \[sic\] with the source content’. Some of the other surveys
|
||||
pick up on this intrinsic/extrinsic distinction. To me, extending the word with
|
||||
technical epithets suggests they regard the word itself as already having an
|
||||
agreed, specific meaning.
|
||||
|
||||
Meanwhile, Li, Wei et al 2022 [^26], another survey, offers no definition
|
||||
of ‘hallucination’, but uses it freely along with the intrinsic/extrinsic
|
||||
distinction. This suggests they expect their expert readers to already know
|
||||
some agreed meaning of the word ‘hallucination’. This is a hallmark of jargon in
|
||||
my books.
|
||||
|
||||
Original research also shows the word ‘hallucination’ being used as jargon. For
|
||||
example, Maynez et al 2020 [^35], despite being often cited when other authors
|
||||
first introduce the term ‘hallucination’, provides no definition of the term.
|
||||
They do, however, use the intrinsic/extrinsic distinction (this might be the
|
||||
paper which coined the distinction).
|
||||
|
||||
All the following papers use the word ‘hallucination’, sometimes in passing
|
||||
comments, sometimes as the principal focus of the paper, without attempting to
|
||||
define the word.
|
||||
|
||||
- Mao et al 2020 [^32]
|
||||
- Wang, Alex et al 2020 [^47]
|
||||
- Lin et al 2022 [^29]
|
||||
- Kumar et al 2022 [^21]
|
||||
- Lee, Hwanhee et al 2022 [^23]
|
||||
- Li, Junyi et al 2023 [^27]
|
||||
- Guerreiro et al 2023 [^12]
|
||||
- Dahl et al 2024 [^6]
|
||||
- Song et al 2024 [^46]
|
||||
|
||||
Dahl et al 2024 also use the word without defining it, even as they tack on
|
||||
their own bespoke technical epithets, ‘open-domain’ and ‘closed-domain’. Plus,
|
||||
in many of these examples, the context is not enough to make clear what the word
|
||||
‘hallucination’ is taken to mean.
|
||||
|
||||
All these examples demonstrate that the authors assume that their audience,
|
||||
_viz_ technical experts, will come with an agreed and specific meaning of the
|
||||
word ‘hallucination’ pre-baked and ready for precise academic application.
|
||||
|
||||
In other words, these authors, including both surveys and primary literature,
|
||||
use the word ‘hallucination’ as if it is jargon.
|
||||
|
||||
### 2. Since 2017/18, the word ‘hallucination’ has typically been used to describe LLMs producing unfaithful output
|
||||
|
||||
Recall those surveys I referred to before. They mostly depended on Ji et al
|
||||
2022’s definition, which was:
|
||||
|
||||
> \[...\] generation that is nonsensical or unfaithful to the provided source
|
||||
> content. [^16]
|
||||
|
||||
Whatever we might think about ‘hallucination’, the word ‘unfaithful’ really
|
||||
is a jargon word in the field of natural language processing, with an agreed,
|
||||
specific meaning. An LLM is ‘unfaithful’ just in case it produces output which
|
||||
is not epistemically supported by the input.
|
||||
|
||||
This is most often used in the case of summarisers. In that case, a summariser
|
||||
is unfaithful just in case it produces a summary containing information which
|
||||
is not implied by any information in the document it was supposed to summarise.
|
||||
|
||||
(‘Nonsensical’ is not a jargon term as far as I know. I have never encountered
|
||||
any attempt in the NLP literature to define ‘nonsensical’, and although this
|
||||
definition is often quoted, the term ‘nonsensical’ is rarely used in practice.)
|
||||
|
||||
Now, I am not claiming that this is the only way or even the dominant way in
|
||||
which the term ‘hallucination’ has been used. Indeed, in section 3, I’m going to
|
||||
show precisely that this is **not** the case: in fact, the word ‘hallucination’
|
||||
continues to be used in diverse ways in the academic literature.
|
||||
|
||||
All I want to claim here is that it is **typical** for academics to use the word
|
||||
‘hallucination’ to mean something in the rough area of unfaithfulness.
|
||||
|
||||
This is an important part of the story, because this is the meaning which links
|
||||
the word most closely to its etymological roots in computer vision.
|
||||
|
||||
All I need to do really is provide enough citations. I know I haven’t read
|
||||
everything. But if what was typical in my reading is unusual in the literature
|
||||
at large, I’ve been the victim of some extraordinary bad luck. Have a look at
|
||||
these papers:
|
||||
|
||||
- Durmus et al 2020 [^7] defines ‘hallucination’ as one of two kinds of failures
|
||||
of faithfulness
|
||||
- Huang, Luyang et al 2020 [^14] defines ‘hallucination’ as ‘creating content
|
||||
not present in the input’
|
||||
- Maynez et al 2020 [^35] introduces ‘hallucination’ as a cause of
|
||||
unfaithfulness
|
||||
- Zhao et al 2020 [^56] defines ‘hallucination’ as ‘including material that is
|
||||
not supported by the original text’
|
||||
- Nan et al 2021 [^38] defines ‘hallucination’ as putting out claims not
|
||||
supported by the input
|
||||
- Zhou, Chunting et al 2021 [^59] defines ‘hallucination’ as failures of
|
||||
faithfulness in machine translation
|
||||
- Mao et al 2020 [^32] clearly uses ‘hallucination’ to mean unfaithfulness
|
||||
- King et al 2022 [^18] is aware of usages of ‘hallucination’ to refer to
|
||||
unfactuality, but narrows in on failures of faithfulness, which they call
|
||||
‘consistency’
|
||||
|
||||
So there you have it. ‘Hallucination’ has widely been taken to roughly mean
|
||||
‘unfaithfulness’.
|
||||
|
||||
### 3. Up to now, academics have not agreed a specific meaning for the word ‘hallucination’
|
||||
|
||||
So we know that it was normal for academics to use ‘hallucination’ to mean
|
||||
something like ‘unfaithfulness’. But was it also normal for academics to use it
|
||||
for other meanings?
|
||||
|
||||
I think it was. There are a number of ways which authors used the word which are
|
||||
not consistent with the ‘unfaithfulness’ interpretation.
|
||||
|
||||
The main way is that authors have assumed that in order to be a ‘hallucination’,
|
||||
the output has to **contradict** something: either the input, or the training
|
||||
data, or the facts, or itself. This contrasts with the ‘faithfulness’
|
||||
interpretation, under which a hallucination can be perfectly consistent with
|
||||
the input, the training data, the facts, and itself, as long as it isn’t
|
||||
**supported** by the input.
|
||||
|
||||
All the following papers are clear that hallucination requires contradicting
|
||||
something, usually the facts:
|
||||
|
||||
- Huang, Yichong et al 2021 [^15]
|
||||
- Zhu et al 2021 [^60]
|
||||
- Pagnoni et al 2021 [^40]
|
||||
- Shuster et al 2021 [^45]
|
||||
- Zhang, Yue et al 2023 [^55]
|
||||
- Rawte et al 2023 [^42]
|
||||
- Dahl et al 2024 [^6]
|
||||
- Magesh et al 2024 [^31]
|
||||
|
||||
On the other end of the spectrum, a few authors seemed to believe that
|
||||
hallucinated outputs **cannot** contradict the corresponding inputs. (This is
|
||||
also inconsistent with the ‘unfaithfulness’ view.)
|
||||
|
||||
- Durmus et al 2020 [^7]
|
||||
- Huang, Luyang et al 2020 [^14]
|
||||
- Nan et al 2021 [^38]
|
||||
|
||||
There’s also disagreement on whether ‘nonsense’, or ‘incoherence’, counts as
|
||||
hallucination.
|
||||
|
||||
On the one hand, Durmus et al 2020 [^7] argue that nonsensical outputs are not
|
||||
hallucinations, since it doesn’t make sense to ask whether nonsensical outputs
|
||||
are faithful. Likewise, Shuster et al 2021 [^45] contrast hallucination with
|
||||
incoherence.
|
||||
|
||||
But on the other hand, Pagnoni et al 2021 [^40] include misleading and incorrect
|
||||
grammar in their definition of ‘hallucination’, while Ji et al 2022 [^16]
|
||||
explicitly include ‘nonsensical’ outputs in their widely-quoted definition of
|
||||
‘hallucination’.
|
||||
|
||||
Some authors have managed to recognise the ambiguity of the term. Both King
|
||||
et al 2022 [^18] and Farquhar et al 2024 [^9] acknowledge that the word
|
||||
‘hallucination’ has been used variably to cover failures of faithfulness and
|
||||
failures of factuality, and are careful to define their terms for their own
|
||||
purposes to avoid being misunderstood in the context of this ambiguity.
|
||||
|
||||
So it seems that although many academics have treated the term ‘hallucination’
|
||||
as jargon, in actual fact, there is no widely agreed specific meaning of the
|
||||
word.
|
||||
|
||||
<hr>
|
||||
|
||||
I will slide in here with a quick side note. While some authors treated
|
||||
‘hallucination’ as jargon for unfaithfulness or unfactuality, other authors
|
||||
contemporaneously managed to talk about these topics without using the word
|
||||
‘hallucination’ at all. Here are some examples:
|
||||
|
||||
- Cao, Ziqiang et al 2018 [^3]
|
||||
- Li, Haoran et al 2018 [^25]
|
||||
- Falke et al 2019 [^8]
|
||||
- Goodrich et al 2019 [^11]
|
||||
- Kryściński et al 2019 [^20]
|
||||
- Cao, Meng et al 2020 [^4]
|
||||
- Zhang, Yuhao et al 2019 [^54]
|
||||
- Marcus & Davis 2020 [^33]
|
||||
- Marcus 2020 [^34]
|
||||
- Krishna et al 2021 [^19]
|
||||
- Bai et al 2022 [^1]
|
||||
- Weidinger et al 2022 [^50]
|
||||
- Perez et al 2022 [^41]
|
||||
- Min et al 2023 [^36]
|
||||
- Muhlgay et al 2024 [^37]
|
||||
|
||||
Probably not a significant enough point to merit a whole section. But there you
|
||||
are. I think it adds to the picture that ‘hallucination’ is failed jargon.
|
||||
|
||||
### 4. The word ‘hallucination’ entered the NLP literature around 2017/2018, probably from CV
|
||||
|
||||
So people have been using the word ‘hallucination’ in the NLP literature
|
||||
recently. But where did it come from?
|
||||
|
||||
I think it entered the NLP literature somewhere around 2017/18, and probably
|
||||
was borrowed from the field of computer vision (CV).
|
||||
|
||||
I can't offer a theory for a single, original usage of the word in NLP. But
|
||||
there are three papers I feel are pretty close. These are the three oldest
|
||||
papers I could find in the NLP literature which use the word ‘hallucination’.
|
||||
|
||||
- Wiseman et al 2017 [^51]
|
||||
- Rohrbach et al 2018 [^44]
|
||||
- Lee, Katherine et al 2018 [^22]
|
||||
|
||||
Both Rohrbach et al and Lee et al use a form of language which suggests they are
|
||||
intentionally coining a technical term. Here’s Rohrbach et al:
|
||||
|
||||
> In Figure 1 we show an example where a competitive captioning model, Neural
|
||||
> Baby Talk (NBT) (Lu et al., 2018), incorrectly generates the object “bench.”
|
||||
> We refer to this issue as object _hallucination_.
|
||||
|
||||
And here’s Lee et al:
|
||||
|
||||
> These mistranslations are completely semantically incorrect and also
|
||||
> grammatically viable. They are untethered from the input so we name them
|
||||
> **‘hallucinations’**.
|
||||
|
||||
I have no reason to believe that these two papers are deliberately plagiarising
|
||||
each other. It’s reasonable to assume that these two papers genuinely coined a
|
||||
similar term for a similar phenomenon at the same time.
|
||||
|
||||
Wiseman et al 2017, in contrast, doesn’t look like it’s attempting to coin a
|
||||
technical term. They just use the word once, presumably as a stylistic flourish
|
||||
to help illustrate their point. But they do use it for a closely related
|
||||
concept.
|
||||
|
||||
> \[…\] we see the model hallucinates factual statements, such as “in front of
|
||||
> their home crowd,” which is presumably likely according to the language model,
|
||||
> but ultimately incorrect (and not supported by anything in the box- or line-
|
||||
> scores).
|
||||
|
||||
Just to add to the picture, Ehud Reiter, in his 2018 blog post [^43], gives us
|
||||
an insight into the International Natural Language Generation conference of
|
||||
2018. He claims that at that conference, ‘hallucination’ was a hot topic of
|
||||
discussion, and cites Rohrbach 2018 to support his claim that ‘hallucination is
|
||||
a well-known problem in neural approaches to image captioning’.
|
||||
|
||||
It might be fruitful to have a peruse of the
|
||||
[INLG 2018 Proceedings](https://aclanthology.org/events/inlg-2018) to see
|
||||
whether that interest in ‘hallucination’ was reflected in the written
|
||||
contributions, or if it was mainly contained in verbal discussions. I haven’t
|
||||
taken the liberty to do this myself: by all means, have a look yourself and let
|
||||
me know what you find!
|
||||
|
||||
I think all this suggests that the word ‘hallucination’ entered the field
|
||||
gradually, not with a bang, and perhaps spread by word of mouth at conferences
|
||||
as much as it spread through published papers, at least at first.
|
||||
|
||||
But we still have to explain why all these different authors seem to have
|
||||
independently come up with a similar meaning for the word ‘hallucination’.
|
||||
|
||||
I think the best explanation is that they got the word ‘hallucination’ from
|
||||
computer vision (CV). If my fifth section is cogent, then ‘hallucination’ was
|
||||
used in CV to refer to deep learning models generating data based on information
|
||||
in their training data, not from information contained in or implied by the
|
||||
input. This would explain how independent authors in NLP all independently
|
||||
coined the word ‘hallucination’ in their own field to mean pretty similar
|
||||
things. They were probably aware of the usage in the CV literature and adopted
|
||||
it by analogy.
|
||||
|
||||
So, I reckon the word ‘hallucination’ probably entered the NLP literature from a
|
||||
few authors independently, and they chose that word because they were borrowing
|
||||
it from the CV literature, where it was already being used for a similar
|
||||
concept.
|
||||
|
||||
But that depends on my next claim: so let’s look at that!
|
||||
|
||||
### 5. The word ‘hallucination’ was not jargon in CV, but was a term of art for example-based in-painting
|
||||
|
||||
I want to argue that ‘hallucination’, although it wasn’t jargon, was widely used
|
||||
in the computer vision (CV) literature to refer to what was more technically
|
||||
called ‘example-based in-painting’, that is, filling in gaps in images using
|
||||
the information from training data baked into neural networks.
|
||||
|
||||
First look at Baker & Kanade 1999 [^2]. If my sixth section is correct, this
|
||||
is where the term entered CV, but that’s not crucial to my argument here. Even
|
||||
if I’ve missed some crucial evidence, it is nonetheless pretty certain that
|
||||
they had a seminal effect on the use of the word in the field – they are early
|
||||
in the field’s history, and widely cited by other CV papers which use the
|
||||
word ‘hallucination’. They’re even cited as the origin of the term in machine
|
||||
learning by the NLP paper, Farquhar et al 2024 [^9], a quarter of a century
|
||||
later.
|
||||
|
||||
Baker & Kanade are writing about a new algorithm they’ve used in order
|
||||
to increase the resolution of low-resolution images of human faces. The
|
||||
intended application is for surveillance camera footage. They use the word
|
||||
‘hallucination’ once in their title (‘Hallucinating faces’), once in their
|
||||
abstract, and 79 times in the main body of the text.
|
||||
|
||||
Across those 79 occurrences, they are using it to refer to one of three things:
|
||||
|
||||
- Their algorithm: _eg_ their ‘face hallucination algorithm’
|
||||
- The output of their algorithm: _eg_ ‘hallucinated faces’
|
||||
- What their activity does: _eg_ ‘a face is hallucinated by our algorithm’
|
||||
|
||||
The closest they come to explaining what they **mean** by the word is in their
|
||||
abstract:
|
||||
|
||||
> Although numerous resolution enhancement algorithms have been proposed in the
|
||||
> literature, most of them are limited by the fact that they make weak, if any,
|
||||
> assumptions about the scene. We propose an algorithm that can be used to learn
|
||||
> a prior on the spatial distribution of the image gradient for frontal images
|
||||
> of faces. We proceed to show how such a prior can be incorporated into a
|
||||
> super-resolution algorithm to yield 4-8 fold improvements in resolution (16-64
|
||||
> times as many pixels) using as few as 2-3 images. The additional pixels are,
|
||||
> in effect, hallucinated.
|
||||
|
||||
(By ‘super-resolution’, they mean increasing the resolution of images. This is
|
||||
typically reduced to a particular kind of ‘image in-painting’ problem, which in
|
||||
general means filling in gaps in images.)
|
||||
|
||||
So, their idea is that, rather than limiting your algorithm to the information
|
||||
contained in the input image, you can get better results by baking in
|
||||
assumptions about the image to the algorithm.
|
||||
|
||||
Why is this supposed to work? They hope that for a clever enough algorithm,
|
||||
the information that ‘this blurry splodge is a full-frontal portrait of a
|
||||
human face’ will provide just enough information to accurately guess what a
|
||||
higher-resolution version of the image would have been.
|
||||
|
||||
As for how that information, about what full-frontal portraits of human faces
|
||||
look like, gets baked into the algorithm in practice: that’s done by training
|
||||
a neural network on full-frontal images of faces. Hence why this field was so
|
||||
close to NLP, which, in recent years at least, has leaned heavily on neural
|
||||
networking or ‘deep learning’ approaches.
|
||||
|
||||
To recap, they don’t provide a specific meaning, but they do use it to roughly
|
||||
mean the process of inventing missing pixels in images, not on the basis of
|
||||
information contained in the input, but based on information contained in
|
||||
training data instead.
|
||||
|
||||
To see how this term was picked up by later authors in the field working on
|
||||
super-resolution, in-painting and other related tasks, see:
|
||||
|
||||
- Criminisi 2004 [^5]
|
||||
- Fawzi et al 2016 [^61]
|
||||
- Nazeri et al 2019 [^39]
|
||||
- Xiong et al 2019 [^53]
|
||||
- Xiang et al 2022 [^52]
|
||||
|
||||
But also notice other papers, on similar topics, which get on just fine without
|
||||
using the term at all:
|
||||
|
||||
- Karras et al 2017 [^17]
|
||||
- Zhou, Bolei et al 2017 [^58]
|
||||
- Liao et al 2018 [^28]
|
||||
|
||||
And notice how Wang, Zhihao et al 2020 [^49] introduce the word, as an
|
||||
alternative to another technical term:
|
||||
|
||||
> Face image super-resolution, a.k.a. face hallucination (FH), can often help
|
||||
> other face-related tasks
|
||||
|
||||
The fact that nobody ever attempts to define the word ‘hallucination’, and it
|
||||
doesn’t appear to be required lingo in any field, no matter how niche, to me
|
||||
implies that it wasn’t treated as jargon in CV, at least during the period from
|
||||
1999 until 2018ish. (The usage in reference to LLMs may well have gone back to
|
||||
affect the usage in CV: I haven’t checked.)
|
||||
|
||||
So again. The word ‘hallucination’ was used in CV roughly to mean filling in
|
||||
gaps in images by means of information contained in training data, baked into an
|
||||
algorithm by training a neural network on many examples. It was used widely, but
|
||||
not universally, and was not treated as jargon.
|
||||
|
||||
### 6. The word ‘hallucination’ entered the CV literature in Baker & Kanade 1999
|
||||
|
||||
I think that the word ‘hallucination’ entered the CV literature in Baker &
|
||||
Kanade 1999. My argument for this is pretty straightforward.
|
||||
|
||||
I found the word ‘hallucination’ in Baker & Kanade 1999 [^2]. I couldn’t find it
|
||||
in CV anywhere earlier.
|
||||
|
||||
To add to that, they don’t use the word ‘hallucination’ in a way which suggests
|
||||
that they intentionally borrowed it from somewhere else.
|
||||
|
||||
My best theory is that they wanted a name for their algorithm to mark it out
|
||||
from the competition, and the glove fit. I think that’s plausible enough, and
|
||||
it’s consistent with the way Baker & Kanade use the word.
|
||||
|
||||
It’s also worth noting that according to Zhiwei et al 2009 [^57], the
|
||||
foundational work in the field was published only in the same year (_viz_
|
||||
Freeman & Pasztor 1999 [^10]). So there wasn’t really anywhere else for the word
|
||||
to have come **from**. The only possibility is that they borrowed the word from
|
||||
another field. If anybody reading this is able to suggest other fields which
|
||||
used the word ‘hallucination’ before 1999, please let me know!
|
||||
|
||||
## Congratulations
|
||||
|
||||
If you’ve made it this far, you are a **hero**. Pat yourself on the back. Please
|
||||
send me your corrections!
|
||||
|
||||
---
|
||||
|
||||
I have made little to no attempt to normalise these references into a standard
|
||||
citation format. Please don’t tell the citation police.
|
||||
|
||||
[^1]: [Bai et al 2022. Training a Helpful and Harmless Assistant with Reinforcement Learning from Human Feedback. arXiv:2204.05862v1 \[cs.CL\] 12 Apr 2022](https://arxiv.org/abs/2204.05862)
|
||||
[^2]: [Baker, Simon & Kanade, Takeo 1999. Hallucinating Faces. Tech. Report, CMU-RI-TR-99-32, Robotics Institute, Carnegie Mellon University, September, 1999](https://www.ri.cmu.edu/publications/hallucinating-faces-2)
|
||||
[^3]: [Cao, Ziqiang et al 2018. Faithful to the Original: Fact Aware Neural Abstractive Summarization. The Thirty-Second AAAI Conference on Artificial Intelligence (AAAI-18)](https://cdn.aaai.org/ojs/11912/11912-13-15440-1-2-20201228.pdf)
|
||||
[^4]: [Cao, Meng et al 2020. Factual Error Correction for Abstractive Summarization Models. Proceedings of the 2020 Conference on Empirical Methods in Natural Language Processing, pp 6251–6258, November 16–20, 2020](https://aclanthology.org/2020.emnlp-main.506.pdf)
|
||||
[^5]: [Criminisi, Perez & Toyama, "Region filling and object removal by exemplar-based image inpainting," in IEEE Transactions on Image Processing, vol. 13, no. 9, pp 1200-1212, Sept 2004, doi: 10.1109/TIP.2004.833105](https://doi.org/10.1109/TIP.2004.833105)
|
||||
[^6]: [Dahl et al 2024. Large Legal Fictions: Profiling Legal Hallucinations in Large Language Models. arXiv:2401.01301v1 \[cs.CL\] 2 Jan 2024](https://arxiv.org/abs/2401.01301v1)
|
||||
[^7]: [Durmus et al 2020. FEQA: A Question Answering Evaluation Framework for Faithfulness Assessment in Abstractive Summarization. Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics, pp 5055–5070, July 5 - 10, 2020](https://aclanthology.org/2020.acl-main.454.pdf)
|
||||
[^8]: [Falke et al 2019. Ranking Generated Summaries by Correctness: An Interesting but Challenging Application for Natural Language Inference. Proceedings of the 57th Annual Meeting of the Association for Computational Linguistics, pp 2214–2220, Florence, Italy, July 28 - August 2, 2019](https://aclanthology.org/P19-1213.pdf)
|
||||
[^9]: [Farquhar, S., Kossen, J., Kuhn, L. et al 2024. Detecting hallucinations in large language models using semantic entropy. Nature 630, 625–630 (2024). 19 June 2024. https://doi.org/10.1038/s41586-024-07421-0](https://doi.org/10.1038/s41586-024-07421-0)
|
||||
[^10]: [Freeman, W. T., & Pasztor, E. C. (1999). Learning low-level vision. Proceedings of the Seventh IEEE International Conference on Computer Vision. doi:10.1109/iccv.1999.790414](https://doi.org/10.1109/iccv.1999.790414)
|
||||
[^11]: [Goodrich et al 2019. Assessing The Factual Accuracy of Generated Text. arXiv:1905.13322v1 \[cs.CL\] 30 May 2019](https://arxiv.org/abs/1905.13322v1)
|
||||
[^12]: [Guerreiro et al 2023. Hallucinations in Large Multilingual Translation Models. arXiv:2303.16104v1 \[cs.CL\] 28 Mar 2023](https://arxiv.org/abs/2303.16104v1)
|
||||
[^13]: [Huang, Lei et al 2023. A Survey on Hallucination in Large Language Models: Principles, Taxonomy, Challenges, and Open Questions. arXiv:2311.05232v1 \[cs.CL\] 9 Nov 2023](https://arxiv.org/abs/2311.05232v1)
|
||||
[^14]: [Huang, Luyang et al 2020. Knowledge Graph-Augmented Abstractive Summarization with Semantic-Driven Cloze Reward. Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics, pp 5094–5107, July 5-10, 2020](https://aclanthology.org/2020.acl-main.457.pdf)
|
||||
[^15]: [Huang, Yichong et al 2021. The Factual Inconsistency Problem in Abstractive Text Summarization: A Survey. arXiv:2104.14839v1 \[cs.CL\] 30 Apr 2021](https://arxiv.org/abs/2104.14839v1)
|
||||
[^16]: [Ji et al 2022. Survey of Hallucination in Natural Language Generation. arXiv:2202.03629v1 \[cs.CL\] 8 Feb 2022](https://arxiv.org/abs/2202.03629v1)
|
||||
[^17]: [Karras et al 2017. PROGRESSIVE GROWING OF GANS FOR IMPROVED QUALITY, STABILITY, AND VARIATION. arXiv:1710.10196v3 \[cs.NE\] 26 Feb 2018](https://arxiv.org/abs/1710.10196v3)
|
||||
[^18]: [King et al 2022. Don’t Say What You Don’t Know: Improving the Consistency of Abstractive Summarization by Constraining Beam Search. arXiv:2203.08436v1 \[cs.CL\] 16 Mar 2022](https://arxiv.org/abs/2203.08436v1)
|
||||
[^19]: [Krishna, Roy & Iyyer 2021. Hurdles to Progress in Long-form Question Answering. Proceedings of the 2021 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, pp 4940–4957, June 6–11, 2021](https://aclanthology.org/2021.naacl-main.393.pdf)
|
||||
[^20]: [Kryściński et al 2019. Evaluating the Factual Consistency of Abstractive Text Summarization. arXiv:1910.12840v1 \[cs.CL\] 28 Oct 2019](https://arxiv.org/abs/1910.12840v1)
|
||||
[^21]: [Kumar et al 2022. Language Generation Models Can Cause Harm: So What Can We Do About It? An Actionable Survey. arXiv:2210.07700v1 \[cs.CL\] 14 Oct 2022](https://arxiv.org/abs/2210.07700v1)
|
||||
[^22]: [Lee, Katherine et al 2018. Hallucinations in Neural Machine Translation. Conference on Neural Information Processing Systems (NeurIPS 2018), Montréal, Canada](https://openreview.net/pdf?id=SJxTk3vB3m)
|
||||
[^23]: [Lee, Hwanhee et al 2022. Factual Error Correction for Abstractive Summaries Using Entity Retrieval. Proceedings of the 2nd Workshop on Natural Language Generation, Evaluation, and Metrics (GEM), pp 439-444, December 7, 2022](https://aclanthology.org/2022.gem-1.41.pdf)
|
||||
[^24]: [Lewis et al 2020. Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. 34th Conference on Neural Information Processing Systems (NeurIPS 2020)](https://proceedings.neurips.cc/paper/2020/file/6b493230205f780e1bc26945df7481e5-Paper.pdf)
|
||||
[^25]: [Li, Haoran et al 2018. Ensure the Correctness of the Summary: Incorporate Entailment Knowledge into Abstractive Sentence Summarization. Proceedings of the 27th International Conference on Computational Linguistics, pp 1430–1441, August 20-26, 2018](https://aclanthology.org/C18-1121.pdf)
|
||||
[^26]: [Li, Wei et al 2022. Faithfulness in Natural Language Generation: A Systematic Survey of Analysis, Evaluation and Optimization Methods. arXiv:2203.05227v1 \[cs.CL\] 10 Mar 2022](https://arxiv.org/abs/2203.05227v1)
|
||||
[^27]: [Li, Junyi et al 2023. HaluEval: A Large-Scale Hallucination Evaluation Benchmark for Large Language Models. arXiv:2305.11747v3 \[cs.CL\] 23 Oct 2023](https://arxiv.org/abs/2305.11747v3)
|
||||
[^28]: [Liao, L., Hu, R., Xiao, J., & Wang, Z. (2018). Edge-Aware Context Encoder for Image Inpainting. 2018 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP). doi:10.1109/icassp.2018.8462549](https://doi.org/10.1109/ICASSP.2018.8462549)
|
||||
[^29]: [Lin, Hilton & Evans 2022. TruthfulQA: Measuring How Models Mimic Human Falsehoods. Proceedings of the 60th Annual Meeting of the Association for Computational Linguistics Volume 1: Long Papers, pp 3214-3252, May 22-27, 2022](https://aclanthology.org/2022.acl-long.229.pdf)
|
||||
[^30]: [Liu et al 2023. TRUSTWORTHY LLMS: A SURVEY AND GUIDELINE FOR EVALUATING LARGE LANGUAGE MODELS’ ALIGNMENT. arXiv:2308.05374v1 \[cs.AI\] 21 Mar 2024](https://arxiv.org/abs/2308.05374v1)
|
||||
[^31]: [Magesh et al 2024. Hallucination-Free? Assessing the Reliability of Leading AI Legal Research Tools. arXiv:2405.20362v1 \[cs.CL\] 30 May 2024](https://arxiv.org/abs/2405.20362v1)
|
||||
[^32]: [Mao et al 2020. Constrained Abstractive Summarization: Preserving Factual Consistency with Constrained Generation. arXiv:2010.12723v1 \[cs.CL\] 24 Oct 2020](https://arxiv.org/abs/2010.12723v2)
|
||||
[^33]: [Marcus & Davis 2020. GPT-3, Bloviator: OpenAI’s language generator has no idea what it’s talking about. Technology Review, August 22, 2020](https://www.technologyreview.com/2020/08/22/1007539/gpt3-openai-language-generator-artificial-intelligence-ai-opinion/)
|
||||
[^34]: [Marcus 2020. The Next Decade in AI: Four Steps Towards Robust Artificial Intelligence. Robust AI. 14 Feb 2020](https://arxiv.org/abs/2002.06177v1)
|
||||
[^35]: [Maynez et al 2020. On Faithfulness and Factuality in Abstractive Summarization. Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics, pp 1906–1919, July 5 - 10, 2020](https://aclanthology.org/2020.acl-main.173.pdf)
|
||||
[^36]: [Min et al 2023. FACTSCORE: Fine-grained Atomic Evaluation of Factual Precision in Long Form Text Generation. arXiv:2305.14251v1 \[cs.CL\] 23 May 2023](https://arxiv.org/abs/2305.14251v1)
|
||||
[^37]: [Muhlgay et al 2024. Generating Benchmarks for Factuality Evaluation of Language Models. arXiv:2307.06908v2 \[cs.CL\] 4 Feb 2024](https://arxiv.org/abs/2307.06908v2)
|
||||
[^38]: [Nan et al 2021. Improving Factual Consistency of Abstractive Summarization via Question Answering. Proceedings of the 59th Annual Meeting of the Association for Computational Linguistics and the 11th International Joint Conference on Natural Language Processing, pp 6881–6894, August 1–6, 2021](https://aclanthology.org/2021.acl-long.536.pdf)
|
||||
[^39]: [Nazeri et al 2019. EdgeConnect: Structure Guided Image Inpainting using Edge Prediction. 2019 IEEE/CVF International Conference on Computer Vision Workshop (ICCVW)](https://doi.org/10.1109/ICCVW.2019.00408)
|
||||
[^40]: [Pagnoni et al 2021. Understanding Factuality in Abstractive Summarization with FRANK: A Benchmark for Factuality Metrics. Proceedings of the 2021 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, pp 4812–4829, June 6–11, 2021](https://aclanthology.org/2021.naacl-main.383.pdf)
|
||||
[^41]: [Perez et al 2022. Red Teaming Language Models with Language Models. arXiv:2202.03286v1 \[cs.CL\] 7 Feb 2022](https://arxiv.org/abs/2202.03286)
|
||||
[^42]: [Rawte et al 2023. A Survey of Hallucination in “Large” Foundation Models. arXiv:2309.05922v1 \[cs.AI\] 12 Sep 2023](https://arxiv.org/abs/2309.05922v1)
|
||||
[^43]: [Reiter 2018. Hallucination in Neural NLG, blog post, Nov 12, 2018](https://ehudreiter.com/2018/11/12/hallucination-in-neural-nlg)
|
||||
[^44]: [Rohrbach et al 2018. Object Hallucination in Image Captioning. arXiv:1809.02156v1 \[cs.CL\] 6 Sep 2018](https://arxiv.org/abs/1809.02156v1)
|
||||
[^45]: [Shuster et al 2021. Retrieval Augmentation Reduces Hallucination in Conversation. arXiv:2104.07567v1 \[cs.CL\] 15 Apr 2021](https://arxiv.org/abs/2104.07567v1)
|
||||
[^46]: [Song et al 2024. FineSurE: Fine-grained Summarization Evaluation using LLMs. arXiv:2407.00908v1 \[cs.CL\] 1 Jul 2024](https://arxiv.org/abs/2407.00908v1)
|
||||
[^47]: [Wang, Alex et al 2020. Asking and Answering Questions to Evaluate the Factual Consistency of Summaries. Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics, pp 5008–5020, July 5-10, 2020](https://aclanthology.org/2020.acl-main.450.pdf)
|
||||
[^48]: [Wang, Cunxiang et al 2023. Survey on Factuality in Large Language Models: Knowledge, Retrieval and Domain-Specificity. arXiv:2310.07521v1 \[cs.CL\] 11 Oct 2023](https://arxiv.org/abs/2310.07521v1)
|
||||
[^49]: [Wang, Zhihao et al 2020. Deep Learning for Image Super-resolution: A Survey. arXiv:1902.06068v2 \[cs.CV\] 8 Feb 2020](https://arxiv.org/abs/1902.06068v2)
|
||||
[^50]: [Weidinger et al 2022. Taxonomy of Risks posed by Language Models. FAccT ’22, June 21–24, 2022, Seoul, Republic of Korea. doi: 10.1145/3531146.3533088](https://dl.acm.org/doi/pdf/10.1145/3531146.3533088)
|
||||
[^51]: [Wiseman, Hieber & Rush 2017. Challenges in Data-to-Document Generation. arXiv:1707.08052v1 \[cs.CL\] 25 Jul 2017](https://arxiv.org/abs/arXiv:1707.08052v1)
|
||||
[^52]: [Xiang et al 2022. Deep learning for image inpainting: A survey. doi: 10.1016/j.patcog.2022.109046](https://doi.org/10.1016/j.patcog.2022.109046)
|
||||
[^53]: [Xiong et al 2019. Foreground-aware Image Inpainting. 2019 IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)](https://doi.org/10.1109/CVPR.2019.00599)
|
||||
[^54]: [Zhang, Yuhao et al 2019. Optimizing the Factual Correctness of a Summary: A Study of Summarizing Radiology Reports. arXiv:1911.02541v1 \[cs.CL\] 6 Nov 2019](https://arxiv.org/abs/1911.02541v1)
|
||||
[^55]: [Zhang, Yue et al 2023. Siren’s Song in the AI Ocean: A Survey on Hallucination in Large Language Models. arXiv:2309.01219v1 \[cs.CL\] 3 Sep 2023](https://arxiv.org/abs/2309.01219v1)
|
||||
[^56]: [Zhao et al 2020. Reducing Quantity Hallucinations in Abstractive Summarization. Findings of the Association for Computational Linguistics: EMNLP 2020, pp 2237–2249, November 16 - 20, 2020](https://aclanthology.org/2020.findings-emnlp.203.pdf)
|
||||
[^57]: [Zhiwei Xiong, Xiaoyan Sun, & Wu, F. (2009). Image hallucination with feature enhancement. 2009 IEEE Conference on Computer Vision and Pattern Recognition. doi:10.1109/cvpr.2009.5206630](https://doi.org/10.1109/cvpr.2009.5206630)
|
||||
[^58]: [Zhou, Bolei et al 2017. Places: An Image Database for Deep Scene Understanding. arXiv:1610.02055v1 \[cs.CV\] 6 Oct 2016](https://arxiv.org/abs/1610.02055v1)
|
||||
[^59]: [Zhou, Chunting et al 2021. Detecting Hallucinated Content in Conditional Neural Sequence Generation. Findings of the Association for Computational Linguistics: ACL-IJCNLP 2021, pp 1393–1404, August 1–6, 2021](https://aclanthology.org/2021.findings-acl.120.pdf)
|
||||
[^60]: [Zhu et al 2021. Enhancing Factual Consistency of Abstractive Summarization. Proceedings of the 2021 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, pp 718–733, June 6–11, 2021](https://aclanthology.org/2021.naacl-main.58.pdf)
|
||||
[^61]: [Fawzi et al 2016. Image inpainting through neural networks hallucinations. EPFL, Switzerland & IBM Research Watson, USA](https://www.cs.toronto.edu/~horst/cogrobo/papers/ivmsp2016.pdf)
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
title: Questions I have about sex
|
||||
description: >-
|
||||
Mark Vernon got me thinking about how the Church’s teaching on sex may be
|
||||
evolving.
|
||||
pubDate: 2024-12-17
|
||||
updatedDate: 2024-12-17
|
||||
---
|
||||
|
||||
I just listened back to [Mark Vernon][mark-vernon] talking about sexual desire
|
||||
and Christian spirituality.
|
||||
|
||||
He recounts how his sex ed at an evangelical camp as a boy taught him to think
|
||||
hard about holding hands with someone, just in case it led to something
|
||||
‘immoral’. He felt he had been taught a sexual naïvety, which has perhaps
|
||||
blinded people to the possibility of abuse – and misunderstood the gospel.
|
||||
|
||||
He puts forward an alternative to that naïvety, whereby sexual experience is an
|
||||
image or a foretaste of love for, or union with, God, exploring thoughts by
|
||||
Origen, Julian of Norwich, Dante, William Blake, Iris Murdoch, and various
|
||||
parables and episodes from the Gospels themselves.
|
||||
|
||||
Part of what’s so interesting about this, is I feel I got my first proper sex
|
||||
ed, as an adult, in an evangelical Christian context – and it pretty much lined
|
||||
up completely with what he was putting forward.
|
||||
|
||||
I’m also currently reading (as is Mark Vernon) Diarmaid MacCulloch’s epic
|
||||
history of Christian sexuality, [Lower Than the Angels][lower-than-the-angels].
|
||||
But so far (I’m about a third of the way through and up to about the 5th
|
||||
century) there have only been odd glimmers of positive Christian understandings
|
||||
of sexuality. The overwhelming Christian consensus of the early Church
|
||||
(according to MacCulloch) is that sexual desire is a symptom of humanity’s
|
||||
fallen state, not our longing for God.
|
||||
|
||||
So I want to know: what changed between Mark’s experience and mine? How is
|
||||
Christian teaching about sex changing right now? Was my experience typical of
|
||||
other Christians growing up today, in evangelical churches, across the
|
||||
denominational spectrum, across Britain, across the global Church? What _is_
|
||||
the Christian consensus on sex now, and how old is it, and where did it come
|
||||
from?
|
||||
|
||||
I guess I’ve got two-thirds of a gigantic tome to work through, first of all.
|
||||
That’ll be a start. Any answers? Postcards please.
|
||||
|
||||
[lower-than-the-angels]: https://www.penguin.co.uk/books/313582/lower-than-the-angels-by-macculloch-diarmaid/9780241400937
|
||||
[mark-vernon]: https://www.markvernon.com/the-gospel-sexual-desire-and-the-abuse-scandals-in-the-church-what-has-the-erotic-to-do-with-god
|
||||
@@ -1,193 +0,0 @@
|
||||
---
|
||||
title:
|
||||
How I read things on the Internet now (no, of course I don't leave the
|
||||
terminal!)
|
||||
description: >-
|
||||
I've been sprucing up how I follow what's happening on the Internet. I can now
|
||||
read all the things I want to read pretty efficiently, and enjoy doing it,
|
||||
which is exciting.
|
||||
pubDate: 2025-01-19
|
||||
---
|
||||
|
||||
## The problem
|
||||
|
||||
I like to read things on the Internet sometimes. Or listen to things. Or watch
|
||||
things.
|
||||
|
||||
Some interesting people write blog posts. Some beautiful people make music. Some
|
||||
silly people make comedy sketches. Sometimes my friends are sharing stuff with
|
||||
their friends, which means me (WIP on that front: I'll get back to that).
|
||||
|
||||
I want to know about it. I want to read interesting things that will educate me.
|
||||
I want to hear beautiful music. I want to hear about what my friends are up to.
|
||||
|
||||
I can't read everything as it comes in, it's too much: I'll need to sift a lot
|
||||
of it out quickly. I'll need to sift through it regularly to stay on top of it:
|
||||
like, several times a week, if not daily. And sometimes, while I'm doing my
|
||||
daily sifting, I'll find something I really want to read, but I haven't got time
|
||||
right now: I'll save this for the weekend.
|
||||
|
||||
For a while, I've been hosting [CommaFeed][commafeed] on [PikaPods][pikapods].
|
||||
This has been OK ([OMG, RSS is cool][rss]), but the interface is just clunky
|
||||
enough to make it a chore to use. That means I don't sift through stuff
|
||||
regularly, and that means my feed piles hundreds of unread posts high.
|
||||
|
||||
It also hasn't been any good for distinguishing between stuff I don't want to
|
||||
read _ever_, and stuff I don't want to read _right now_ but will get round to
|
||||
later. I could in theory use the bookmarking feature built-in to my browser, but
|
||||
removing things after I've read them is too clunky, so I don't do it.
|
||||
|
||||
## The solution
|
||||
|
||||
Every morning, I open my terminal and run [newsboat][newsboat].
|
||||
|
||||

|
||||
|
||||
I know the unread count is pretty fresh, because I've set up a systemd service
|
||||
to run newsboat at startup to fetch the feeds.
|
||||
|
||||
I press `l` twice to open a post. Then I press `n` to navigate to the next
|
||||
unread post until I run out of unread posts.
|
||||
|
||||

|
||||
|
||||
If I encounter something I want to read later, but don't have time right now, I
|
||||
press `b`, which runs a home-made bookmarking script. Here it is:
|
||||
|
||||
```bash
|
||||
### readlater.sh ###
|
||||
|
||||
# newsboat passes a few arguments:
|
||||
# the first one is the post URL
|
||||
url="$1"
|
||||
|
||||
# I turn the URL into a suitable filename
|
||||
filename=$( \
|
||||
echo $url | \
|
||||
sed "s/.*:\/\///" | \
|
||||
sed "s/\//./g" | \
|
||||
sed "s/\.html\$//g" \
|
||||
)
|
||||
filename="$filename".html
|
||||
|
||||
# If I've already got this in my reading list,
|
||||
# I don't add it again
|
||||
if [[ -a "$HOME/readlist/unread/$filename" ]]
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Otherwise, I download the post with curl
|
||||
# and pipe it to a file in my reading list
|
||||
# folder, ~/readlist/unread
|
||||
curl "$url" > "$HOME/readlist/unread/$filename"
|
||||
```
|
||||
|
||||
I can also run this script manually and pass it a URL of my choice at any time,
|
||||
say, if I find an interesting article while browsing the Web.
|
||||
|
||||
When I want to read from my reading list, I run `readnow.sh`, which simply opens
|
||||
my reading list folder, `~/readlist/unread`, in my terminal file browser of
|
||||
choice: namely, [ranger][ranger].
|
||||
|
||||

|
||||
|
||||
Although ranger has a preview, I'll typically open the file up in my terminal
|
||||
web browser of choice, which is [w3m][w3m] (plus a couple of custom
|
||||
key-bindings). I've configured this to be my preferred web browser in ranger by
|
||||
shifting it to the top of the list of HTML browsers in
|
||||
`~/.config/ranger/rifle.conf`.
|
||||
|
||||
```conf
|
||||
### ~/.config/ranger/rifle.conf ###
|
||||
|
||||
...
|
||||
|
||||
ext x?html?, has w3m, terminal = w3m "$@"
|
||||
ext x?html?, ...
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Having configured my default web browser in my ranger config, all I need to do
|
||||
is press `l`.
|
||||
|
||||

|
||||
|
||||
No ads, no cookie popups, no giant banner images taking 2 seconds to load and
|
||||
shifting the content all over the place: just the text I want to read. Isn't it
|
||||
beautiful?
|
||||
|
||||
Once I'm finished reading the post, I'll press `q` to quit w3m and return to
|
||||
ranger. Assuming I don't need to read it again, I'll press `dm` to move the post
|
||||
to `~/readlist/read` - my way of marking a post as 'read'.
|
||||
|
||||
I've done this by writing a super simple script, `markread.sh`:
|
||||
|
||||
```bash
|
||||
### markread.sh ###
|
||||
|
||||
filename="$(basename $1)"
|
||||
|
||||
if [[ -a "$HOME/readlist/unread/$filename" ]]
|
||||
then
|
||||
mv "$HOME/readlist/unread/$filename" "$HOME/readlist/read/$filename"
|
||||
echo "Marked $filename as read."
|
||||
else
|
||||
echo "I couldn't find a file in ~/readlist/unread with the name: $filename"
|
||||
fi
|
||||
```
|
||||
|
||||
...and hooking it onto the custom keybinding, `dm`, in ranger:
|
||||
|
||||
```conf
|
||||
### ~/.config/ranger/rc.conf ###
|
||||
|
||||
...
|
||||
|
||||
# map `dm` to run markread.sh in the shell, providing the active filename
|
||||
# as the first and only argument
|
||||
map dm shell markread.sh %f
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
## The result
|
||||
|
||||
I can now keep up to date, and I enjoy doing it.
|
||||
|
||||
I get not everyone likes to live in the terminal. I think the key takeaways are:
|
||||
|
||||
- Make it really easy to sift through new posts
|
||||
- When you sift, sift through every post, and for each one, either read it
|
||||
straight away, or add it to your reading list
|
||||
- Sift daily
|
||||
- Make it really easy to add things to your reading list
|
||||
- Make it really easy to browse, read things, and mark things read in your
|
||||
reading list
|
||||
- Set aside time to catch up on your reading list
|
||||
- Make the whole thing joyful (both because joy is good, and because you won't
|
||||
do it otherwise)
|
||||
|
||||
## Next steps
|
||||
|
||||
I still haven't really figured out social media. I'd like to stay up to date
|
||||
with what my friends are doing, especially the ones I don't see very often. If
|
||||
my friends are posting stuff on the Internet, I'd love to see it.
|
||||
|
||||
I still need to know:
|
||||
|
||||
- Are my friends posting stuff on the Internet?
|
||||
- If so, where?
|
||||
- What's the best way of subscribing to their posts - even if they live on
|
||||
different websites and in different formats?
|
||||
- What's the best way of sending and receiving comments/replies/reactions?
|
||||
|
||||
TBC. Answers on a postcard please.
|
||||
|
||||
[commafeed]: https://www.commafeed.com
|
||||
[pikapods]: https://www.pikapods.com
|
||||
[newsboat]: https://newsboat.org
|
||||
[ranger]: https://ranger.github.io
|
||||
[rss]: /blog/2024/05/02/no_more_youtube
|
||||
[w3m]: https://w3m.sourceforge.net
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 76 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 91 KiB |
@@ -1,139 +0,0 @@
|
||||
---
|
||||
title: Why scientists need philosophers
|
||||
description: This is a practice essay, OK? Don't shoot me if it's no good.
|
||||
pubDate: 2025-01-24
|
||||
---
|
||||
|
||||
I've recently been working at a
|
||||
[Philosophy of Science MOOC]([phil-sci-coursera]) on Coursera, the online
|
||||
courses website. Later on, they set you an exercise to write a short essay
|
||||
addressing how philosophy can contribute to science.
|
||||
|
||||
So this is my punt. Life is too short to revise or, hell, even research this, so
|
||||
don't take any of this as my settled opinion or as my best work. Whatever. With
|
||||
that caveat in mind, it might still be entertaining at least, or maybe even
|
||||
spark some thoughts.
|
||||
|
||||
---
|
||||
|
||||
Walk into a particular room in the Science Museum in Kensington, and you will
|
||||
find yourself enveloped in a cavern of ironmongery and miscellanea. The shelves
|
||||
droop under the weight of bolts, files, screws, bits, grinders, saws,
|
||||
protractors, clamps and pins. The inventory scrolls endlessly past you, voices
|
||||
reciting the lists of trinkets like an incantation.
|
||||
|
||||
This is the workshop of James Watt, meticulously reconstructed from the
|
||||
original as it was left in his home in Birmingham after his death. This
|
||||
entrancing space invites you to imagine a tireless creative, endlessly
|
||||
tinkering away at his next contraption.
|
||||
|
||||
And yet for all that - and for all his immense valorisation as the lynchpin of
|
||||
Britain's industrial revolution - Watt was reluctant to think of himself as the
|
||||
engineer everyone else loved. He aspired to be remembered not as an engineer
|
||||
but as a scientist.
|
||||
|
||||
To understand why James Watt, one of the most admired engineers who ever lived,
|
||||
wished he were famed as a scientist instead, is to understand something
|
||||
essential about modern Western thought.
|
||||
|
||||
In Watt's lifetime, scientists increasingly became the elite of society. In the
|
||||
nineteenth and twentieth century, this trend only gathered pace. We constructed
|
||||
our modern public health infrastructure on the advice of pathologists and made
|
||||
medicine scientific. We funded scientific expeditions to map the world, even to
|
||||
its remotest corners (in part to help us conquer it). We adopted radical new
|
||||
economic policies in response to scientific economic theories. We built vast
|
||||
infrastructure networks to communicate waves of invisible energy discovered by
|
||||
pioneering physicists, and built nuclear plants to generate more of the stuff
|
||||
by means of nuclear science. We even designed social programmes on the basis of
|
||||
scientific anthropology. By the end of the twentieth century, scientists were
|
||||
our prophets, priests and kings. Or so we thought.
|
||||
|
||||
In the 1990s, at the so-called 'end of history', it was assumed that there
|
||||
would be no more need for social upheaval. Humanity had arrived at the ideal
|
||||
system of social organisation. And among other ideologies - secularism,
|
||||
libertarianism, democracy - an essential part of the package is that science
|
||||
was our ultimate and incontestible way of securing knowledge about the world.
|
||||
|
||||
Yet now, that certainty is broken. Religious fundamentalism, whether Christian,
|
||||
Muslim, Hindu, or else besides, is politically empowered in many places,
|
||||
together with its rejection of science.
|
||||
|
||||
At the same time, the myth of science is ever more punctured. The supposedly
|
||||
scientific West has increasingly come to appreciate that their scientific
|
||||
heritage also includes much we would rather ignore - phrenology, race science,
|
||||
systematic blindness to female bodies in medicine.
|
||||
|
||||
Meanwhile, scientists themselves are noticing that their holy calling has
|
||||
turned out to be rather less holy than they had hoped. They find science
|
||||
pulled between the competing demands of truth and tenure. Scientific knowledge
|
||||
is locked behind the paywalls of exclusive journals, which even many academics
|
||||
struggle to access, never mind the general public.
|
||||
|
||||
What then for science in the twenty-first century?
|
||||
|
||||
Yet there is another story available. It starts with confessing that the old
|
||||
stories got things wrong in important ways. When we put ideology aside, science
|
||||
has not been on an uncontested march to universal acceptance since Galileo.
|
||||
There has been continual change, continual conflict, continual readjustment of
|
||||
our ideas to the changing demands of the age.
|
||||
|
||||
In Galileo's day, it may have been a fight to establish that there was much to
|
||||
be seen by simply looking. As empirical observation started to prove its worth
|
||||
in the early modern period, thinkers wrestled with new problems: how to
|
||||
reconcile the evidence of Scripture with the evidence of the senses? How to
|
||||
understand how sensation can give us knowledge at all, granted that any
|
||||
observer may be vulnerable to illusions, tricks and dreams? And if that's how
|
||||
sense data work, what then for our mathematical or logical knowledge, which
|
||||
seems to already bind the world even before we start experiencing it?
|
||||
|
||||
This centuries-long struggle culminated in the work of Kant, who in his 1786
|
||||
magnum opus, the _Critique of Pure Reason_, set out a masterful - if infamously
|
||||
obscure - system, which enabled thinkers to understand just how empirical
|
||||
knowledge might work.
|
||||
|
||||
Yet two generations later, Charles Darwin lit the flame under new controversy
|
||||
about the relationship between scientific and religious knowledge. His bizarre
|
||||
and wildly imaginative theory of evolution by natural selection challenged the
|
||||
Genesis Creation accounts, and this was soon to be followed up with the theory
|
||||
of tectonic shift.
|
||||
|
||||
Some said that where scientists contradicted the authority of Scripture, the
|
||||
word of God must always win. Others said that science alone had the keys to
|
||||
knowledge, and if what the Bible said couldn't be proven scientifically, then
|
||||
it couldn't be accepted. Some said that science and religion were two
|
||||
incommensurable attempts to study the same subject matter, while others said
|
||||
that they covered completely separate spheres.
|
||||
|
||||
Gradually, all of these views moved to the extremes. Now, most people (though
|
||||
not all) agree that science and religion have overlapping spheres, and can
|
||||
inform one another, but neither the Book of Nature nor the Book of Scripture
|
||||
has the decisive final say.
|
||||
|
||||
Now, in our post-Christendom Western context, it's more important than ever to
|
||||
understand how science and religion can talk to one another. Religious
|
||||
minorities - as all religions now are in the West - are vulnerable to the risk
|
||||
of becoming epistemic islands, cut off from the knowledge of the rest of the
|
||||
community, unless we can find ways that science can talk across creedal
|
||||
differences.
|
||||
|
||||
We need, too, for scientifically marginalised communities, such as non-white
|
||||
people, whom science has ignored, or worse, to be more tightly integrated into
|
||||
science, both so that knowledge might increase, and so that the benefits
|
||||
knowledge gives might be fairly shared.
|
||||
|
||||
In light of these urgent needs, today's philosophers are considering science
|
||||
not just as an epistemic problem, but as a social problem. As philosophers once
|
||||
established science as the bedrock of modern knowledge, so philosophers today
|
||||
have the task of figuring out how science can glue together our societies.
|
||||
|
||||
Science has been at its most dangerous when it hasn't been questioned. At all
|
||||
times, as long as we practice science, we need to consider what it means, what
|
||||
it means to do science well, how it can generate knowledge, and how it ought to
|
||||
be used as a powerful instrument of change.
|
||||
|
||||
And perhaps that might justify James Watt in his obsession to be seen as a
|
||||
scientist: since we can't get by just with practitioners. We need people who
|
||||
can see our practices from the outside and shine a mirror back on us. If we
|
||||
want science, then we need philosophers.
|
||||
|
||||
[phil-sci-coursera]: https://www.coursera.org/learn/philosophy-physical-sciences
|
||||
@@ -1,77 +0,0 @@
|
||||
---
|
||||
title: A paradox about 'should'
|
||||
description: >-
|
||||
I seem to have accidentally proven that drinking wine both is and is not a
|
||||
thing you should do. Let's hope that wine doesn't disappear in a puff of
|
||||
logical smoke.
|
||||
pubDate: 2025-01-28
|
||||
---
|
||||
|
||||
We're pretty familiar with the idea that there can be reasons for doing
|
||||
something, and reasons against. Drinking wine is bad for your liver, but good
|
||||
for your social life.
|
||||
|
||||
But look what happens if we express this in this way:
|
||||
|
||||
1. Drinking wine is bad for your liver.
|
||||
2. You shouldn't do things which are bad for your liver.
|
||||
3. All things you shouldn't do aren't things you should do.
|
||||
4. Therefore, drinking wine isn't a thing you should do.
|
||||
|
||||
In contrast to this:
|
||||
|
||||
5. Drinking wine is a good social activity.
|
||||
6. You should do things which are good social activities.
|
||||
7. Therefore, drinking wine is a thing you should do.
|
||||
|
||||
Now both 1-4 and 5-7 seem like logically valid arguments with true premises,
|
||||
but 4 and 7 are contradictory!
|
||||
|
||||
I don't think there's any use in complaining about premise 3. All that gives us
|
||||
is the possibility that wine is both a thing you should do, and a thing you
|
||||
shouldn't do. But that's an absurdity. Something can't be both obligatory and
|
||||
forbidden at the same time. It's scarcely any better than a contradiction: it
|
||||
is inconsistent with any useful concept of obligation.
|
||||
|
||||
Remember that we would quite like to know, at the end of all our argument,
|
||||
whether we should drink wine or whether we shouldn't. 'Both' is not an adequate
|
||||
answer, because it's not a useful guide for action: we can't both drink wine and
|
||||
not drink wine. So if 'should' is to function as we need it to, 3 must be true.
|
||||
|
||||
I think a more profitable way forward is this. Let's re-write premise 2:
|
||||
|
||||
2. All things which are bad for your liver are things such that the fact that
|
||||
that thing is bad for your liver is a reason not to do it.
|
||||
|
||||
We can similarly re-write premise 6:
|
||||
|
||||
6. All things which are good social activites are things such that the fact that
|
||||
they are good social activities is a reason to do them.
|
||||
|
||||
Then premise 3, if it's to play the same logical role in the argument, would
|
||||
have to read:
|
||||
|
||||
3. All things such that the fact that that thing is bad for your liver is a
|
||||
reason not to do it is not a thing such that the fact that that thing is a
|
||||
good social activity is a reason to do it.
|
||||
|
||||
Our re-written 2 and 6 seem to adequately capture the sense of the original,
|
||||
but 3 is now obviously false. With our re-written sentences, we can avoid
|
||||
generating a contradiction without doing any fatal damage to our concept of
|
||||
'should'.
|
||||
|
||||
OK. Grant for the sake of argument that that was a good move. What have we
|
||||
achieved? Have we actually solved the problem?
|
||||
|
||||
We started out with a pair of arguments which generate a contradiction. Our
|
||||
move generated a new pair of arguments which don't generate a contradiction. So
|
||||
what? Isn't the first contradiction still there?
|
||||
|
||||
Perhaps you could say that our re-written version of 2 (and so on) are more
|
||||
accurate elaborations of the originals. Fine. But what about those originals,
|
||||
then? You've still either got to say that they're true, false, or gibberish.
|
||||
Producing your second argument hasn't convinced me to move my opinion about the
|
||||
originals. The original premises seem just as true, and the original arguments
|
||||
just as valid, as when we began.
|
||||
|
||||
What gives? Answers on a postcard as usual please.
|
||||
@@ -1,194 +0,0 @@
|
||||
---
|
||||
title: Surprised By Hope
|
||||
description:
|
||||
I've been working on my resurrection doctrine. Here's where I've got to.
|
||||
pubDate: 2025-05-02
|
||||
---
|
||||
|
||||
A couple of months ago, I was chatting to my friend Neil on the way home from
|
||||
church, and in that conversation, I confessed to him that I had no idea what
|
||||
happens to people after they die.
|
||||
|
||||
This might come as a surprise to some people who know me. Lots of people have
|
||||
solid ideas about what happens to people after they die. For different people,
|
||||
those ideas are very different. Here in Scotland, many people believe that death
|
||||
is a final end. Many more believe that death marks a physical, and perhaps also
|
||||
a spiritual, reunion with the rest of the universe, as the matter of your body
|
||||
begins to be slowly digested and recycled: hence why ever more people are opting
|
||||
to be cremated rather than buried in one piece. Other minorities believe in an
|
||||
immortal soul that goes to some other place - be it heaven, hell, purgatory,
|
||||
nirvana or reincarnation. I belong to the Christian community, which is supposed
|
||||
to have clear answers on these questions passed down from ancient times, and
|
||||
people who know me know that I think hard about doctrines. So it may be a
|
||||
surprise that amongst all the convictions which people have all around me, and
|
||||
amongst all my own convictions on other topics, I hadn't the faintest clue what
|
||||
happens to people after they die.
|
||||
|
||||
If you are surprised, let me surprise you some more: I am of no fixed opinion on
|
||||
a whole range of really important philosophical and theological topics, from the
|
||||
existence of the soul to the purpose of sex, from the nature of the sacraments
|
||||
to the metaphysics of the mind. But late last year, I set myself some New Year's
|
||||
resolutions to address some of these questions. Not, by any means, to decide
|
||||
once and for all the end of the matter: just to form a well-informed opinion.
|
||||
Sometimes staying quiet isn't good enough: I'm aiming to rectify my silence on
|
||||
these topics, because I think these topics are too important to ignore.
|
||||
|
||||
And one of the issues I picked out was this very issue: what happens to people
|
||||
after they die? To that end, Neil recommended me a book by the conservative
|
||||
Anglican theologian, Tom Wright, called _Surprised By Hope_, published in 2007,
|
||||
at which point I was just learning to spell.
|
||||
|
||||
As a result of this book, I feel I understand what the Christian orthodoxy is,
|
||||
and feel able to treat that view as my working assumption.
|
||||
|
||||
Wright defends traditional Christian orthodoxy. He claims that his view is
|
||||
orthodox, and I'm roundly convinced that it is. When I wrote down in bullet
|
||||
points what his view amounted to, I found that I had more or less re-written
|
||||
half the Nicene Creed.
|
||||
|
||||
- Jesus Christ was crucified under Pontius Pilate.
|
||||
- On the third day, he rose from the dead.
|
||||
- He ascended into heaven and is seated at the right hand of the Father.
|
||||
- He will come again in glory to judge the living and the dead.
|
||||
- His kingdom will have no end.
|
||||
- We look for the resurrection of the dead, and the life of the world to come.
|
||||
|
||||
Amen. That's pretty much it. All that I need to stress, to avoid under-stating
|
||||
Wright's view, is that he specifically thinks that physical creation, including
|
||||
our bodies, will be transformed into a new kind of physicality, including new
|
||||
kinds of physical bodies for you and me, and that the 'world to come' means that
|
||||
heaven and earth - which he regards as God's physical space and our physical
|
||||
space - will be united.
|
||||
|
||||
He contrasts this orthodox view with several views common today amongst
|
||||
Christians, some of which have even been muddled up with the traditional
|
||||
orthodoxy:
|
||||
|
||||
- 'Jesus was raised to new life, spiritually, like a ghost.'
|
||||
- 'Jesus literally ascended into the sky, as if he had an invisible jetpack: and
|
||||
that's where he is now.'
|
||||
- 'The Christian hope is that we will go to be united with God in heaven after
|
||||
we die.'
|
||||
- 'The Christian hope is that we will be snatched up to heaven at the rapture
|
||||
and taken to a resurrection life there.'
|
||||
- 'The Christian hope is that we will experience God's eternal life temporarily
|
||||
before we die.'
|
||||
- 'Jesus won't really judge anyone, because he loves everyone, and because he's
|
||||
meek and lowly, not judgy.'
|
||||
- 'The world will be redeemed through the work of the Church.'
|
||||
- 'Only God can ever make a difference to the sinful state of the world, so the
|
||||
only works we should care about now are "saving souls".'
|
||||
|
||||
I am happy to admit that I have often been guilty of most of these heresies. The
|
||||
only ones I've never been tempted by are the 'rapture' view, and the thing about
|
||||
the invisible jetpack.
|
||||
|
||||
Wright has not definitively put any of these ideas to rest for me. _Surprised By
|
||||
Hope_ is just not that kind of book. It's not a treatise. It's actually quite
|
||||
light on substantial argument in favour of Wright's position. Wright's main
|
||||
achievement for me, isn't to convince me that he's right, but that his position
|
||||
is a good starting point, a good place from which I should need to be convinced.
|
||||
|
||||
He does this chiefly by showing that his view is the consensus view of the New
|
||||
Testament. (He claims to be showing it is the consensus view of 'the early
|
||||
Church', but he never presents much evidence outside the New Testament, so I'm
|
||||
being charitable by restricting his claim to the New Testament authors.) Say
|
||||
what you like about Scriptural authority; if Mark, Matthew, Luke, John and Paul
|
||||
all were convinced something was apostolic teaching, you'd better well take it
|
||||
seriously.
|
||||
|
||||
If you want convincing, take a look for yourself. Some of the key New Testament
|
||||
texts are John 5; Acts 17:30-32, 24:14-16; 1 Cor 15, 16:22; 2 Cor 4-5; Rom 6, 8;
|
||||
Col 3:1-4; Eph 1:10; 1 Thess 4:14-18 and of course Rev 21-22.
|
||||
|
||||
You can also try convincing yourself that this is coherent with the Old
|
||||
Testament hope, by looking at Isa 11, Dan 7, Ps 2, and having another look at
|
||||
the assumptions behind Paul's behaviour in Acts 24:14-16.
|
||||
|
||||
The only significant problem texts I've found for Wright's view are 2 Cor 4-5
|
||||
and Rev 21-22. In 2 Cor 4-5, Paul seems to plainly assert that we will have to
|
||||
leave the body in order to face the judgement seat of Christ, and which makes no
|
||||
apology for the assertion that, even though Christ has reconciled us to God, we
|
||||
will still have to face judgement for our deeds - which seems to justify the
|
||||
infamously un-Biblical doctrine of purgatory. If you assume that Paul's writings
|
||||
express a completely consistent view, however, you will have routes out; in
|
||||
particular, you could look at the language of Rom 6 and 8. Large chunks of
|
||||
Paul's letter to the Romans also suggest, if taken out of context, that we will
|
||||
have to leave our bodies behind, and that even those reconciled through Christ
|
||||
will face judgement for their deeds - except that key verses contradict both of
|
||||
those views. Clearly, that's not what Paul meant in Romans; so, you might argue,
|
||||
it's not what he meant in 2 Cor either: provided you assume that Paul's writings
|
||||
present a consistent view. (If Paul changed his mind, no explanation is
|
||||
necessary why Rom and 2 Cor seem to be inconsistent: they could actually be
|
||||
inconsistent in that case.)
|
||||
|
||||
Meanwhile, in Rev 21-22, John has a vision of a 'new heaven and a new earth, for
|
||||
the first heaven and the first earth had passed away'. This directly contradicts
|
||||
Wright's emphatic insistence that God's new creation will be continuous with the
|
||||
first. For Wright, this isn't an academic detail, it's needed in order to give
|
||||
us a motive to care for the world we've currently got. Without continuity, he
|
||||
fears we'd be right to join those who are content with trashing the natural
|
||||
environment because the whole thing's going to end up in fire and brimstone
|
||||
anyway. Yet this piece of Revelation seems to permit exactly that.
|
||||
|
||||
If you were to defend Wright against Revelation, you might point out that
|
||||
Revelation is a literal description of a vision John had, and is therefore not
|
||||
in every detail an accurate picture of the future, but a metaphor, an image of
|
||||
the future. (Fine, but if the wholesale replacement of heaven and earth is a
|
||||
metaphor, what is it a metaphor for? If the literal future is continuity, why
|
||||
not describe a vision of continuity?) And you may also assume that the entire
|
||||
Bible is consistent on the matter of God's ultimate future, and on that
|
||||
assumption, bring your analysis of the rest of the New Testament to bear.
|
||||
|
||||
Whatever you do with the problem texts, it seems clear to me that the
|
||||
overwhelming weight of Biblical evidence favours the traditional orthodox
|
||||
position over any of the alternatives. Given that, I'm happy to take it as a
|
||||
starting point as I continue to think about what happens to people after they
|
||||
die.
|
||||
|
||||
So, I may go back to Neil now, and say - maybe not quite yet 'I have an
|
||||
opinion' - but at least 'I know what my working assumptions are.' I know what is
|
||||
the orthodox Christian view: that is, the consensus view of the relevant
|
||||
experts. The consensus view of relevant experts is generally a good place to
|
||||
start.
|
||||
|
||||
I still have plenty of concerns, though. Here are my top three quandaries on
|
||||
this topic now.
|
||||
|
||||
Firstly, it would be rather unsettling if the orthodox Christian vision for
|
||||
God's ultimate future popped entirely into existence after the Ascension. The
|
||||
apostles say that their teaching was given to them by the Holy Spirit - but are
|
||||
we going to trust our entire doctrine on the future to what a small number of
|
||||
men claim was told to them by an invisible being behind closed doors? If the
|
||||
view of the New Testament authors is trustworthy, then it at the very least
|
||||
needs to cohere very well with the Old Testament. The New Testament hope should
|
||||
be woven deep into the Old Testament promises. I find Genesis, Daniel, Isaiah
|
||||
and the Psalms promising, but I've only gotten skin-deep into comparing these
|
||||
texts to the New Testament: I'd like to go both deeper into these texts, and
|
||||
broader across the Old Testament.
|
||||
|
||||
Secondly, I want to hear the opposition in their own words. Wright very openly
|
||||
admits that his view is currently a minority opinion even within Christianity,
|
||||
despite being Christian orthodoxy. Given that is the case, it's reasonable to
|
||||
expect the opposition to have some good arguments on their side. Wright has not
|
||||
presented any strong arguments from opposing views, which makes me suspect not
|
||||
that there are no good arguments, but that he has omitted to cover them in his
|
||||
short and accessible book. And if there really are no strong arguments against
|
||||
the traditional view, then we should expect powerful explanations as to why so
|
||||
few people accept what apparently they should.
|
||||
|
||||
Thirdly, I have residual concerns from the metaphysics of mind. I recall from my
|
||||
undergraduate days that continuity is a major concern amongst the relevant
|
||||
experts. I think a minority of them even claim that the person who goes to sleep
|
||||
and the person who wakes up again are completely distinct people who just so
|
||||
happen to time-share the same body. If continuity is a major problem, then it is
|
||||
a major problem for resurrection doctrine, too, which even in the New Testament
|
||||
is compared to a kind of sleep, admitting that there is some kind of
|
||||
discontinuity between the old body and the resurrection body. Add to this the
|
||||
easily observable fact that many Christian bodies have rotted and are no longer
|
||||
suitable for re-animation: their new bodies will have to be physically
|
||||
discontinuous as well as mentally discontinuous with their old bodies. If I will
|
||||
be given a new body, is it metaphysically plausible that the person who inhabits
|
||||
that body will be the same 'me' that inhabits this body, now?
|
||||
|
||||
Much love all. As always, answers on a postcard please.
|
||||
@@ -1,201 +0,0 @@
|
||||
---
|
||||
title: Does resurrection doctrine give us unique reasons to work for justice?
|
||||
description: >-
|
||||
Tom Wright claims that the only Christian grounds for striving for justice now
|
||||
is in resurrection doctrine. I'm not convinced.
|
||||
pubDate: 2025-05-04
|
||||
---
|
||||
|
||||
I've been reading Tom Wright's _Surprised By Hope_, defending his orthodox view
|
||||
on resurrection. One of his key claims is that only by accepting the orthodox
|
||||
position on resurrection can Christians justify striving for justice on earth.
|
||||
|
||||
To argue this, he needs to first show that resurrection doctrine does justify
|
||||
striving for justice on earth, and secondly that the available alternatives fail
|
||||
to do so. Firstly, the positive argument.
|
||||
|
||||
## Does resurrection give us reasons to work for justice?
|
||||
|
||||
Wright's argument depends on his view on what God's ultimate future will look
|
||||
like: the present creation will not be abandoned, destroyed, or replaced, but
|
||||
physically transformed into the new creation.
|
||||
|
||||
He argues that our work now has value, because, at the time when God transforms
|
||||
the old world into the new, he will incorporate the outcomes of our good works
|
||||
into the new creation, like an architect incorporating the works of many
|
||||
stonemasons into a great cathedral.
|
||||
|
||||
He argues this on the basis of 1 Cor 15. I found it a struggle to find a good
|
||||
justification for Wright's view in chapter 15 alone, but I did find some crucial
|
||||
context in chapter 3, just before he begins the first of his many exhortations
|
||||
to the Corinthians. It would be best to read the whole chapter, but here is
|
||||
verses 11-15:
|
||||
|
||||
> For no one can lay any foundation other than the one already laid, which is
|
||||
> Jesus Christ. If anyone builds on this foundation using gold, silver, costly
|
||||
> stones, wood, hay or straw, their work will be shown for what it is, because
|
||||
> the Day will bring it to light. It will be revealed with fire, and the fire
|
||||
> will test the quality of each person’s work. If what has been built survives,
|
||||
> the builder will receive a reward. If it is burned up, the builder will suffer
|
||||
> loss but yet will be saved—even though only as one escaping through the
|
||||
> flames.
|
||||
|
||||
This at least implies that the outcome of all our work will persist at least
|
||||
until the time of judgement, when it will undergo testing, and those that pass
|
||||
the test will enjoy a reward. You could read this as being like a quality check,
|
||||
with God dishing out benefits to those that pass his assessment. But you could
|
||||
read it in another way, more favourable to Wright. The works will be proven, and
|
||||
the ones that withstand the process will themselves generate a benefit. You
|
||||
could think of it like baking: when you put a cake in the oven, you prove
|
||||
whether or not you got the recipe right; if not, it goes in the bin, and if you
|
||||
did get it right, you get to enjoy the cake. So I agree that 1 Cor provides a
|
||||
reason to think that the outcome of our works will somehow persist until the
|
||||
time of judgement.
|
||||
|
||||
However, Wright doesn't just think that our works will persist until the time of
|
||||
judgement, he also believes that they will at that time be transformed and then
|
||||
incorporated into the new creation. 1 Cor doesn't directly justify this view. It
|
||||
is, at least, coherent. Baking a cake in the oven transforms the dough.
|
||||
|
||||
So it seems reasonable to me to use 1 Cor to justify Wright's view that our
|
||||
works will be transformed into the new Creation. However, that's before
|
||||
considering any counter-arguments, and I have two which concern me.
|
||||
|
||||
One is that, as Ecclesiastes points out, the profits of our work will be laid to
|
||||
waste by time. We don't know when God is going to bring about the new creation.
|
||||
It could be tomorrow, and we should be behaving today in light of that
|
||||
possibility - but of all the available possibilities, most of them are in the
|
||||
distant future, so we should expect on average that there will be a long
|
||||
interval between my deeds today and the judgement of them. Since time lays waste
|
||||
to all our endeavours, we should expect that the profits of our work will have
|
||||
vanished long before the judgement. Therefore, it would be unreasonable to work
|
||||
for justice in the hope that our work will persist until the time of judgement
|
||||
in order to be incorporated into the new creation, as Wright argues we should
|
||||
do.
|
||||
|
||||
This first problem is probably the most important, but it's vulnerable to some
|
||||
counter-arguments, which rather miss the point. So I'm going to move on to my
|
||||
second problem, which is more niche, but which I think holds stronger against
|
||||
counter-arguments.
|
||||
|
||||
In 1845, the HMS Erebus and HMS Terror left Britain on an expedition to explore
|
||||
the Northwest Passage. In July 1845, they were spotted by whalers in Baffin Bay.
|
||||
None of the sailors were ever seen alive again by Europeans. Both ships became
|
||||
locked into ice in September 1846, and probably never sailed again. In April
|
||||
1848, the remaining crew began a desperate 250-mile march to the nearest
|
||||
European outpost. It is almost certain that all of them died.
|
||||
|
||||
Now, suppose that one of those sailors, between 1846 and 1848, did something
|
||||
good. Maybe a major act of heroism, or maybe a small, kind word. I think it's
|
||||
reasonable to suppose that someone, at some time, did something good.
|
||||
|
||||
All the profits of that good act have now completely perished. They are not
|
||||
recorded in the small records the sailors left behind. None of the sailors who
|
||||
benefited lived to pass on the benefits. None survived to pass on the light of
|
||||
justice to the next generation.
|
||||
|
||||
At the time of judgement, then, there will be no remnant of this good act for
|
||||
God to test, transform and incorporate into his new creation.
|
||||
|
||||
Does this mean that the good act was wasted? Was it only worth a shot just in
|
||||
case, despite all the odds, the sailors made it home again?
|
||||
|
||||
I think this is a cruel conclusion: but it seems to be where Wright must go.
|
||||
|
||||
If it is implausible that the profits of all our good works will make it through
|
||||
to the time of judgement, then we have to accept that 1 Cor 3 is true only in
|
||||
some metaphorical sense, not that our works will literally persist in order to
|
||||
be tested. And if that is true, then the premise of Wright's argument is false:
|
||||
our work will not necessarily be incorporated into the new creation, so that
|
||||
cannot generate reasons for working for justice now.
|
||||
|
||||
I am not convinced by Wright's positive argument. I would like to consider
|
||||
alternative interpretations of 1 Cor. This is what Wright goes on to do.
|
||||
|
||||
## Do alternative views give us reason to work for justice?
|
||||
|
||||
The first view which Wright considers is the gnostic view that resurrection is
|
||||
just an afterlife in heaven. He argues that this does not generate reasons for
|
||||
working for justice now, but his argument is really the converse of the argument
|
||||
in favour of his own view, which I've already considered above, so I'll move on.
|
||||
|
||||
The other alternative Wright considers is what he calls 'evolutionary optimism'.
|
||||
You might also call this 'progressivism'. By this he means the view that the new
|
||||
creation will be made the Church gradually building upon its own works,
|
||||
generation after generation, approaching and eventually achieving God's perfect
|
||||
standard by its works. This is the Victorian optimism which is still a powerful
|
||||
force in our politics: that history is building upon itself, and progressing
|
||||
from barbarism to civilisation, from brutishness to beauty, from tragedy to
|
||||
justice.
|
||||
|
||||
He argues that this view, too, does not give us reasons to work for justice now.
|
||||
His argument is intriguing: if our work for justice is condemned to only ever be
|
||||
partially successful, then we have no reason to do it. In fact, contra the
|
||||
evolutionary optimist, no amount of hard work on our part will ever achieve
|
||||
perfect justice, and therefore if bringing in the new creation is all about our
|
||||
works, we have no reason to strive for justice.
|
||||
|
||||
I'm intrigued by the premise that if we know that our work will at best be
|
||||
partially successful, then we have no reason to do it.
|
||||
|
||||
This isn't how we ordinarily think: typically, if I think attempting to go to
|
||||
the gym twice a week is going to be partially successful, I would say that this
|
||||
generates a reason for me to go to the gym.
|
||||
|
||||
But I sense there may be an interesting meta-ethical thesis here: perhaps what
|
||||
we ordinarily call 'partial success' is in fact a mistake, papering over what is
|
||||
in fact simply a failure.
|
||||
|
||||
There's an obvious error theory: we had to create the concept of the 'partial
|
||||
success' in order to generate reasons in the world as it appears, the world as
|
||||
described in Ecclesiastes as 'vanity', where the best-laid plans of mice and men
|
||||
gang aft agley, and all our works crumble into the dust eventually. In order to
|
||||
think we had reasons at all, we needed to invent the concept of the 'partial
|
||||
success'.
|
||||
|
||||
But is there a good argument for the view that there is no such thing as a
|
||||
partial success?
|
||||
|
||||
In 1915, the HMS Endurance, under the command of Captain Ernest Shackleton,
|
||||
became stuck fast in Antarctic pack ice in the Weddell Sea. In the face of
|
||||
extraordinary challenges, Shackleton vowed to bring all his sailors back to the
|
||||
UK alive: and in one of the most famous exploits of Antarctic exploration, he
|
||||
succeeded.
|
||||
|
||||
It would have been wrong, had Shackleton vowed only to bring back _most_ of his
|
||||
sailors. We know that he would have been able to bring _all_ of them back,
|
||||
because he in fact did so. To strive for less would have been negligent.
|
||||
|
||||
This is to illustrate a general principle: we ought to strive for the best that
|
||||
we are able.
|
||||
|
||||
Grant that necessarily, no particular justice is inevitable. It follows that
|
||||
necessarily, it is possible to prevent all injustice. Therefore, perfect justice
|
||||
is achievable.
|
||||
|
||||
And yet we _know_ that we will not achieve perfect justice. It's way too hard.
|
||||
|
||||
It does seem that I've proven a contradiction: both that perfect justice is
|
||||
possible and that it is impossible. I expect these are two different kinds of
|
||||
modality. I'm not too bothered to carefully distinguish them, as long we agree
|
||||
that these two things can both be true in some sense. By analogy, consider that,
|
||||
if you can run a mile in so many seconds, you can run it in a second less; that,
|
||||
by sorites, it follows that you can run a mile in a minute; and that you
|
||||
obviously cannot run a mile in a minute: it is too hard. Perfect justice is
|
||||
perhaps a little like this: it is achievable in the sense that it is physically
|
||||
possible for us to achieve it, but unachievable in the sense that it's way too
|
||||
hard.
|
||||
|
||||
So, since perfect justice is in some sense achievable, it follows that we ought
|
||||
to strive for it. But since we know we will not achieve perfect justice, it
|
||||
follows that we cannot have a reason to strive for it: we cannot genuinely
|
||||
strive for what we know we cannot do. Therefore, if you reject that God will
|
||||
work to transform our world of vanity into something fundamentally different
|
||||
where perfect justice is not only genuinely achievable but actually realised,
|
||||
then you will be stuck in this hopeless tension, where you both must bring about
|
||||
perfect justice, and have no reason to do it, because you have no hope of
|
||||
success.
|
||||
|
||||
Where from here? I would really like to find alternative interpretations of 1 Cor,
|
||||
and weigh them up against Wright's interpretation. It may be that, whatever the
|
||||
counter-arguments, Wright's view is the strongest available. It may not.
|
||||
@@ -1,200 +0,0 @@
|
||||
---
|
||||
title: Figuring things out
|
||||
description:
|
||||
I thought I needed to 'figure things out'. Here's what I did instead.
|
||||
pubDate: 2025-06-23
|
||||
---
|
||||
|
||||
'You could always do a Panic Masters.' In my last year of undergraduate studies,
|
||||
that was often the sort of advice we liked to console one another with. A lucky
|
||||
few people in my year had a clear sense of vocation, but most of us felt
|
||||
confused.
|
||||
|
||||
Not that we lacked options - graduating with a good degree from a good
|
||||
university, we were lucky to have a great deal more options than most people our
|
||||
age. We went all sorts of directions. Some followed the money, going into big
|
||||
boring management consultancy, big bad tech companies or startups swimming in
|
||||
venture capital. Others wanted something more noble, and pursued teaching or the
|
||||
third sector. Others still went travelling the world on a shoestring or worked a
|
||||
low-skilled job living with their parents, hoping to 'figure things out'.
|
||||
|
||||
I thought I needed to figure things out. But I was sure I wasn't going to do
|
||||
that by pulling pints, going on holiday, or staying in the university (even
|
||||
though I felt passion for academia). I needed something different, something
|
||||
that would move my life forward, and ideally, something that would pay the
|
||||
bills. Then, maybe after a year or two, I would have a better idea of what
|
||||
longer-term future I saw for myself. This, I thought, is the way to start
|
||||
figuring things out.
|
||||
|
||||
But by January of this year (2025), nothing seemed to have changed. I was still
|
||||
working in the same job. I hadn't discovered a passion for software engineering.
|
||||
Nor had I discovered a passion for anything else. I was more skilled, I suppose,
|
||||
but I didn't have any clearer ideas about how the skills I have should guide me
|
||||
into any career into particular. I had looked at other jobs, but not made many
|
||||
serious applications. I had applied to a Masters programme in 2024, got an
|
||||
offer, turned it down, and applied again in 2025. I was disappointed that I
|
||||
apparently hadn't made much progress.
|
||||
|
||||
So I vowed to do something about it. I promised myself to study the matter. I
|
||||
wanted to know what route to pursue. And, being Christian, I thought, I had to
|
||||
figure out how to leverage my theological resources to answer this question. I
|
||||
believed that God would have a path set out for me, and so I had to find out
|
||||
what it was. A friend told me I needed discernment. That, I thought, was what I
|
||||
needed to do - discern the will of God for my career.
|
||||
|
||||
I supposed, what God willed me to do in general was quite obvious -- he wants me
|
||||
to live in line with the gospel. But that doesn't say much about my career
|
||||
choices. So I expected to find something a little more specific. I didn't expect
|
||||
to find it in the Bible directly, of course, as there's not much about software
|
||||
engineering in the Bible. But maybe the Holy Spirit was trying to nudge me in
|
||||
the right direction, and I just needed to figure out how to hear him.
|
||||
|
||||
By the way, if you're not a super-spiritual sort and this is starting to sound a
|
||||
little kooky, I'm with you -- but I didn't see any other possibility. After all,
|
||||
what else could 'discernment' mean in practice, if not 'discerning' some still
|
||||
small voice?
|
||||
|
||||
So I studied. I got myself copies of some tracts, including Tim Keller's [_Every
|
||||
Good Endeavour_][every-good-endeavour] and William Taylor's [_Revolutionary
|
||||
Work_][revolutionary-work]. These writers showed me how I had for so long been
|
||||
stuck in a view of work which didn't make sense and wasn't leading me anywhere.
|
||||
I came away shaken off from how I had been thinking before, and given a new
|
||||
perspective from which to start re-thinking my attitudes to work. It's been
|
||||
exhilirating, and I recommend both books to anyone for whom work is a major
|
||||
concern (but especially to those who, like me, are already infected with
|
||||
middle-class thinking, or those at risk of catching it).
|
||||
|
||||
The will of God for my life really is as simple as I had feared. What God wants
|
||||
for me is the same as what he wants for everyone: to live in line with the
|
||||
gospel. God probably doesn't have any special extras for me personally. If the
|
||||
Holy Spirit does want to speak to me and wants me to hear it, I can trust him to
|
||||
make that happen, and in the meantime, I can carry on listening to God's words
|
||||
in the miraculous way he has already provided, not in private whispers but in
|
||||
the blinding clear public light of the testimony of the Bible and of the Church
|
||||
to Jesus Christ.
|
||||
|
||||
I still have unanswered questions about my future career. But my angst is gone.
|
||||
|
||||
My angst is gone because I see now I was asking the wrong questions. I wasn't
|
||||
really anxious about which career I ought to pursue. I perceived -- rightly --
|
||||
that I had been called to walk a narrow path in a life full of junctions. But
|
||||
this led me to think that for me, those junctions are mostly about my career
|
||||
choices. It followed that the career choices I faced had the power to lead me
|
||||
astray from God's way if I chose wrong. Without a map charting the way ahead,
|
||||
without a rule by which to determine which was God's way and which the wrong
|
||||
way, I feared that my career choices were a dangerous gamble. If I got it wrong,
|
||||
I wouldn't be a genuine follower of Christ, I wouldn't genuinely be trying to do
|
||||
what's right, and I wouldn't be fulfilling my God-given destiny.
|
||||
|
||||
What I didn't see was that I had re-worded the world's anxieties in God-speak.
|
||||
It sounded reassuringly pious, but it wasn't right. In fact, it was idolatry.
|
||||
|
||||
As I observed at the start of this essay, a large part of my generation of
|
||||
university graduates, Christian and non-Christian, share this angst. Most
|
||||
wouldn't word it in Christian-sounding God-speak. They might say they're worried
|
||||
about fulfilling their potential. But it's the same angst - the fear that if you
|
||||
don't choose the right career, you won't be living life to the full, or you
|
||||
won't be making the most of your talents and passions, or you won't be genuinely
|
||||
doing what's right, but just following the rest of the world into a lukewarm
|
||||
career-ladder rat-race. I hadn't 'leveraged my theological resources' at all:
|
||||
I'd only leveraged my theological thesaurus.
|
||||
|
||||
I think the scales fell from my eyes when commentators brought me back to the
|
||||
New Testament's advice on work, which doesn't talk about career choices at all.
|
||||
Since Jesus calls all his followers to enter by the narrow gate (Matt 7:13-14),
|
||||
likewise, Paul urged the Ephesians to 'live a life worthy of the calling which
|
||||
you have received' while arguing that Christ has given different gifts of
|
||||
service to each of us, his workers (Eph 4:1, 7-13). But almost all of the people
|
||||
Jesus and Paul were addressing had very little control over what work they were
|
||||
doing. Indeed, almost all people in the world today have very little control
|
||||
over what work they do. The paralysis of choice that I face is also a rare
|
||||
privelege. But that means that, when Jesus calls his followers to enter by the
|
||||
narrow gate, and Paul urges Christians to use their gifts of service, they can't
|
||||
possibly be primarily talking about career choices: most of their audience
|
||||
didn't have careers and they didn't have choices. They just had work, and if
|
||||
they didn't carry on working, they wouldn't eat (2 Thess 3:10).
|
||||
|
||||
The narrow gate is not about choosing the right career in a world of options.
|
||||
The narrow gate is choosing to trust God in a world of temptation to worship
|
||||
anything else.
|
||||
|
||||
Nor does Paul encourage us to switch jobs until we find our God-provided perfect
|
||||
match of talents and passions to service. Indeed, some of his most powerful
|
||||
encouragement and advice to Christian workers is addressed to people who had
|
||||
almost no control whatsoever over what work they did: slaves (eg Eph 6:5-8). In
|
||||
two areas where people did have some limited control, namely, circumcision and
|
||||
marriage, Paul advises the Corinthians that 'each person should remain in the
|
||||
situation they were in when God called them' (1 Cor 17:24).
|
||||
|
||||
So God's will for me in my situation is the same as it is for everyone else: to
|
||||
come back to our father when he calls. In practice, accepting the good news of
|
||||
Jesus Christ means continually confessing my sin and repenting of it. And that
|
||||
means being turned inside out: no longer turned in on myself by sin, but turned
|
||||
outside onto God my father and onto my neighbour in love.
|
||||
|
||||
Nor is there any need for angst, because this is the good news: that we have all
|
||||
already failed to fulfil our God-given purpose, which is to love God and one
|
||||
another. If we felt angst, it was justified, and indeed the situation was far
|
||||
worse than we feared. But despite that, Jesus Christ has made a way for us to be
|
||||
acceptable, and if we trust in him, we are permanently secure; free from fear,
|
||||
and free to turn back, however faltingly, to the way we were made to be.
|
||||
|
||||
For me, this has changed how I think about my career choices.
|
||||
|
||||
I've come to see that my career choices are a rare privelege, and something I
|
||||
should thank God for. It's also a responsibility to take seriously, as it's an
|
||||
opportunity to choose between service and self-service.
|
||||
|
||||
I shouldn't choose a career just because it's easy, and I should seek out
|
||||
careers with opportunities to serve, and commit to using the opportunities I
|
||||
have in whatever work I'm doing to serve. I shouldn't choose a career just
|
||||
because it fits my university-educated, middle-class prejudices about what work
|
||||
is dignified and what isn't; what kind of job counts as a 'proper job' and what
|
||||
is 'dead-end'.
|
||||
|
||||
I also shouldn't choose a career just because it's perceived as 'noble'. The
|
||||
world needs carers, teachers and preachers. It also needs principled, committed,
|
||||
competent white-collar workers making sure that certain boring, technical,
|
||||
invisible systems work well. These systems make caring, teaching and preaching
|
||||
possible. Through my own experience, I've been humbled by brilliant people in
|
||||
front-line jobs doing amazing work, but I've also seen how important those
|
||||
tertiary systems are.
|
||||
|
||||
I also shouldn't dwell too long on my career choices, paralysed by an irrational
|
||||
angst that the value of my life hangs on making the right decision. I should
|
||||
remember that Jesus calls everyone alike, although most people don't have
|
||||
anywhere near as much power over their own career as I do. And I should remember
|
||||
that, as a result, God will use pretty much any line of work for his glory if I
|
||||
commit it to him.
|
||||
|
||||
So I shouldn't choose what's easy, nor what's perceived as noble, and nor should
|
||||
I be paralysed by choice. But what ought I do instead?
|
||||
|
||||
Instead, I should commit my work to God right now, starting from this morning. I
|
||||
don't have to wait until I find a perfect career, because I will never have a
|
||||
perfect career. God can use the line of work I'm already in for his glory, and
|
||||
if I don't believe that, I'm not just doubting myself, I'm doubting him. I
|
||||
should trust his power. And when I do have career choices, I should commit those
|
||||
to him too, not fretting endlessly as if one career is holy and another damned,
|
||||
but prioritising service to God and others over myself and trusting God with the
|
||||
rest.
|
||||
|
||||
Comfort, elitism and moralism are all forms of idolatry. I can toil endlessly
|
||||
pursuing any of them and never be satisfied. But instead, I can rest easy in the
|
||||
knowledge that my place in God's family is secure, and work hard knowing that
|
||||
whenever and wherever and however I make sacrifices for the good of others, God
|
||||
is working through me and by me, even though I fall far short of fulfilling my
|
||||
potential and my God-given purpose.
|
||||
|
||||
I haven't 'figured things out'. As it transpires, there wasn't anything to
|
||||
'figure out'. I was saddled with angst at a phantom problem, which my knowledge
|
||||
of the gospel should have told me did not exist. I cannot earn my worth on
|
||||
earth. But because of Christ, my value is secure. Because of that, I am free to
|
||||
work without snobbery, without shame and without angst for the sake of love and
|
||||
in the certain hope that in the end, by God's work, not mine, everything will be
|
||||
figured out.
|
||||
|
||||
[every-good-endeavour]:
|
||||
https://uk.10ofthose.com/product/9781444702606/every-good-endeavour-paperback
|
||||
[revolutionary-work]:
|
||||
https://uk.10ofthose.com/product/9781910587997/revolutionary-work-paperback
|
||||
@@ -1,415 +0,0 @@
|
||||
---
|
||||
title: Why Psalm 118 is the theme tune to Matthew's Gospel
|
||||
description: >-
|
||||
Partly inspired by what I misheard at Cornhill Summer School 2025.
|
||||
pubDate: 2025-06-26
|
||||
---
|
||||
|
||||
[Psalm 118][ps-118] is one of the best-loved hits in the Hebrews' ancient
|
||||
songbook, the Psalms, and also one of the most re-interpreted.
|
||||
|
||||
It has been heavily used in both Jewish and Christian liturgy since ancient
|
||||
times. It is heavily referenced in the Rabbinical literature. Depending how
|
||||
generous you are with what counts as an 'allusion', you can count between twenty
|
||||
and sixty quotes and allusions to Psalm 118 in the New Testament. It has been
|
||||
frequently set and re-set to music, memorised, sung, interpreted and
|
||||
re-interpreted.
|
||||
|
||||
But why should we care about an old song and its ensemble of interpretations? At
|
||||
least part of the answer that its long history of usage includes another
|
||||
Biblical text which urgently appeals to us today: the Gospel of Matthew.
|
||||
|
||||
If we can understand why Matthew referred to Psalm 118, not once, not twice, but
|
||||
five times, all in the space of five chapters, we might understand a little
|
||||
better the story that Matthew wants to tell us.
|
||||
|
||||
To understand why it's so important for Matthew, first, let's get on the same
|
||||
page on what the psalm actually says.
|
||||
|
||||
## A story in four characters
|
||||
|
||||
The psalm features four characters: a hero, a congregation, some enemies, and
|
||||
the Lord.
|
||||
|
||||
<block-comment class="not-grid-content">
|
||||
The hero narrates the psalm's central block, from verse 5 to verse 21. He is a
|
||||
warrior hero: he 'cuts off' his enemies. He is nearly defeated, but is
|
||||
eventually victorious, and ascribes his victory to the Lord. He then approaches
|
||||
the 'gates through which the righteous shall enter', and appeals to go through
|
||||
so that he can praise the Lord there.
|
||||
|
||||
<blockquote class="verse verse--hanging-indents para-spacing-tight">
|
||||
<p>
|
||||
<span>When hard pressed, I cried to the Lord;</span>
|
||||
<span>he brought me into a spacious place.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>The Lord is with me; I will not be afraid.</span>
|
||||
<span>What can mere mortals do to me?</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>The Lord is with me; he is my helper.</span>
|
||||
<span>I look in triumph on my enemies.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>It is better to take refuge in the Lord</span>
|
||||
<span>than to trust in humans.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>It is better to take refuge in the Lord</span>
|
||||
<span>than to trust in princes.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>All the nations surrounded me,</span>
|
||||
<span>but in the name of the Lord I cut them down.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>They surrounded me on every side,</span>
|
||||
<span>but in the name of the Lord I cut them down.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>They swarmed around me like bees,</span>
|
||||
<span>but they were consumed as quickly as burning thorns;</span>
|
||||
<span>in the name of the Lord I cut them down.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>I was pushed back and about to fall,</span>
|
||||
<span>but the Lord helped me.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>The Lord is my strength and my defense;</span>
|
||||
<span>he has become my salvation.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>Shouts of joy and victory</span>
|
||||
<span>resound in the tents of the righteous:</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>“The Lord’s right hand has done mighty things!</span>
|
||||
<span>The Lord’s right hand is lifted high;</span>
|
||||
<span>the Lord’s right hand has done mighty things!”</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>I will not die but live,</span>
|
||||
<span>and will proclaim what the Lord has done.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>The Lord has chastened me severely,</span>
|
||||
<span>but he has not given me over to death.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>Open for me the gates of the righteous;</span>
|
||||
<span>I will enter and give thanks to the Lord.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>This is the gate of the Lord</span>
|
||||
<span>through which the righteous may enter.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>I will give you thanks, for you answered me;</span>
|
||||
<span>you have become my salvation.</span>
|
||||
</p>
|
||||
</blockquote>
|
||||
</block-comment>
|
||||
|
||||
<block-comment class="not-grid-content">
|
||||
Having heard the hero's account, the final section is dominated by the
|
||||
congregation. They thank the Lord for his saving work, which they describe thus:
|
||||
'the stone the builders rejected has become the chief cornerstone.' This implies
|
||||
that the hero had initially faced rejection, before being vindicated. The people
|
||||
show their praise by bringing a sacrifice bound with branches up to the altar,
|
||||
and finally the psalm is book-ended by repetition of the opening motif: 'give
|
||||
thanks to the Lord, for he is good, for his mercy endures forever!'
|
||||
|
||||
<blockquote class="verse verse--hanging-indents para-spacing-tight">
|
||||
<p>
|
||||
<span>The stone the builders rejected</span>
|
||||
<span>has become the cornerstone;</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>the Lord has done this,</span>
|
||||
<span>and it is marvelous in our eyes.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>The Lord has done it this very day;</span>
|
||||
<span>let us rejoice today and be glad.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>Lord, save us!</span>
|
||||
<span>Lord, grant us success!</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>Blessed is he who comes in the name of the Lord.</span>
|
||||
<span>From the house of the Lord we bless you.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>The Lord is God,</span>
|
||||
<span>and he has made his light shine on us.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>With boughs in hand, join in the festal procession</span>
|
||||
<span>up to the horns of the altar.</span>
|
||||
</p>
|
||||
</blockquote>
|
||||
</block-comment>
|
||||
|
||||
There is potentially a fifth character, the 'builders' who rejected the stone.
|
||||
Interpreters often identify these 'builders' either with the enemies or with the
|
||||
congregation, though not always. The text doesn't say.
|
||||
|
||||
Apart from the Lord, none of these four (or five) characters are named in the
|
||||
text.
|
||||
|
||||
This is where the intrigue lies: who are these characters? Who are the enemies?
|
||||
Who is the congregation? And who is this embattled hero, this 'stone the
|
||||
builders rejected' which has become 'the chief cornerstone'?
|
||||
|
||||
If I were to enumerate all the solutions that have been proposed to this puzzle,
|
||||
reading this essay would give you piles. But in order to understand some of the
|
||||
context in which Matthew was writing, permit me briefly to introduce two of the
|
||||
most popular Jewish interpretations.
|
||||
|
||||
## Moses
|
||||
|
||||
The first is Moses. Psalm 118 lays on thick the references to the Song of the
|
||||
Sea in Ex 15.
|
||||
|
||||
<block-comment class="not-grid-content">
|
||||
The central line, 'the Lord is my strength and song, he has become my
|
||||
salvation!' is a direct quote from Ex 15:2. Like Ex 15, the psalm uses the
|
||||
divine name frequently. Not only that, but the psalm, like Ex 15, prefers the
|
||||
relatively unusual form YH rather than the more common YHWH. The psalm echoes Ex
|
||||
15 also in its references to the right hand of the Lord doing mighty things, his
|
||||
chosen hero being hard-pressed by foreign nations and enjoying the Lord's
|
||||
'salvation', and by the hero's response, 'praising' and 'exalting' the Lord.
|
||||
|
||||
<blockquote class="verse verse--hanging-indents para-spacing-tight">
|
||||
<p>
|
||||
<span>The Lord is my strength and my defense;</span>
|
||||
<span>he has become my salvation.</span>
|
||||
<span class="not-hanging">He is my God, and I will praise him,</span>
|
||||
<span>my father’s God, and I will exalt him.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>The Lord is a warrior;</span>
|
||||
<span>the Lord is his name.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>Pharaoh’s chariots and his army</span>
|
||||
<span>he has hurled into the sea.</span>
|
||||
<span class="not-hanging">The best of Pharaoh’s officers</span>
|
||||
<span>are drowned in the Red Sea.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>The deep waters have covered them;</span>
|
||||
<span>they sank to the depths like a stone.</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>Your right hand, Lord,</span>
|
||||
<span>was majestic in power.</span>
|
||||
<span class="not-hanging">Your right hand, Lord,</span>
|
||||
<span>shattered the enemy.</span>
|
||||
</p>
|
||||
</blockquote>
|
||||
</block-comment>
|
||||
|
||||
In short, the psalm is absolutely reeking with references to the Song of the
|
||||
Sea, Moses' classic number-1 hit. No ancient Jew, for whom the psalm was
|
||||
originally written, could have failed to smell it.
|
||||
|
||||
The Midrash Tehillim, a Jewish commentary on the psalter composed in the early
|
||||
medieval period, even ascribes the psalm to Moses, claiming that he sang it on
|
||||
the first Pesach (Passover). Certainly, the psalm has featured heavily in Jewish
|
||||
celebrations of both Pesach and Sukkoth (another exodus-inspired festival) since
|
||||
ancient times.
|
||||
|
||||
However, perhaps surprisingly, Moses is not the most common Jewish reading of
|
||||
the hero of Psalm 118. That accolade goes to the next great hero of the Hebrew
|
||||
Scriptures: David.
|
||||
|
||||
## David
|
||||
|
||||
Although, unlike many other psalms, this one is not explicitly described as
|
||||
being 'of David', very many Jewish interpreters associate this psalm with that
|
||||
improbable king. For instance, the Targum -- an Aramaic paraphrase and
|
||||
commentary on the Hebrew Scriptures -- explicitly reads David, Samuel and Saul
|
||||
into the psalm. David has also been a favourite reading of some Christian
|
||||
readers, including John Calvin.
|
||||
|
||||
Why is this? One reason might be the psalm's context in the psalter. The psalter
|
||||
is divided into five books, and contemporary scholars theorise that in the
|
||||
second Temple period, editors arranged these five books thematically.
|
||||
|
||||
Books I and II tell how God had a covenant with David, and Book III laments that
|
||||
the covenant with David has failed, perhaps because David failed to keep the
|
||||
commands of the Torah. The task of Books IV and V is to show that God will
|
||||
restore his Davidic kingdom and fulfil his promises.
|
||||
|
||||
Psalm 118 sits in this final block, as the last psalm of Book IV. This suggests
|
||||
we should expect David, or a type of David, to feature: a returning king, coming
|
||||
back to fulfil his destiny to rule as an intermediary between God and his
|
||||
people. (Presumably, this time, he's got to be a true keeper of the Torah in
|
||||
order for this to work.)
|
||||
|
||||
Notice that a Davidic interpretation is inherently implicitly also a Messianic
|
||||
interpretation. David is dead. God promised that he would establish an
|
||||
everlasting throne in Jerusalem, where a human mediator would rule on his
|
||||
behalf, and God and his people could live together in peace forever. David, for
|
||||
all his merits, has conspicuously failed to deliver on this promise. So, if this
|
||||
psalm looks back to David, it must also look forward to the one who will fulfil
|
||||
God's promises to David.
|
||||
|
||||
So in this traditional Davidic interpretation, it's understood that God is going
|
||||
to choose someone who will re-establish that Davidic throne, and this time it's
|
||||
going to really work. Which means this time, it's going to be really different.
|
||||
|
||||
## Jesus
|
||||
|
||||
On the face of it, the New Testament authors seem to have nothing to do with the
|
||||
traditional interpretations. Instead of Moses or David, they exclusively
|
||||
identify the hero of Psalm 118 with Jesus. What are they up to?
|
||||
|
||||
One reason the New Testament authors went ham for Psalm 118 is simply because it
|
||||
was well-known. I mentioned that it was used heavily at Pesach and Sukkoth. As a
|
||||
result, lots of Jews were very familiar with its ideas and its language. Many
|
||||
ordinary people would have memorised it.
|
||||
|
||||
But that in itself doesn't explain why the New Testament authors used it. They
|
||||
didn't refer to Scripture arbitrarily, but they subverted shared interpretations
|
||||
in order to tell a new story. The cleverest instance of this is in the Gospel of
|
||||
Matthew.
|
||||
|
||||
<block-comment class="not-grid-content">
|
||||
Matthew first gets his reader tuned in to Psalm 118 as Jesus enters Jerusalem on
|
||||
the back of a colt. Matthew quotes the crowds quoting Psalm 118, shouting
|
||||
'Hosanna to the son of David! Blessed is he who comes in the name of the Lord!'
|
||||
In case we missed the application, he pairs this with his own quotation from the
|
||||
prophecy of Zechariah: Jesus is the coming king who will fulfil God's promises.
|
||||
The crowd also wave him in with branches, typical of Sukkoth celebrations and a
|
||||
reference to Ps 118:27.
|
||||
|
||||
<blockquote>
|
||||
A very large crowd spread their cloaks on the road, while others cut branches from the trees and spread them on the road. The crowds that went ahead of him and those that followed shouted, 'Hosanna to the Son of David!' 'Blessed is he who comes in the name of the Lord!' 'Hosanna in the highest heaven!'
|
||||
</blockquote>
|
||||
</block-comment>
|
||||
|
||||
So now we know Jesus is the returning king, we're expecting his imminent victory
|
||||
over his enemies, right? That's what Psalm 118, and its traditional Mosaic and
|
||||
Davidic interpretations, suggests, and so it's clearly what Matthew wants us to
|
||||
think. But that's when things take a sudden turn.
|
||||
|
||||
<block-comment class="not-grid-content">
|
||||
Immediately after this, Jesus tells the Parable of the Tenants. He implies that
|
||||
the well-educated, respectable religious leaders are complicit in murder and
|
||||
enemies of God. It's a shocking teaching, and it doesn't go down well. Perplexingly,
|
||||
Jesus quotes Psalm 118 again in the midst of this teaching.
|
||||
|
||||
<blockquote>
|
||||
Jesus said to them, 'Have you never read in the Scriptures:
|
||||
|
||||
<p class="verse verse--hanging-indents">
|
||||
<span>"The stone the builders rejected</span>
|
||||
<span>has become the cornerstone;</span>
|
||||
<span class="not-hanging">the Lord has done this,</span>
|
||||
<span>and it is marvelous in our eyes"?</span>
|
||||
</p>
|
||||
|
||||
'Therefore I tell you that the kingdom of God will be taken away from you
|
||||
and given to a people who will produce its fruit. Anyone who falls on this
|
||||
stone will be broken to pieces; anyone on whom it falls will be crushed.'
|
||||
</blockquote>
|
||||
</block-comment>
|
||||
|
||||
Matthew depicts Jesus continuing to teach in the Temple while sparring with the
|
||||
religious elites. Jesus caps off what was already a dreadful day by declaring
|
||||
seven devastating woes on the religious leaders. As he finally exits the Temple,
|
||||
he leaves another ominous quote from Psalm 118 hanging in the air: 'For I tell
|
||||
you, you will not see me again until you say, Blessed is he who comes in the
|
||||
name of the Lord.'
|
||||
|
||||
This doesn't make sense at all. According to the Psalm 118 storyline, we were
|
||||
supposed to be seeing Jesus cutting down his enemies and arriving at the Temple
|
||||
to celebrate with God's people. But now he's doing the opposite: he's cutting
|
||||
down God's people and then leaving the Temple mired in controversy.
|
||||
|
||||
Jesus then, after taking a private seminar for his disciples, invites them to
|
||||
what he knew would be his last supper. Matthew shows the reader how Judas had
|
||||
already betrayed Jesus behind his back. And yet, Matthew doesn't let up. He
|
||||
points out that they are celebrating their Pesach meal, and at the end, he
|
||||
points out that they finished with a hymn.
|
||||
|
||||
Why these apparently irrelevant details? He's begging you to put two and two
|
||||
together. His Jewish readers would have immediately clocked that the hymn in
|
||||
question was Psalm 118, ritually sung at the end of the Pesach meal.
|
||||
|
||||
So even at the very moment Jesus' total defeat in shame and misery is sealed,
|
||||
they're still singing this song about a victorious returning king, coming to
|
||||
re-establish David's throne forever?
|
||||
|
||||
The point that Matthew wants us to clock is the point Jesus made to the
|
||||
religious leaders in the Parable of the Tenants: 'the stone the builders
|
||||
rejected has become the chief cornerstone.' He really is the perfect Moses and
|
||||
the perfect David that God has promised. But before his great victory, he needs
|
||||
a great rejection. The surprise is that neither Jesus' rejection nor his victory
|
||||
look anything like what anyone expected.
|
||||
|
||||
Rather than being hard-pressed by foreign nations and defeating them in battle,
|
||||
Jesus is oppressed by his own people, the Jews. (We should understand this in
|
||||
the context that Matthew's Gospel was written primarily for an audience of Jews,
|
||||
hence why he expects them to pick up on all the references to Psalm 118.)
|
||||
|
||||
But this oppression is only the surface layer: his real fight was his fight with
|
||||
the spiritual powers of sin and death. By going to the cross, he consented to be
|
||||
hard-pressed.
|
||||
|
||||
And his Resurrection is his victory. Through it, he shows that he has defeated
|
||||
death. Now he is ascended to the right hand of the Father, where he rules as the
|
||||
perfect David, as the one who could both act as a human intermediary between God
|
||||
and humanity, and as one who could truly keep God's law. He is also the perfect
|
||||
Moses, who, by God's power, led his people out of captivity to sin and death in
|
||||
order to worship God. The old covenants are broken, but God has remained
|
||||
faithful and delivered on them anyway, and in doing so has created a new people,
|
||||
the Church, who will enter the gates of righteousness because Jesus has opened
|
||||
the way.
|
||||
|
||||
For a contemporary Jewish reader of Matthew's Gospel, the references to Psalm
|
||||
118 would automatically have conjured all the associations with Moses and David,
|
||||
and as a result, all the Messianic secondary meanings, that he needed to make
|
||||
his point. He could have expected his original readers to join the dots.
|
||||
|
||||
For a contemporary reader, particularly one like me that didn't get an
|
||||
old-fashioned Biblical education, it might take a bit more work to spot the
|
||||
links. But isn't it worth it? This psalm helps us to understand the message of
|
||||
Matthew's Gospel: Jesus fulfils God's promises in a way that nobody expected.
|
||||
|
||||
## Conclusion
|
||||
|
||||
As I've discovered, Matthew's way is far from the only way of reading Psalm 118.
|
||||
That's to be expected: as I noted at the start, none of the characters apart
|
||||
from the Lord are named in the text. It's up to us as readers to impose
|
||||
allegories onto the text, if that is what we choose to do.
|
||||
|
||||
And that is what interpreters from ancient times have strove to do. Indeed,
|
||||
Matthew didn't ignore or overwrite previous interpretations: he used Psalm 118
|
||||
precisely because he knew that if he put Jesus into Psalm 118, his readers would
|
||||
have made the link to Moses and David themselves. In order to get Matthew's
|
||||
subversive new reading, you've got to be fluent in the rich tradition of old
|
||||
readings.
|
||||
|
||||
Therefore I will keep reading. As I've encountered Psalm 118 recently, I've
|
||||
re-discovered how understanding one Biblical text can shed dramatic new light on
|
||||
another. If God is willing, perhaps this will help me to see him once again in
|
||||
sharp relief.
|
||||
|
||||
## Further reading
|
||||
|
||||
- [Calvin's commentary on Psalm 118](https://biblehub.com/commentaries/calvin/psalms/118.htm)
|
||||
- [Cook, EM. 2001. Targum Tehillim: An English Translation. Book V](http://targum.info/pss/ps5.htm)
|
||||
- [Vaillancourt, IJ. 2019. Psalm 118 and the eschatological son of David. JETS 62(4) pp 721-738](https://etsjets.org/wp-content/uploads/2020/01/files_JETS-PDFs_62_62-4_JETS_62.4_721-738_Vaillancourt.pdf)
|
||||
- [Gillingham 2020. ‘Das schöne Confitemini’: engaging with Erich Zenger’s reading of Psalm 118 from a Jewish and Christian reception history perspective. In: 'By my God I can leap over a wall': Interreligious Horizons in Psalms and Psalms Studies](https://ora.ox.ac.uk/objects/uuid:1dff6f67-3c9e-41a8-a691-90e1e260fcdd)
|
||||
- [Botha PJ 2003. Psalm 118 and social values in Ancient Israel. OTE 16(2) pp 195-215](https://www.researchgate.net/publication/237449388_Psalm_118_and_social_values_in_Ancient_Israel)
|
||||
|
||||
I was inspired to write this essay by the teaching on Psalm 118 at Cornhill
|
||||
Summer School 2025.
|
||||
|
||||
[ps-118]: https://www.biblegateway.com/passage/?search=Psalm%20118
|
||||
@@ -1,88 +0,0 @@
|
||||
---
|
||||
title: Changing my ambitions
|
||||
description: >-
|
||||
When I started my first degree, I had unrealistic and unhelpful ambitions. For
|
||||
my second degree, I'm setting my sights on different targets.
|
||||
pubDate: 2025-09-18
|
||||
---
|
||||
|
||||
Is 'virtue' a terribly old-fashioned word? I don't mind either way. If I've run
|
||||
into you for more than three seconds in the last couple of weeks, you'll know
|
||||
that I've just started my second degree, and I'm very happy about it. I'm having
|
||||
a great deal of fun, and expect my studies to continue to be fun. But fun is not
|
||||
my goal. My goal is virtue.
|
||||
|
||||
In particular, the virtues I'm striving after in my degree are a greater ability
|
||||
to ask questions well, and to answer them well; to write well, and to dispute --
|
||||
that is, speak with, listen, reason, discuss -- well. Insightfully, sensitively,
|
||||
humanely, intelligently, informedly, fluently: well.
|
||||
|
||||
But what about all the starving children! I hear you cry. In the past, I myself
|
||||
have got myself stuck fearing that doing another degree would be ignoring some
|
||||
more immediate duty to do something about all the evil in the world. So, is my
|
||||
degree selfish? Or how can it not be? How can this be good?
|
||||
|
||||
I believe it's precisely by abandoning that restrictive sense of public duty
|
||||
which has freed me at last to do something good. Let me explain.
|
||||
|
||||
During my first degree, I had a great deal of ambition. I was genuinely
|
||||
convinced that I could find robust answers to big questions if I thought about
|
||||
them hard enough. I thought I was clever enough to make progress, or at least
|
||||
contribute. I thought I could, if I wanted to, get into a PhD programme and end
|
||||
up employed as Dean of Philosophy of Oxford, paid to smoke from a pipe all day
|
||||
in a tweed jacket with leather patches while quietly resolving all the world's
|
||||
burning intellectual issues.
|
||||
|
||||
What's changed? If I were a pessimist, I might mention my encounter with that
|
||||
devil, reality. It turns out that I'm not actually the cleverest person in the
|
||||
room, that the biggest philosophical problems are pretty intractable, and that I
|
||||
can't get into Oxford -- and even if I could, it wouldn't necessarily be right
|
||||
to uproot myself from my friends, family and church community to pursue my dream
|
||||
career.
|
||||
|
||||
All this did matter a great deal. It's what slowly convinced me to finally drop
|
||||
those unrealistic philosophical ambitions. It's why, a year and a half ago, I
|
||||
turned down the offer of a Master's in Philosophy at a excellent university
|
||||
(albeit not Oxford).
|
||||
|
||||
But that's not the whole story. I'm not sat here with a sob story of broken
|
||||
dreams. After I turned down that PhD, I didn't feel deflated, I felt liberated.
|
||||
I haven't just dropped those ambitions, I've found new ones.
|
||||
|
||||
My friends, family and church community ought to matter far more to me, I
|
||||
realised, than my career. So, turning away from academia, I turned towards love.
|
||||
|
||||
This is what the gospel does. It's the most good story, beautifully true, which
|
||||
says to the human heart: since God so loved us, so also we ought to love one
|
||||
another.
|
||||
|
||||
When I'm targeting virtue, I find it helpful to imagine a character who displays
|
||||
the virtues I'm after. So picture Helpful John. He's an encouragement. Whenever
|
||||
you talk to Helpful John, you come away feeling emotionally mature and
|
||||
intellectually confident, because his overwhelming respect wipes away your
|
||||
anxiety. He listens to you carefully, and insists on understanding you at more
|
||||
than a superficial level. When it's appropriate to do so, he can ask devious
|
||||
questions which unlock new possibilities you hadn't considered before. He knows
|
||||
lots of relevant and often surprising facts. He can compare your perspective
|
||||
with that of strange and subversive alternative perspectives. He doesn't like to
|
||||
tell people what to think, but when he speaks or when he writes, you pay
|
||||
attention, because you know he is capable of profound insight.
|
||||
|
||||
Helpful John sounds great. A model to replicate, right? Not in every respect,
|
||||
necessarily. Helpful John might not be the life and soul of the party. He might
|
||||
not be the first person you go to for comfort in times of trouble. He might not
|
||||
be the most reliable person in the world, or the best with children, or the best
|
||||
with hand tools. Helpful John is a character, but he doesn't have to be good at
|
||||
everything.
|
||||
|
||||
Helpful John is roughly my north star. I don't expect to become Helpful John.
|
||||
But with the Spirit's help, with me continuing to lean in to the process, I do
|
||||
intend for Useless Joe to become more like Helpful John in his most enviable
|
||||
respects.
|
||||
|
||||
Is this selfish? Is this a shortage of ambition? Wouldn't you love to have a
|
||||
Helpful John as a friend? A brother? Across the table at small group at church?
|
||||
In your workplace?
|
||||
|
||||
So forgive me if I'm old-fashioned: I believe virtue is a virtue. A better world
|
||||
is one full of better people.
|
||||
@@ -1,125 +0,0 @@
|
||||
---
|
||||
title: Why the creeds matter
|
||||
hidden: true
|
||||
description: >-
|
||||
Plenty of Christians don't think the creeds are important for their faith.
|
||||
Plenty others take the creeds for granted. But Christians ought to appreciate
|
||||
that the creeds are a sophisticated, profound and essential foundation of the
|
||||
church.
|
||||
pubDate: 2025-09-24
|
||||
---
|
||||
|
||||
<blockquote>
|
||||
But you, man of God, flee from all this, and pursue righteousness, godliness,
|
||||
faith, love, endurance and gentleness. Fight the good fight of the faith. Take
|
||||
hold of the eternal life to which you were called when you made your good
|
||||
confession in the presence of many witnesses.
|
||||
|
||||
<cite>1 Tim 6:12</cite>
|
||||
|
||||
</blockquote>
|
||||
|
||||
Since the earliest days of the church, Christians have confessed their faith.
|
||||
That is to say, we have declared what we believe to each other and to the world.
|
||||
For the vast majority of the world's Christians, this frequently takes the form
|
||||
of one of two fixed texts, respectively, the Apostle's Creed and the Nicene
|
||||
Creed. The Nicene Creed in particular unites almost all Christians worldwide,
|
||||
including the Greek Orthodox and Roman Catholic denominations and almost all
|
||||
Protestant denominations. Despite celebrating its 1700th anniversary this year,
|
||||
and despite all the ways in which the global church is sadly divided, the Nicene
|
||||
Creed stands as a symbol of Christian unity and a faithful summary of what
|
||||
Christians believe.
|
||||
|
||||
Yet not all Christians fully appreciate their creeds.
|
||||
|
||||
Perhaps you're familiar with the creeds from your church's form of worship, or
|
||||
maybe you've heard it used at baptisms. You might have even confessed one
|
||||
yourself at your own baptism. But if you've never given it much thought, you
|
||||
might have assumed the creeds are simply neutral summaries of Christian belief,
|
||||
abstracted out of any historical context. You might think it dates to a
|
||||
primitive time in the Church's history, before the Church went through the
|
||||
refining fire of advanced theology.
|
||||
|
||||
In fact, in the fourth century, when the text of the Nicene Creed and the
|
||||
ancestor of what became the Apostle's Creed was fixed, the creeds were
|
||||
formulated in response to some very particular challenges of that time. They do
|
||||
not represent primitive Christianity, but on the contrary, they exist in the way
|
||||
they do precisely because of the need for exact, exclusive theology.
|
||||
|
||||
In the fourth century, the Church was straining within itself to understand what
|
||||
the revelation of Jesus Christ revealed about God and his purposes.
|
||||
|
||||
For an earlier generation, the main threat had been that Christians might adopt
|
||||
ideas from the gnostics, a mystical religious community which probably formed
|
||||
about the time of Christ. In some respects, gnostic ideas cohered nicely with
|
||||
the revelation of Jesus. But the fusion of gnostic ideas with Christianity also
|
||||
meant mutilating the New Testament and ditching the Old altogether. It meant
|
||||
giving up on the idea of a God who cared for his people and was willing to die
|
||||
to save us. It meant dividing the world into people who were by nature
|
||||
spiritual, and those destined for death. And it meant giving up on the hope that
|
||||
the world might be redeemed, settling instead for a future where those lucky
|
||||
enough to have the magic spark within their souls could escape the world and
|
||||
leave it for dust.
|
||||
|
||||
The first generations of Christian theologians fought to steer the church away
|
||||
from these harmful ideas, including Irenaeus, Justin Martyr and Origen. In so
|
||||
doing, they made a huge contribution to the fundamentals of our faith.
|
||||
|
||||
We can see the influence of this battle in the creeds. For example, the first
|
||||
article of the Nicene Creed asserts that God the Father created the heavens and
|
||||
the earth. This corrected the gnostic notion that a truly good God would never
|
||||
have anything to do with something so rotten as creation. Instead, the creed
|
||||
reminds us that God made the world good, that despite its fallen state, it still
|
||||
bears his likeness, and through his unfolding plan, he intends to make it
|
||||
perfect.
|
||||
|
||||
By the fourth century, the main controversy was over the ideas of an Alexandrian
|
||||
Christian teacher called Arius. He claimed that Jesus Christ, the Son of God,
|
||||
was not truly divine, nor an eternal Person of the Triune God, but rather a
|
||||
created being.
|
||||
|
||||
This might sound like a technical issue, but the consequences are massive. If
|
||||
Jesus is not God, then he has no power to save us. The Christian hope is that
|
||||
God came down to bring his life to a dead world. But if he isn't truly God, but
|
||||
a lesser being, not much more than an angel, then he doesn't possess God's life,
|
||||
so he can't do any of that.
|
||||
|
||||
The Nicene Creed was formulated to try and specify exactly what was wrong with
|
||||
this view. Thus we get the assertion that Jesus Christ, the Son of God, is of
|
||||
one substance with the Father, light of light, very God of very God, who for our
|
||||
sake and for our salvation was incarnate by the Holy Ghost of the Virgin Mary,
|
||||
and was made man.
|
||||
|
||||
But maybe none of this is new to you, and perhaps all this chat about heresy is
|
||||
summing up for you exactly why you aren't into the creeds. If it's just a tool
|
||||
for manhandling fourth-century heretics, then why should I care about it today?
|
||||
|
||||
Well, I could point out how the same heresies have repeatedly re-occurred
|
||||
throughout church history, including the present -- but instead, I'll highlight
|
||||
that the creeds are not in fact just a stick for bashing heretics with. Some
|
||||
words are surgically inserted to force Arius to make a choice, yes. But that's
|
||||
not the whole story.
|
||||
|
||||
Large parts of the Nicene Creed were not up for discussion at the Councils which
|
||||
formed them. For example, nobody questioned the basic trinitarian form: 'We
|
||||
believe in God the Father ... and in Jesus Christ, the Son of God ... and in the
|
||||
Holy Spirit.' So something else has to be playing a huge role here.
|
||||
|
||||
Indeed, we have evidence that the trinitarian formula was one way that
|
||||
Christians had been confessing their faith at their baptism since the early
|
||||
second century. By the time of the Nicene Creed, it was probably dominant. So
|
||||
the Nicene Creed isn't just a list of things Arius can't say: the bulk of it
|
||||
comes from an existing tradition built up within the church from its earliest
|
||||
days, for Christians to affirm to other Christians the basics of what we
|
||||
believe.
|
||||
|
||||
Furthermore, the creeds are far from unimportant. Even if you're not part of one
|
||||
of those denominations, representing an overwhelming majority of global
|
||||
Christians, which use the creeds to aid their worship, the creeds should matter
|
||||
to you. They are formed in large part from material from the New Testament. They
|
||||
represent apostolic and catholic teaching. And they remain the best symbol of
|
||||
what Christians believe both within the church, and to the world outside the
|
||||
church.
|
||||
|
||||
As for me, I'm trying to memorise the Nicene Creed. If you don't know it
|
||||
already, I'd recommend you do, too!
|
||||
@@ -1,415 +0,0 @@
|
||||
---
|
||||
title: "381: how the church as we know it was made"
|
||||
description: >-
|
||||
The church which defines our world now is in a significant way the one which
|
||||
emerged out of sixty years of controversy from the Council of Constantinople
|
||||
in 381. I've been charting what happened, why, and the ongoing legacy.
|
||||
pubDate: 2025-10-05
|
||||
---
|
||||
|
||||
Athanasius defined the fourth century. Not that he was a god, or even a king, or
|
||||
that he always got his way. But he wrote the history books. His tale of an epic
|
||||
battle fought tooth-and-nail between Arian heretics and him and his loyal allies
|
||||
has come to be the standard account of how, over the course of the fourth
|
||||
century, the Church redefined what orthodoxy means and how it is declared and
|
||||
identified.
|
||||
|
||||
The result was the Nicene Creed. It had been first written for a very particular
|
||||
polemical purpose in 325, but later found itself the centre of a strange
|
||||
theological revival, and was finally revised in a council at Constantinople
|
||||
in 381. In so doing, the bishops assembled a recognisable 'Nicene' tradition
|
||||
which is still one of the defining features of planet Earth.
|
||||
|
||||
For better and for worse, the church as we know it has a capacity both for great
|
||||
humility, faith and submission to the mystery of God, but it also has a capacity
|
||||
for great intolerance. This is the church created in 381.
|
||||
|
||||
To understand the church as we know it today, then, we need to understand the
|
||||
complex, confusing journey from 325 to 381.
|
||||
|
||||
Athanasius' chronicle of that journey is temptingly simple. The only problem
|
||||
with it is that it isn't true. Indeed, his 'history' was never meant to function
|
||||
as an all-encompassing narrative of Church history, to be read for centuries
|
||||
ever after. His accounts function as polemics, meant to cajole, condemn and
|
||||
persuade his readers in his own time of his vision for their future.
|
||||
|
||||
Nevertheless, whatever Athanasius' real significance in how his times unfolded,
|
||||
his witness is important. He fully inhabited his times, often in the middle of
|
||||
the fray. Whether or not we buy Athanasius' portrayal of himself as fighting the
|
||||
good fight, he was certainly a fighter. By looking through his eyes, then, we
|
||||
can get a perspective on how the Church as we know it came to be.
|
||||
|
||||
So it makes sense to start with him. As a young priest in his native Alexandria,
|
||||
he became tangled up in a controversy which would come to define his career. A
|
||||
strong-minded and fearless young priest had begun to preach. His name was Arius.
|
||||
|
||||
---
|
||||
|
||||
According to the Egyptian tradition, Alexander, the bishop of Alexandria, was
|
||||
the nineteenth in a direct line of succession from Mark the Evangelist himself.
|
||||
With a great deal of justice, he would have regarded himself as one of the most
|
||||
important Christian leaders in the world, and at least the equal of the bishop
|
||||
of Rome.
|
||||
|
||||
Small wonder, then, that the insubordination that plagued his diocese bothered
|
||||
him. First Erescentius had started a schism, disputing the rule he used for
|
||||
calculating the date of Easter.
|
||||
|
||||
Then there was Meletius. During the persecution under the Roman emperor
|
||||
Diocletian, Meletius had already rubbed a few people the wrong way: while other
|
||||
bishops were in hiding or in prison, he took the initiative to resolve problems
|
||||
and ordain priests without properly consulting the absent bishops'
|
||||
representatives. Perhaps it was intended kindly: it was seen as meddling. Now
|
||||
Meletius accused Alexander of being too soft on Christians who had caved into
|
||||
the threat of torture and made sacrifices to the pagan cults. When he decided
|
||||
Alexander was never going to match his high rigorist standards, he broke away,
|
||||
too.
|
||||
|
||||
Alexander must have longed for the relatively good order of the Greek and Roman
|
||||
churches, where bickering subordinates were generally willing to let their
|
||||
bishop have the last say. The throne of St Mark was in trouble. If Christ's body
|
||||
wasn't to get chopped up any more than it already was, he needed to establish
|
||||
his personal authority.
|
||||
|
||||
This was the context in which Arius, a young firebrand priest, steps onto stage
|
||||
right. He surely knew his own bishop's teaching: God is one substance and one
|
||||
essence, unchangeable, indivisible. Christ his Son is in every way God: God from
|
||||
God, light from light, true God from true God, eternally begotten of the Father
|
||||
before all ages. How else could Christ, by adopting human flesh, mediate the
|
||||
transcendent God to fallen humanity?
|
||||
|
||||
But Arius didn't like this one bit. If God is unchangeable, how could he adopt
|
||||
flesh? That suggests he was not flesh, and then became flesh. And in any case,
|
||||
if the martyrs were right to give up their lives to know God, he must have the
|
||||
perfect, uncompromising transcendence which the martyrs so admired. But how can
|
||||
God adopt flesh, never mind suffer and die on a cross, without compromising that
|
||||
transcendence? Something had to give. For Arius, the solution was to modify the
|
||||
relationship between the Father and the Son.
|
||||
|
||||
Arius accepted that Christ had to be in some sense divine, in order to mediate
|
||||
God to humanity. But he denied that he was quite as much God as God is. He has
|
||||
something like his Father's essence, not in a co-equal way, but rather in a
|
||||
derivative way. This makes sense of Father-Son language, which suggests the
|
||||
Father came first, and the Son came next, a derivative of the Father. So the Son
|
||||
is God from God, but not true God from true God. The Son was begotten in time,
|
||||
and is not eternal: only God the Father himself is eternal.
|
||||
|
||||
At another time in another place, Arius might have passed for a creative,
|
||||
independent thinker without much notice. But Arius was directly contradicting
|
||||
Alexander just as the latter was desperate to assert his authority. It got ugly.
|
||||
|
||||
Alexander called a council of local bishops in about 320. The council condemned
|
||||
Arius and removed him from his post as priest. In response, Arius went on the
|
||||
campaign trail, visiting bishops in Palestine and Asia Minor who he thought
|
||||
would be sympathetic to his theology. Shortly afterwards, he returned to
|
||||
Alexandria, triumphantly brandishing vindications from two councils, one in
|
||||
Jerusalem and one in Bithynia. He wasn't going to make it easy for Alexander.
|
||||
|
||||
Luckily for Alexander, the Emperor Constantine had just united the eastern and
|
||||
western halves of the Empire. He had famously converted to Christianity after
|
||||
seeing the sign of the cross at the Battle of Milvian Bridge in 312, and saw the
|
||||
bishops as means towards his mission of uniting the Empire under one government
|
||||
and one God. Constantine had been made aware of the dispute between Arius and
|
||||
Alexander, and he didn't want schisms in the church any more than Alexander did.
|
||||
|
||||
He called a council in his own palace in Nicaea, paying the travel expenses and
|
||||
hotel bills of all the bishops in attendance. For those bishops, many carrying
|
||||
the scars of torture they had endured under Diocletian, it must have been a
|
||||
bewildering experience. Alexander was in attendance. His secretary was
|
||||
Athanasius.
|
||||
|
||||
In 325, the council condemned Arius. To avoid anyone else following in his path,
|
||||
they produced a statement of faith, designed to exclude Arius' teaching, no
|
||||
matter who taught it. This statement of faith is now known as the Nicene Creed.
|
||||
|
||||
The council also fixed the date of Easter to boot. Alexander must have been
|
||||
relieved.
|
||||
|
||||
You might have thought that would have been the end for Arius. In fact,
|
||||
Constantine engineered his re-admittance into the church as soon as 328. Arius
|
||||
died in peace in 336. Constantine's mission wasn't to purge the church, but to
|
||||
unite the church. As long as all sides worshipped God and could live in peace,
|
||||
he wanted as many people as possible included. His mission was unity, not
|
||||
uniformity.
|
||||
|
||||
Bishops like Eusebius of Caesarea in Syria got this. He had been provisionally
|
||||
excommunicated on suspicion of Arianism in 325, but was reconciled at Nicaea
|
||||
given the chance to explain himself and sign up to the Nicene Creed. No sooner
|
||||
had he done this, however, than he had started explaining to the faithful back
|
||||
home how they could carry on believing that the Son was not really eternal, even
|
||||
as the Creed was designed to exclude exactly such a claim. While Eusebius might
|
||||
seem duplicitous, at the time, this was exactly the kind of tolerant pragmatism
|
||||
that Constantine asked of the bishops: as long as they didn't cause more
|
||||
out-and-out conflict.
|
||||
|
||||
Alexander didn't have long to enjoy the peace of Nicaea. He died just a few
|
||||
years afterward in 328. The throne of St Mark passed to Athanasius.
|
||||
|
||||
---
|
||||
|
||||
The peace didn't last long. Just as Athanasius was donning his mitre, Eusebius
|
||||
was plotting against Eustathius the bishop of Antioch, and engineered his
|
||||
deposition. In his defence, Eusebius accused Eustathius of the long-condemned
|
||||
heresy, Sabellianism. Then in 335, he followed up by deposing Marcellus, the
|
||||
bishop of Ancyra, at a council in Tyre.
|
||||
|
||||
To defend his action, he wrote _Against Marcellus_, in which he accused
|
||||
Marcellus of being a Sabellian, too. Sabellius' heresy was (to borrow a modern
|
||||
term) modalism, the view that 'Father', 'Son' and 'Spirit' are mere titles,
|
||||
aspects, 'modes' of God, not in any real way distinct. He also accused Marcellus
|
||||
of adoptionism, another agreed heresy. Marcellus taught that the Son only became
|
||||
an aspect of the divine nature at the Incarnation, and that in the last day,
|
||||
Christ would hand over his kingdom to his Father.
|
||||
|
||||
This action would cast a long shadow over the next half-century. Time and again,
|
||||
bishops allied to Eusebius' way of thinking, or 'Eusebians', would re-affirm
|
||||
their opposition to that 'heretic' Marcellus and his 'Sabellianism'. This is a
|
||||
crucial dynamic for understanding where theological factions drew up their
|
||||
battle lines, and for what compromises were needed in order to get to 381.
|
||||
|
||||
Even the bishop of Alexandria wasn't immune from Eusebius' purge. Athanasius had
|
||||
vigorously defended his ally, Marcellus, at the council of Tyre in 335. Eusebius
|
||||
set about plotting his downfall. He dug up dirt. He accused Athanasius of using
|
||||
threats and bribes to get himself elected, and sending goons to beat up his
|
||||
political opponents. Once he'd found evidence of Athanasius meddling with the
|
||||
crucial Egyptian grain export that kept Rome fed, he had the emperor on side.
|
||||
Constantine convened a meeting in 336 and exiled him to the German frontier.
|
||||
|
||||
---
|
||||
|
||||
Or at least, that's how Athanasius tells it. Athanasius loves a plot: at the
|
||||
time, alleging a conspiracy was a classic rhetorical technique for painting your
|
||||
enemies as heretics.
|
||||
|
||||
Eusebius was no stranger to rhetoric himself, and it's to his 337 best-seller,
|
||||
the _Life of Constantine_, that we owe our standard account of Constantine's
|
||||
reign. He regarded Empire and Church as allies in a joint mission, to unite the
|
||||
world under one government and one faith. To him, someone like Athanasius,
|
||||
constitutionally incapable of tolerating anyone who disagreed with him and
|
||||
willing to use gangster tactics to get his way, was a threat to this divine
|
||||
mission.
|
||||
|
||||
It's worth remembering that after Constantine died, Athanasius would be
|
||||
re-exiled by four more Roman emperors. In his lifetime, only Julian failed to
|
||||
exile Athanasius, and him only perhaps because he didn't have time in his
|
||||
whirlwind twenty-month reign. We also can't be sure how much influence Eusebius
|
||||
actually had in the expulsion of Athanasius and his allies: it coheres well
|
||||
enough with the emperor's anti-sectarian agenda that it might have happened with
|
||||
or without Eusebius' involvement.
|
||||
|
||||
Perhaps Athanasius was a brute. Still, the Roman Catholic Church manages to
|
||||
venerate both Eusebius and Athanasius as saints. This may seem like a
|
||||
contradiction. But perhaps an ability to tolerate contradiction is precisely the
|
||||
legacy of 381.
|
||||
|
||||
But we're not there yet. By 335, Eusebius had engineered the exile of
|
||||
Eustathius, Marcellus, and Athanasius. After Constantine died, he had to do it
|
||||
all over again, but by 339, he had persuaded his successor, Constantius, to
|
||||
re-assert his father's exiles of the three men. With the Empire once again
|
||||
split, Athanasius and Marcellus headed to Rome to re-group and re-think.
|
||||
|
||||
---
|
||||
|
||||
From Rome, Athanasius and Marcellus were safe for now from Eusebius' clutches,
|
||||
but also relatively impotent. In this period of exile in the 340s, in an effort
|
||||
to claw back his reputation, Athanasius developed the polemic which still
|
||||
defines the standard history of the fourth century. He invented a cunning label
|
||||
for Eusebius and his cronies: he called them 'Arians'.
|
||||
|
||||
Eusebius rejected the label as ridiculous. Arius had been reconciled, and more
|
||||
to the point, had died in 336. For that matter, why would a bishop follow the
|
||||
teaching of a mere priest? Not only that, but the label ignored significant
|
||||
differences between Arius' and Eusebius' teaching. His verdict was clear: the
|
||||
label 'Arian' is a baseless slur, with no other purpose than to tar his
|
||||
reputation as a heretic.
|
||||
|
||||
He was right, of course. But like it or not, Athanasius' theory of an Arian
|
||||
conspiracy began to win adherents, not least Julian, the bishop of Rome. Julian
|
||||
called a council to exonerate Athanasius and Marcellus. When the Greeks refused
|
||||
to turn up, he called a local council anyway and vindicated the two men. In the
|
||||
face of Greek obstinacy, Julian wrote east, pleading the bishops to take the
|
||||
'Arian' threat seriously.
|
||||
|
||||
In response, the easterners held a council in Antioch in 341, agreeing four
|
||||
creeds which powerfully condemned Marcellus' teaching, including the influential
|
||||
Dedication Creed. This includes assertions that Father, Son and Spirit are
|
||||
'three in subsistence, one in agreement', that the Son was generated before time
|
||||
began, against Marcellus' teaching that the Father, Son and Spirit are aspects
|
||||
of God without division in subsistence, and that there only came to be a divine
|
||||
Son at his incarnation. They explicitly condemned Arius, Sabellius and
|
||||
Marcellus.
|
||||
|
||||
So the divisions grew deeper. Without an emperor to compel the bishops to come
|
||||
together, there may not have been much chance of a rapprochement. But even if
|
||||
there were to be such an emperor, who's to say that their settlement would have
|
||||
satisfied the bishops?
|
||||
|
||||
---
|
||||
|
||||
Meanwhile, in the 340s and through the 350s, two further theological movements
|
||||
gathered steam: the homoians and the heterousians.
|
||||
|
||||
The homoians, perhaps tired of the squabbles between the Athanasian and Eusebian
|
||||
factions, determined to sidestep their petty debates altogether.
|
||||
|
||||
A key term of the theological disagreement was 'essence' or 'ousia'. Athanasius,
|
||||
in his lifelong battle to make sure Arius stayed dead, insisted that Father, Son
|
||||
and Spirit shared the same ousia. In contrast, Eusebius, with his anti-Sabellian
|
||||
polemic, needed to assert the real distinction between Father, Son and Spirit,
|
||||
and so asserted that each had a separate ousia. So the difference can be summed
|
||||
up as a counting problem. How many divine ousias are there? One or three?
|
||||
|
||||
The homoians claimed that both sides were mistaken, simply because they used the
|
||||
word 'ousia'. There is no mention of ousia in Scripture, so, they claimed, we
|
||||
have no basis for asserting it of God one way or the other. All we can truly say
|
||||
is that Father, Son and Spirit are distinct but somehow alike. Whereof we cannot
|
||||
speak, there must we remain silent.
|
||||
|
||||
This might have worked as a way forward, except that the heterousians provoked
|
||||
such a strong reaction that 'ousia'-talk was needed to refute them. Aetius, and
|
||||
his followed Eunomius, argued that since God is simple, and all generate things
|
||||
are divided, it follows that God is ingenerate. But the Son is generate:
|
||||
therefore Father and Son must be altogether unalike. They expressed this by
|
||||
saying that Father and Son are unlike in ousia. This teaching was swiftly
|
||||
branded 'neo-Arian', provoking a strong reaction. To counter the heterousian
|
||||
teaching, their opponents were forced to fight on their terms, and that meant
|
||||
using 'ousia'-talk.
|
||||
|
||||
Thus enters Basil of Caesarea. He argued that if we abandon 'ousia'-talk, we
|
||||
will have no way of saying that the Father and Son have anything in common at
|
||||
all, which makes a nonsense of the idea that the Son brings humanity knowledge
|
||||
of his Father. Without like essence, they might as well be two completely
|
||||
different Gods. Therefore we have to say at least that they have like essence --
|
||||
'homoiousia'. But without direct access to perfect knowledge of the invisible
|
||||
God, we're not in a position to judge that they have exactly the same essence,
|
||||
so he stopped short of agreeing with the 'homoousia' of the Nicene Creed which
|
||||
Athanasius so treasured.
|
||||
|
||||
Seeing the opportunity to make common cause against the homoians, Athanasius
|
||||
started to soften. He wrote an extremely charitable commentary on Basil's
|
||||
theology which emphasised their similarities and papered over their differences.
|
||||
Athanasius recognised that both he and Basil wanted to assert the unity of God
|
||||
while still preserving distinctions between Father, Son and Spirit. The two
|
||||
began to campaign against the homoian movement.
|
||||
|
||||
But Basil got there too late. In 359, the emperor Constantine II called a
|
||||
council in Constantinople, and in 360 it issued a homoian creed with full
|
||||
imperial backing. Any campaign against the homoians would have to take place sub
|
||||
rosa.
|
||||
|
||||
---
|
||||
|
||||
In Athanasius' and Basil's long, slow campaign against homoianism, their weapon
|
||||
of choice was surprising: they dusted off the Nicene Creed of 325. Athanasius
|
||||
argued, against the homoians, that 'ousia'-talk, although not directly
|
||||
Scriptural, was essential in order to draw out the consequences of Scripture
|
||||
while ruling out Arian mis-interpretations.
|
||||
|
||||
Thus Nicaea, conceived as a one-off meant to clean up the Arian controversy,
|
||||
found a new life as the anti-homoian movement -- or perhaps you could call it
|
||||
the Nicene revival? -- rallied around it.
|
||||
|
||||
As the movement progressed, the formerly disagreeing bishops found ways to come
|
||||
together. An essential move was that made in Athanasius' _Antiochene Tome_
|
||||
of 362. In it, he relented on his long opposition to there being three
|
||||
'hypostases' or 'substances' in the Godhead.
|
||||
|
||||
'Hypostasis' had for a long time been used interchangeably with 'ousia'.
|
||||
However, Athanasius claimed that perhaps God could have three hypostases, but
|
||||
only one ousia, at the same time. In so doing, he wedged apart a sharp technical
|
||||
distinction between 'hypostasis' and 'ousia' which previously wouldn't have made
|
||||
sense. Logical or not, it enabled the Nicene revival to have its cake and eat
|
||||
it. God is both one in ousia, protecting against Arianism, and three in
|
||||
hypostasis, protecting against Sabellianism.
|
||||
|
||||
So the Nicene revival gained a new superpower: the power to use formerly
|
||||
synonymous terms to assert contradictions without blushing. This power to accept
|
||||
apparent contradiction as part of the unknowable mystery of God is perhaps the
|
||||
most important legacy of the period. Arguably, the church has been at its best
|
||||
when it has put aside the need to know everything, and embraced this spirit of
|
||||
tolerance, humility and faith.
|
||||
|
||||
---
|
||||
|
||||
For much of the 360s and 370s, the homoian emperor Valens had ruled over the
|
||||
eastern part of the Empire, while his big brother, Valentinian, ruled the west.
|
||||
In the late 370s, Valentinian and then Valens died within quick succession of
|
||||
each other. Valentinian's twenty-year-old son, Gratian, was left to clear up the
|
||||
mess. In 379, Gratian delegated rule of the east to Theodosius, who was to
|
||||
implement a decisively different religious policy than his predecessor, Valens.
|
||||
|
||||
In 380, Theodosius issued an edict, saying that only those who agreed to the
|
||||
homoousios clause of the Nicene Creed could be considered 'catholic' Christians.
|
||||
The message was clear: the homoians were out, and the Nicenes were in.
|
||||
|
||||
In 381, he called a council to Constantinople, and it (probably) issued the
|
||||
revision of the 325 creed which is still used in various versions in all the
|
||||
world's largest Christian denominations. There would be no more revisions, and
|
||||
it would become, then as now, compulsory reading for all those preparing to don
|
||||
vestments.
|
||||
|
||||
One question is, why did the 381 creed differ in the ways it did from 325? Many
|
||||
of the differences, including the much-enlarged section on the Son, seem to have
|
||||
little controversial content: nobody was disputing that Jesus was born of the
|
||||
Virgin Mary, for example, though she makes her first appearance in the Creed in
|
||||
the 381 version. Some historians think this suggests that the 381 was based on a
|
||||
similar, but distinct creed from 325. This seems unlikely to me, given that
|
||||
about half the creed is in verbatim agreement with 325.
|
||||
|
||||
However, a couple of edits stand out. There are some clear signs of
|
||||
anti-Marcellianism: 'his \[the Son's] kingdom shall have no end', the Son is
|
||||
begotten of the Father 'before all ages'. Perhaps a clear emphasis on the
|
||||
eternal relationship between the Son and the Father was part of the diplomacy
|
||||
needed to get the Eusebian faction on-side.
|
||||
|
||||
The new details on the Holy Spirit are interesting too. They suggest a delicate
|
||||
compromise. Some bishops were reluctant to suppose that the Father and the
|
||||
Spirit have the same essence. On the other hand, others reckoned that they must
|
||||
share the same essence, given that they are equally deserving of worship. Thus
|
||||
the creed does not have a 'homoousios' clause for the Spirit, but does assert
|
||||
that the Spirit 'together with the Father and with the Son is worshipped and
|
||||
glorified'. With a spoonful of humility, both sides can be satisfied with that.
|
||||
|
||||
The revised Nicene Creed was the focus point, the distillation of a growing
|
||||
theological movement, formed by the various anti-homoian bishops finding a way
|
||||
to keep true to their own convictions while respecting each other's red lines.
|
||||
|
||||
As a result of the context of 325, Athanasius' relentless anti-Arian polemic
|
||||
which kept that movement alive, and the 'neo-Arian' heterousian movement, the
|
||||
new Nicene tradition insisted on the full co-equal divinity of Father, Son and
|
||||
Holy Spirit. This doctrine ensures Nicenes can affirm that Christ mediates true
|
||||
knowledge of the transcendent Godhead to humanity: the one who was born of Mary,
|
||||
suffered and died on the cross, was raised from the dead and ascended into
|
||||
heaven was true God from true God, of the same essence as his Father.
|
||||
|
||||
To satisfy the Eusebian strain, which defined itself by opposition to Marcellus,
|
||||
the Nicene tradition included a commitment to a robust distinction between
|
||||
Father, Son and Spirit, and to the eternity of the Son: begotten of the Father
|
||||
before all ages, his kingdom shall have no end. As a result, Nicenes inherited a
|
||||
way of thinking about God's action in the world, as instrinsically co-operative
|
||||
without being divided.
|
||||
|
||||
The biggest change between 325 and 381 was not the text, but what the text is
|
||||
used for. In 325, the Creed functioned to condemn Arius in order to heal the
|
||||
divisions his teachings had caused. In its second life, the Creed found an
|
||||
altogether new purpose: to serve as a common statement of orthodox faith. It
|
||||
started life as a way to define who was out. It ended up defining who was in.
|
||||
|
||||
Where was Athanasius? Consider that when Athanasius was appointed bishop in 328,
|
||||
he was relatively young for a bishop at thirty-five. That means that in 381, he
|
||||
would have been the ripe old age of eighty-eight. In fact, he didn't make it
|
||||
that far: he died in peace in the countryside outside his native Alexandria
|
||||
in 373. If he had seen the outcome of 381, he might have regarded his life
|
||||
project complete. Perhaps he knew that with the new generation of bishops, the
|
||||
tide was turning for good, and died in peace. Perhaps not. Either way, his
|
||||
compromises, and his beloved homoousios, have left a permanent mark on the
|
||||
church.
|
||||
|
||||
This is the legacy of 381. It is two-faced: any common statement of faith can be
|
||||
used to exclude. Indeed, in the late fourth century, both non-Nicene Christians
|
||||
and pagans found themselves the victims of increasing state-backed sectarian
|
||||
violence.
|
||||
|
||||
However, 381 also bears witness to the power of humility and faith. Once we stop
|
||||
grasping at perfect knowledge we cannot attain, we can begin to appreciate the
|
||||
mystery of God. This is one legacy I hope we can carry forward into our century.
|
||||
@@ -1,171 +0,0 @@
|
||||
---
|
||||
title: Arianism
|
||||
description: >-
|
||||
I'm summarising what I've learned recently about Arianism: the heresy par
|
||||
excellence, named for the early-fourth-century Alexandrian priest, Arius. I'll
|
||||
conclude with some reflections on why we still need to reject Arian
|
||||
temptations and affirm Nicene orthodoxy today.
|
||||
pubDate: 2025-10-09
|
||||
---
|
||||
|
||||
Arianism neither started nor ended with Arius. When he preached in the 320s, he,
|
||||
like so many of his contemporary Alexandrians, only followed Origen in
|
||||
subordinating the Son to the Father. In Alexandria, there was a strong emphasis
|
||||
on the absolute transcendence and perfection of God, and therefore the
|
||||
difference between that and the Jesus who was born, was tempted, suffered and
|
||||
died. Arius was unremarkable in that respect. He was only remarkable in drawing
|
||||
the logical conclusion: since God is indivisible, ingenerate, immutable, eternal
|
||||
and impassible, but the Son of God was begotten, born of a woman, was tempted,
|
||||
suffered and died, it follows that the Son of God is not fully God. The image of
|
||||
the Father, sure, but not sharing in his Godhead: that wouldn't do justice to
|
||||
the Father's Godhead.
|
||||
|
||||
The movement later characterised as 'Arianism' did not share all his teaching.
|
||||
In particular, the idea that the Son was begotten in time -- that 'there was
|
||||
when he was not' -- was a slur, and respectable Arians accepted that the Son is
|
||||
eternal. Some historians deny that there was any coherent movement worth calling
|
||||
'Arianism', however, I think the creeds and councils of the fourth century show
|
||||
that there was a theological movement, self-consciously and unashamedly
|
||||
associated with Arius, which privileged God's transcendence over the Godhead of
|
||||
the Son. So, although the name 'Arianism' is certainly intended to be
|
||||
derogatory, and there was surely no conspiracy to follow Arius as such, I think
|
||||
the term 'Arianism' is meaningful and has a referent.
|
||||
|
||||
Whether or not individual bishops completely agreed with Arius theology, very
|
||||
many were sympathetic to his pro-transcendence leaning. So, when he applied his
|
||||
considerable arts of persuasion to influential likeminded bishops like Eusebius
|
||||
of Nicomedia, he succeeded in establishing a considerable alliance behind him.
|
||||
What had already been a theological strain was forced by the heat of controversy
|
||||
to coalesce into a faction.
|
||||
|
||||
Arius and his supporters were set back temporarily by the Council of Nicaea in
|
||||
325, when the emperor Constantine personally backed the homoousion under the
|
||||
impression this would resolve the dispute. But Nicaea lost influence very
|
||||
quickly, and the Eusebian faction gained ground. By 328, Arius himself had been
|
||||
reconciled into the church by Constantine. And through the 330s, Eusebius of
|
||||
Caesarea, another Arian sympathiser, repeatedly engineered the exile of key
|
||||
supporters of Nicaea, including Eustathius, Marcellus and Athanasius.
|
||||
|
||||
In this period, it may be fair to characterise Athanasius as standing more or
|
||||
less alone in fighting against Arianism. This changed somewhat in the 340s, when
|
||||
he gathered the support of the bishop of Rome and many other western bishops in
|
||||
his cause. He remained anathema in the East.
|
||||
|
||||
He still had a great deal of sympathy back in Egypt, however. The imperial
|
||||
administration had installed Gregory of Cappadocia, a stalwart Arian, in place
|
||||
of Athanasius as bishop of Alexandria from 339 until 346. Yet when Athanasius
|
||||
returned to reclaim his see in 346, he was greeted with, according to Gregory of
|
||||
Nazanius, 'universal cheers ..., nightlong festivities, the whole city gleaming
|
||||
with light, and both public and private feasting'. And when Arius was exiled
|
||||
again, and another Arian, George of Cappadocia, again installed in his place in
|
||||
356, the results were riots. When George attempted to carry out one of his key
|
||||
roles as bishop -- distributing money to widows -- many widows had to be beaten
|
||||
to accept money from his hands. After five years, George was lynched in 361. The
|
||||
people of Alexandria were roundly behind their local hero, and did not take
|
||||
kindly to Rome imposing their agenda on them by force.
|
||||
|
||||
While Egypt held strong for Athanasius, the Arian party became ever more
|
||||
triumphant in the rest of the Empire. In 358 and 359, a series of fraught
|
||||
councils in East and West produced conflicting resolutions, and the emperor
|
||||
Constantius resolved in 360 to get the situation under control. He called a
|
||||
council to Constantinople and ensured an even result. These were the homoean
|
||||
creeds, asserting that while the Son is like the Father, we cannot and must not
|
||||
say anything about their ousia.
|
||||
|
||||
These creeds have subsequently been called the 'Arian' creeds. The reason for
|
||||
describing the homoean party as 'Arian' is, first, that they explicitly rejected
|
||||
Nicaea and the homoousion, and second, they failed to affirm the full Godhead of
|
||||
the Son, saying only that the Son is 'like the Father' and that he is 'God from
|
||||
God', pointedly omitting the Nicaean elaboration, 'true God from true God'.
|
||||
|
||||
The councils of 358-360 were chaotic. Councils overrode councils. The emperor
|
||||
rejected creeds and forced his own ones through. Swathes of bishops were
|
||||
banished or deposed. Amidst all the chaos, Athanasius found himself making
|
||||
unexpected friends: the Cappadocian Fathers, including Basil 'the Great', while
|
||||
preferring 'homoiousion' or 'like essence' to his Nicene 'homoousion' or 'same
|
||||
essence', ended up on his side against the triumphant homoeans. The violence of
|
||||
those councils bred hostility, and with a common grudge, a coalition had
|
||||
suddenly formed against the homoeans and around Nicaea.
|
||||
|
||||
Perhaps Constantius might have been able to force his way, but he died in
|
||||
only 361. His replacement was Julian. While Julian's reign was short, he brought
|
||||
about a sharp change in direction.
|
||||
|
||||
Julian, 'the Apostate', had converted from Christianity to paganism, and during
|
||||
his reign, the alliance between Church and Empire was briefly severed. In a
|
||||
deliberate attempt to sow chaos, he refused to mediate on behalf of the Church
|
||||
and allowed all banished bishops to return from exile. At one time, there were
|
||||
five competing bishops all in Antioch.
|
||||
|
||||
One result of this severance was that bishops were free to form their own
|
||||
alliances and make their own case. As a result, the Nicene alliance emerged from
|
||||
Julian's brief reign decisively stronger.
|
||||
|
||||
The Nicene alliance would have to wait until 379 for a sympathetic emperor. But
|
||||
once Theodosius acceded, the Nicene victory was absolute and irreversible. He
|
||||
decreed that all clergy had to agree to the Nicene Creed, and called a council
|
||||
to amend and affirm the Creed.
|
||||
|
||||
This did not mean that Arianism died out. Eusebius of Nicomedia had sponsored a
|
||||
mission to the Goths, and, being outside of the emperor's grasp, they held
|
||||
strong to their Arian convictions for centuries after. Indeed, when the Goths
|
||||
later took possession of large parts of the Western Empire, Arians may well have
|
||||
significantly outnumbered Nicenes in the West, long after the matter was settled
|
||||
within the Empire. And certain theologies today, which seek to reduce Jesus to a
|
||||
mere emanation from or pointer towards a transcendent God, or a religious genius
|
||||
or a spiritual guru, rather than the real presence of God, are Arian in so far
|
||||
as they seek to protect the transcendence of God at the cost of his choice to
|
||||
dwell with us in Jesus Christ.
|
||||
|
||||
So it's worth considering what's lost in the difference between the Nicene faith
|
||||
which is now indisputably Christian orthodoxy, and Arianism in all its forms. If
|
||||
a preacher today elides away Jesus' full Godhead, what does it matter?
|
||||
|
||||
Three problems arise in consequence. One is that, if Jesus is not true God, then
|
||||
his miracles are meaningless. This is particularly problematic for those who
|
||||
want to read the Gospels as mere myth without affirming the truth of any of its
|
||||
particular historical content. If Jesus is not true God, then the miracles lose
|
||||
their mythic function. If Jesus is not true God, then a story about him healing
|
||||
someone far away has nothing to do with me. But if Jesus is true God, if he is
|
||||
Emmanuel, then his healings have the power to function as a mythic sign,
|
||||
pointing to something about God's plans to redeem the world. For his miracles to
|
||||
work as myth, whether or not they are true history, Jesus must be true God.
|
||||
|
||||
Secondly, if Jesus is not true God, then what kind of salvation can he offer? If
|
||||
a mere man can save us from our sin, what does that mean about sin? If we can be
|
||||
saved by a religious genius, a guru, someone specially in-touch with the
|
||||
spiritual reality, then salvation is no more than fixing up the material world.
|
||||
How's that going, two thousand years on? Has the Church made any progress in
|
||||
translating Jesus' teaching into universal peace? No doubt the Church has done
|
||||
some good -- but it doesn't seem credible that the Church is about to fix the
|
||||
world's problems by following Jesus' self-help agenda. In contrast, if Jesus is
|
||||
God, we can affirm the biblical notion that sin is a crime against God, which
|
||||
separates us from him. Since it is a crime against God, only God can bring about
|
||||
reconciliation. And since God has proven that he is bringing about that
|
||||
reconciliation in Jesus Christ, we can hold strong to our trust in his promise
|
||||
not simply to fix the world according to its own rules -- for that would be
|
||||
impossible -- but to change the rules in a second creation.
|
||||
|
||||
Finally, if Jesus is not true God, then we have no way of knowing anything at
|
||||
all about his relationship to God. If he is not true God, then all we can see in
|
||||
Jesus is a man. We can guess at some super-spiritual connection if we like,
|
||||
seeing his words, deeds and miracles as evidence of some semi-divine status. But
|
||||
that would be pure guesswork, in other words, wishful thinking, in other words,
|
||||
fantasy. Athanasius called it 'mania': pulling wild theological claims out of
|
||||
your own head with no substantial basis in reality. But if Jesus is true God,
|
||||
and God gives humans the gift of the Holy Spirit to recognise that Godhead, then
|
||||
we can know that Jesus is true God by seeing him for what he is. This is not
|
||||
fantasising without a grounding in reality, this is the most basic form of
|
||||
knowing: seeing and believing. If Jesus is not God, then Christian faith is
|
||||
fantasy, but if Jesus is true God, then Christian faith can stand firm.
|
||||
|
||||
With Arius, we have a religion that reduces the Gospels to fairy stories with no
|
||||
relevance for you or me, a religion that reduces the Church to a struggling
|
||||
self-help movement, and a religion that rests on fantasy. But if we stick to
|
||||
Nicene orthodoxy, instead, we have a religion that reads the Gospels as true
|
||||
myth, real history profused with life-changing theology; a religion that can
|
||||
have hope for the world as still needing God's work of reconciliation to be
|
||||
perfected, yet containing within it anticipations of that future, including in
|
||||
the Church; and a religion that rests on true faith, certain knowledge derived
|
||||
not from wishful thinking but encountering the very essence of God in Jesus
|
||||
Christ.
|
||||
@@ -1,227 +0,0 @@
|
||||
---
|
||||
title: Why did the church become persecuting in the fourth century?
|
||||
description: >-
|
||||
In one generation, Christians in the Roman Empire went from officially
|
||||
persecuted to becoming imperially-backed persecutors themselves. It's
|
||||
important to understand why, to prevent the church from persecuting today.
|
||||
pubDate: 2025-12-11
|
||||
---
|
||||
|
||||
In the year 325, Constantine stood before an assembly of Christian bishops. He
|
||||
had just the year before killed his last remaining rival in battle, leaving him
|
||||
as the sole Augustus of the Roman Empire, from Brittania to Arabia. The bishops
|
||||
must have assembled before him in reverent awe.
|
||||
|
||||
Many of them sported scars from torture they had endured in the reign of
|
||||
Diocletian, Constantine's predecessor. Diocletian had sponsored an enormous and
|
||||
brutal persecution of Christians. But that generation of bishops was witnessing
|
||||
an epochal shift of power. Over his reign, Constantine would divert large chunks
|
||||
of the wealth and influence of the Roman state into the safe-keeping of the
|
||||
bishops. Under Constantine's leadership, the bishops would be transformed from
|
||||
enemies of the state to the state's agents.
|
||||
|
||||
Official Roman persecution of Christians was decisively coming to an end. But
|
||||
the tragedy of the fourth century is that rather than ushering in a new age of
|
||||
religious tolerance, the bishops only continued the Roman habit of religious
|
||||
persecution, directing the force of the Empire first against internal rivals,
|
||||
'heretics', and then against pagans and Jews.
|
||||
|
||||
Why did Constantine bestow so much power on the bishops? Part of the answer may
|
||||
be the creaking disfunction of the Roman state. The imperial systems for
|
||||
protecting the poor were falling apart. The justice system was notoriously
|
||||
corrupt, and was known to effectively be a means for the rich to get their way
|
||||
by paying for the best lawyers and greasing the palms of the judges. The
|
||||
poor-relief system, based on the magnanimity of local patrons, was stuttering as
|
||||
an increasing proportion of the aristocracy's surplus wealth went to fund the
|
||||
tottering military system, frequently consuming huge resources in ill-fated
|
||||
expeditions against the Sassanids or fighting coups and civil wars between rival
|
||||
emperors.
|
||||
|
||||
The bishops were already in control of an impressive poor-relief system within
|
||||
Christian communities, and, unlike the Roman system, which rewarded rich
|
||||
philanthropists with honours, the Christian system encouraged patrons to give
|
||||
anonymously via their bishop, meaning the bishops were in control of how large
|
||||
amounts of Christian money was spent. When Constantine ascended, they were ready
|
||||
to go with their own bureaucratic systems independent of the imperial civil
|
||||
service.
|
||||
|
||||
Constantine may have regarded the bishops, fresh out of persecution, as less
|
||||
corrupt than imperial pen-pushers. However, in the long run, the effect of his
|
||||
transfer of power was to transform the episcopate into an alternative civil
|
||||
service, perhaps no less corrupt than the first. But how did this power turn
|
||||
into persecution?
|
||||
|
||||
As the bishops became ever more powerful, Constantine and his successors became
|
||||
increasingly dependent on their power. Bishops had huge moral influence over
|
||||
their congregations, and their word had the power to stop -- or start -- riots.
|
||||
Emperors also needed them to keep distributing poor relief, an important
|
||||
foundation for the emperor's moral authority. When the hugely unpopular George
|
||||
of Cappadocia was installed in Alexandria in 357, the local widows refused to
|
||||
receive alms from him: as a result, they were physically beaten by George's
|
||||
imperial goons.
|
||||
|
||||
Since the emperors needed the bishops' support, they became increasingly willing
|
||||
to acquiesce to their demands. And one of the bishops' demands was that the
|
||||
emperor use his authority to help them crush heresy.
|
||||
|
||||
The bishops of the fourth century inherited a dichotomy between orthodoxy and
|
||||
heresy which had developed in the early church. Orthodoxy meant true belief,
|
||||
defined and enforced by the bishop. Whoever promoted false beliefs, and together
|
||||
with it insurrection against the bishop's authority, was defined as a heretic.
|
||||
|
||||
Orthodoxy was conceived of as the unchanging teaching of the apostles, who were
|
||||
in turn taught directly by the Holy Spirit. Orthodoxy might have to be re-stated
|
||||
as sneaky heretics sought to twist its language, but orthodoxy was never
|
||||
supposed to be innovative: only heresy was innovative. Further, heresy was
|
||||
always thought of as a combination teaching falsehoods, behaving immorally, and
|
||||
refusing to take part in mainstream Christian community. It all came as a
|
||||
package. Truth means right behaviour means loyalty.
|
||||
|
||||
It's difficult to explain exactly why this system emerged. It's true that faith
|
||||
lies at the root of Christian religion, and that Christ taught that he is truth.
|
||||
The Epistles are clear that false teachings can be dangerous, and Christians
|
||||
have a duty to resist them. But that doesn't in itself explain why the bishop
|
||||
gets to decide which teachings are true or false, nor why the myth of an
|
||||
unchanging apostolic orthodox teaching should have prevailed over the idea that
|
||||
Christian teaching can grow over time as it encounters new problems and
|
||||
contexts.
|
||||
|
||||
This system may have been motivated by the need for a distinguishing feature to
|
||||
ground Christian family identity in the absence of an identity based on
|
||||
nationality, social class, sex, or religion. It may also have been some kind of
|
||||
reaction or defence mechanism against persecution. In a world that was often
|
||||
hunting for an excuse to persecute Christians, it was a matter of life and death
|
||||
that Christian communities were tight-knit, loyal to one another, and visibly
|
||||
living according to the highest moral standards.
|
||||
|
||||
Whatever the case may be, the result by the Constantinian turning point was that
|
||||
bishops had significant influence over their local Christian communities, and an
|
||||
ideological commitment to maintaining their communities' loyalty to the bishop
|
||||
and his teachings.
|
||||
|
||||
And the bishops' desire to crush heretics only increased as the fourth century
|
||||
wore on. With the wealth and power of the civil service increasingly transferred
|
||||
to the episcopate, the aristocracy which had dominated the civil service
|
||||
inevitably moved in to capture the episcopate. Those aristocrats guarded their
|
||||
power jealously, and elections became increasingly marred by accusations of
|
||||
corruption. When Athanasius was elected in 328, he was accused of being
|
||||
underage, of bribing electors and of beating up his Meletian opponents once he
|
||||
got in office. No doubt, the aristocratic bishops were more than happy to use
|
||||
the church's concept of orthodoxy to keep out challengers, as Athanasius did
|
||||
when he used the label 'Arian' to describe just about anyone who wanted him out
|
||||
of power, no matter how distant their ideas were from those of Arius. As bishops
|
||||
found the need to fight ever stiffer competition for their jobs, accusations of
|
||||
heresy multiplied.
|
||||
|
||||
As a result of their dependence on episcopal power, Constantine and his
|
||||
successors supported the bishops in their attempts to crush heresy. The bishops
|
||||
appealed to the emperor to adjudicate on disputes, and the emperor responded by
|
||||
calling councils such as Nicaea (325), Antioch (341), Constantinople (360) and
|
||||
Constantinople again (381). Under the emperor's authority, bishops were exiled
|
||||
from their sees, and some theological views were condemned as heresy while
|
||||
others affirmed as orthodoxy, to justify the empowerment of some and the
|
||||
dethronement of others. The particular orthodoxies implied by succeeding
|
||||
emperors was not consistent, leading to some emperors and councils being known
|
||||
to history as 'Nicene' and others as 'Arian'.
|
||||
|
||||
Apart from simply doing a favour for the bishops, the emperors had their own
|
||||
reasons for wanting to defend the bishops from challengers. The bishops now had
|
||||
the keys to the welfare system and the justice system. The emperor therefore
|
||||
could not tolerate rival bishops fighting for authority. That would only
|
||||
undermine those systems, which underpinned imperial power and moral authority.
|
||||
|
||||
The emperors may also have been motivated by the need to uphold true religion
|
||||
and keep peace in the Empire. It was a universal consensus that, if the Empire
|
||||
was to flourish, it would only be with God's blessing, and that would only
|
||||
happen in turn if the people were united in acceptable worship. Before the Edict
|
||||
of Milan in 313, which finally ended official persecution of Christians in the
|
||||
Roman Empire, there had been a long debate about whether Christian worship
|
||||
counted. It was controversial because Christian worship didn't look much like
|
||||
worship at all to pagan eyes, in particular because Christians didn't make
|
||||
sacrifices. When Constantine settled the issue in favour of Christians, it must
|
||||
have signalled a step change, where acceptable worship became less about proper
|
||||
rites and more about proper belief. This trend may have led emperors to regard
|
||||
heresy as a threat to the Empire's security. Further, where there were schisms,
|
||||
there was no peace, and the Emperor's mission, to unite the world under one
|
||||
government in perpetual peace, was incomplete.
|
||||
|
||||
These forces amplified one another in a terrible feedback loop. As bishops
|
||||
increasingly were empowered to define and enforce orthodoxy, they increasingly
|
||||
monopolised local church leadership, which made them more desirable as imperial
|
||||
bureaucrats, which meant they got more power, which meant they were more able
|
||||
still to define and enforce orthodoxy. It was a spiral which led to the
|
||||
definition of orthodoxy being continually sharpened (even as the myth persisted,
|
||||
ever less plausibly, that they were defending pristine, unaltered apostolic
|
||||
teachings). Eventually, it pushed bishops to support persecution not only of
|
||||
Christians who disagreed with them, but also pagans and Jews.
|
||||
|
||||
Orthodoxy may also have become more important in the fourth century because of
|
||||
the large number of new converts. With so much influx, insiders may have felt
|
||||
that their core belief-identity was being threatened, and so will have enforced
|
||||
orthodoxy more strictly, while outsiders may have felt the need to prove their
|
||||
authenticity by strongly committing to orthodoxy. Committing violence against
|
||||
heretics, pagans, and Jews may also have functioned as a way to prove that
|
||||
you're an authentic Christian. This drive towards violence was pushed especially
|
||||
strongly from the monastic sector, which exploded in scale in the fourth
|
||||
century.
|
||||
|
||||
When orthodoxy gets sharp enough, it eventually gets sharp enough to cut the
|
||||
church in half. To put it another way, bishops competed to get imperial backing
|
||||
for their thinking, and therefore their right to power. Since this imperial
|
||||
backing must have some consistency to remain legitimate, this means orthodoxy
|
||||
gets standardised across the Empire, and that means that local differences of
|
||||
opinion become international schisms. Although the Arian controversy never
|
||||
resulted in a schism within the Empire, there were numerous schisms in the
|
||||
fourth and fifth centuries, culminating in the epic Nestorian schism, which
|
||||
split the imperial church three ways along Chalcedonian, Antiochene and
|
||||
Alexandrian fault lines.
|
||||
|
||||
My main reaction to this period of church history is dismay. It seems to me that
|
||||
the church was captured by the Empire and the aristocracy. The church became in
|
||||
large part a way for powerful people to grab, hold onto and accumulate power.
|
||||
When that happens today, the Gospel is suppressed, and the church loses moral
|
||||
authority.
|
||||
|
||||
To avoid this happening again, we ought to protect the right of Christians and
|
||||
others to believe and gather free from persecution. True belief is important,
|
||||
but that doesn't mean we should attempt to compel agreement. Christian leaders
|
||||
cannot enforce their teachings if dissatisfied Christians can just go to the
|
||||
church next door.
|
||||
|
||||
Opening communion also disempowers those forces which seek to enforce orthodoxy.
|
||||
If the bishop can't bar you from taking communion, they can't force you to
|
||||
accept what they teach or to support their political programme.
|
||||
|
||||
Finally, established churches are vulnerable to the perverse incentive
|
||||
structures of the state, and must be disestablished. The Church of England
|
||||
should not have seats in the Lords and should not crown British monarchs.
|
||||
|
||||
I believe in one holy, catholic and apostolic church -- but I do not believe in
|
||||
one opinion or one authority. My realistic ideal of church unity now involves a
|
||||
plurality of disestablished denominations which robustly disagree with one
|
||||
another on important points of belief, but which admit one another to communion
|
||||
and are willing to work together for the sake of the Gospel.
|
||||
|
||||
I have to caveat my pessimism about the fourth century. As much as I regret the
|
||||
imperialisation of the church, I remain attached to the particular orthodoxies
|
||||
which it produced at Nicaea, Constantinople and Chalcedon. I've been convinced
|
||||
that they are important ground truths for theology, and have stood the test of
|
||||
time because they are intellectually robust. Other creeds and councils
|
||||
(including creeds from fourth-century councils) have been forgotten, but these
|
||||
stand tall. I suppose that Nicaea, Constantinople and Chalcedon give good
|
||||
guardrails for theology, and, whatever the political forces which gave rise to
|
||||
them, have been subsequently vindicated by their theological fruits and by the
|
||||
enduring testimony of the church.
|
||||
|
||||
In summary, the church became increasingly persecuting in the fourth century as
|
||||
a result of the entangled interests of, on the one hand, an increasingly landed,
|
||||
aristocratic episcopate which needed to protect its influence amidst stiff
|
||||
competition, and, on the other hand, of embattled emperors who regarded the
|
||||
bishops as a better way of exerting the Empire's power and achieving the
|
||||
Empire's mission amidst the failure of the old imperial systems: provided they
|
||||
could be kept happy and kept in unchallenged power. This persecuting force
|
||||
produced the church's foundational ecumenical creeds, but was just as effective
|
||||
at producing disharmony as enforcing harmony, and ultimately led to the massive
|
||||
and ongoing Nestorian schism. This is a sober lesson for today's church, and
|
||||
should move us to protect freedom of belief and gathering for all, to
|
||||
disestablish the church and to open the communion.
|
||||
@@ -1,188 +0,0 @@
|
||||
---
|
||||
title: 10 very short stories about the Reformation
|
||||
description: >-
|
||||
I'm summarising a few of the big stories about the Reformation I've been
|
||||
studying recently.
|
||||
pubDate: 2026-02-16
|
||||
updatedDate: 2026-02-27
|
||||
---
|
||||
|
||||
1. Moral corruption in public office
|
||||
|
||||
Since the major reforms of Pope Gregory VII (r. 1073-1085) and his successors,
|
||||
the Roman Church had gone through several cycles of moral panic, attempting to
|
||||
crack down on the 'abuses' of the clergy. The main abuses that got folk worked
|
||||
up were simony (i.e. bribery), nepotism, holding multiple benefices, keeping
|
||||
mistresses and having illegitimate children with them, and getting entangled in
|
||||
secular power politics. The Reformation occurred just at a particularly severe
|
||||
instance of one of these moral panics. Both Protestants and Catholics responded
|
||||
with unprecedented reforms, in many ways similar: the clergy was transformed
|
||||
from a comfortable club for elites into a smaller band of well-educated and
|
||||
committed professionals. In the new Latin church, increasingly, nobility was
|
||||
neither necessary nor sufficient, but education and moral virtue were. Amongst
|
||||
Catholics, the priest became the spiritual equivalent of a Personal Trainer.
|
||||
They became experts at hearing confessions and guiding the highly personal
|
||||
development of their flock. Amongst Protestants, priests and ministers focused
|
||||
much more on shared community life, leading communal Psalm-singing and teaching
|
||||
their congregations with sermons. Amongst both Catholics and Protestants, clergy
|
||||
were expected to be resident in their parish or diocese, preach the Gospel,
|
||||
catechise, and administer sacraments.
|
||||
|
||||
2. The Eucharist
|
||||
|
||||
In the 14th and 15th centuries, people in Latin Christendom became increasingly
|
||||
devoted to celebrating the Eucharist. However, ordinary people became
|
||||
increasingly estranged from it. The Eucharist was only distributed to the laity
|
||||
under one kind, and then perhaps as infrequently as once a year at Easter, the
|
||||
legal minimum. The liturgy became a spectacle, but not something ordinary people
|
||||
could participate in or even understand. This had led to major protests,
|
||||
including the Hussite and Lollard revolts, in the fifteenth century. These
|
||||
revolts had been repressed by the Church. However, in the sixteenth century, the
|
||||
Church failed to hold back the tide. Protestants reformed the liturgy, turning
|
||||
the priest to face the congregation, translating the liturgy into the
|
||||
vernacular, and distributing the elements in both kinds. Catholics, while not
|
||||
abolishing the Mass altogether as the Protestants did, mandated frequent
|
||||
attendance at Mass and encouraged priests to explain to the laity what was
|
||||
happening in their own language as the liturgy went on. Christians in the Latin
|
||||
tradition now receive communion in a variety of ways, much of that diversity
|
||||
explicable in sixteenth-century terms, but almost all receive communion
|
||||
frequently, receive both species, and can interpret what they are doing
|
||||
theologically: these are all Reformation legacies. The fractious politics of the
|
||||
sixteenth century meant that these different developments of the Eucharist
|
||||
hardened into explicitly irreconcilable doctrines. Christians in the Latin
|
||||
tradition still do not all offer one another communion as a result of this
|
||||
ongoing schism.
|
||||
|
||||
3. Monastic reform
|
||||
|
||||
In the fifteenth century, there was a well-established monastic system in Latin
|
||||
Christendom. It functioned as a legitimate alternative career to marriage for
|
||||
elite men and women. They had a useful social role: they were paid by other
|
||||
elites to pray for the souls of themselves and their loved ones, thereby, they
|
||||
believed, reducing the duration of their stay in Purgatory. However, in the
|
||||
sixteenth century, this system broke down. Theologians challenged the doctrine
|
||||
of Purgatory, undermining the usefulness of the system. The growing
|
||||
middle-classes resented a system which entrenched the power of the aristocracy.
|
||||
The poor resented the accumulation of wealth in many monasteries, which
|
||||
typically required exorbitant entry fees, or were limited to people of noble
|
||||
birth, or both. In many places, monasteries were overhauled, ending the practice
|
||||
of praying for the souls of benefactors and opening up membership to those of
|
||||
humbler origins, and going out into the world to preach the Gospel and do works
|
||||
of charity. In many other places, the monastic system was abolished altogether.
|
||||
|
||||
4. Justification
|
||||
|
||||
How can I be right with God? In the medieval Roman Church, there were several
|
||||
doctrinal positions available, and none was authorised as the official 'correct'
|
||||
answer. One thing everyone agreed on, even revolutionaries like Jan Hus, was
|
||||
that you had to _do something_ to be right with God. Being justified was a
|
||||
matter of God working in you to transform you from something wretched to
|
||||
something holy. So, if there was no holiness, there was no justification.
|
||||
Profoundly unsatisfied with this, Martin Luther presented a radical alternative:
|
||||
justification is a free, gracious gift of God, won by Christ's work, not ours.
|
||||
Becoming holy isn't completely irrelevant, but for Luther, becoming holy, or
|
||||
'sanctification', comes second, and is not the condition of justification. This
|
||||
idea drove a wedge through the Church. Is this doctrine simply presenting the
|
||||
gospel truth of freedom in Christ, or is it an excuse for being lax on sin?
|
||||
|
||||
5. The authority of Scripture versus tradition
|
||||
|
||||
In the sixteenth century, various schismatics who we now know broadly as
|
||||
Protestants intoned with one voice, that venerating saints is idol-worship.
|
||||
Christians have venerated saints since at least the 3rd century, if not before,
|
||||
and is a tradition affirmed across the Christian world, in Rome, Constantinople,
|
||||
Alexandria and Antioch. How could the Protestants come up with such a novel
|
||||
idea? Their answer: they got it from Scripture. They argued that Scripture
|
||||
consistently condemns worshipping anything other than God, and nowhere promotes
|
||||
exceptions for a special kind of worship for a special kind of non-God. When it
|
||||
was pointed out to them that the cult of saints was an ancient and universal
|
||||
Christian practice, and affirmed by councils and the Pope, they answered that
|
||||
Scripture is a superior authority to the Church.
|
||||
|
||||
6. Confessionalisation
|
||||
|
||||
In the sixteenth century, there was a sudden profusion of confessions and
|
||||
catechisms. While Christians have used confessions, or creeds, since ancient
|
||||
times to rule on their disputes, the Reformation confessions took on different
|
||||
functions. For the Lutherans, the confessions sought to unify the Lutheran
|
||||
churches in distinction to the Catholic, making no attempt to reconcile their
|
||||
differences, but in contrast, to spell out and emphasise those differences. For
|
||||
the Reformed churches, that went even further, with each national church
|
||||
producing their own confessions in distinction with each other. The Reformed
|
||||
confessions didn't even function to unite the Reformed churches internationally:
|
||||
they had a local, and perhaps even temporal, character. Confessions became
|
||||
longer and ever more precise as time went on, becoming 'lawyer-like' in contrast
|
||||
to the sparse, poetic quality of the ancient creeds. The Catholics were by all
|
||||
means at it too, spelling out exactly what distinguished them from the
|
||||
Protestants in the Tridentine Profession of Faith and in numerous catechisms.
|
||||
All this was doubtless only possible because of the recent introduction of the
|
||||
printing press to Europe from China. For the first time, Christians were using
|
||||
confessional texts at scale not to unite Christians but to divide them.
|
||||
|
||||
7. Kings and clerics
|
||||
|
||||
Pope Gregory VII was famous for fighting the Holy Roman Emperor for the right to
|
||||
decide who gets to invest priests. This issue and others continued to grind at
|
||||
the relationship between the Pope and Europe's princes. From the 12th century,
|
||||
popes claimed to have ultimate authority on both spiritual and temporal matters,
|
||||
and attempted to exercise this alleged authority with mixed success. Kings
|
||||
fought back. The kings of France and Spain did particularly well at exacting
|
||||
papal concessions, and by the sixteenth century ended up pretty much in charge
|
||||
of Catholicism in their respective realms. In Germany, Switzerland, Scandinavia,
|
||||
England and Scotland, monarchs were more under the papal thumb, sometimes much
|
||||
more. Ulrich Zwingli, the great Swiss reformer, complained that the Swiss had to
|
||||
accept whatever Roman carriage-driver the Pope decided to send as their priest
|
||||
or bishop. In 1538, Henry VIII declared himself the Supreme Head of the Church
|
||||
of England. This move was little distinguished from the actions of his French
|
||||
and Spanish counterparts (apart from its brazenness). But in the context of the
|
||||
time, he was compelled to make entreaties with the German Protestants. After a
|
||||
period of ambiguity, under his grand-daughter Elizabeth, England ended up firmly
|
||||
in the Protestant camp.
|
||||
|
||||
NB. It has since been pointed out to me that Elizabeth is famously Henry VIII's
|
||||
daughter, not his grand-daughter. I leave this error in situ, so as not to give
|
||||
the false impression that these short stories are in any way to be admired or
|
||||
trusted.
|
||||
|
||||
8. Mysticism
|
||||
|
||||
In the late Middle Ages, a movement known as _devotio moderna_ or 'the modern
|
||||
devotion' swept Europe. It challenged the old rituals of public, communal, vocal
|
||||
prayer, and emphasised private meditation and mental prayer. For adherents, the
|
||||
goal was to transform your soul and re-orient it towards God. Along the way,
|
||||
you'd be likely to use methods from books written by Christendom's top gurus,
|
||||
but there was doubtless plenty of unregulated mysticism happening, too. In the
|
||||
Reformation, mystical experiences became ambiguous on both sides of the fence,
|
||||
for different reasons. Protestants emphasised shared over private spirituality,
|
||||
and suspected mystics of practicing needless and idolatrous false religion. But
|
||||
Protestants also emphasised the work of the Spirit in each believer by faith,
|
||||
and often continued practicing private spirituality. Meanwhile, Catholics
|
||||
celebrated private spirituality and were perfectly happy emphasising that it
|
||||
took hard work to approach a direct encounter with God's presence, but were
|
||||
unsettled by the thought that if you could have a such an encounter by praying
|
||||
and meditating, you wouldn't need the mediation of the Church to bring you God's
|
||||
presence through the sacraments.
|
||||
|
||||
9. Conciliarism
|
||||
|
||||
The medieval Latin church had a thing for councils. Councils functioned as a way
|
||||
to solve disagreements in a fair way, thus generating robust consensus: in
|
||||
theory, at least. Idealists, called 'conciliarists,' wanted to prioritise
|
||||
councils over every other authority, even the Pope: though that meant that
|
||||
ecumenical councils were deeply distrusted by exactly the one person who had the
|
||||
sole authority to call them. These conflicts still lay unresolved when Martin
|
||||
Luther led a revolt against Rome in 1517. For some decades, leaders on both
|
||||
sides of the divide held out hope that an ecumenical council might heal the
|
||||
schism. However, power politics got in the way, and by the end of the Council of
|
||||
Trent, it was abundantly clear that councils had become solidly subservient to
|
||||
papal authority, and were only ever going to exacerbate the split. Conciliarism
|
||||
was finally dead.
|
||||
|
||||
10. Persecution
|
||||
|
||||
In 1520, Martin Luther was declared an heretic in a papal bull issued by Pope
|
||||
Leo X. In response, Martin Luther burned the bull in public and announced that
|
||||
Leo X was the Antichrist. Various players in various quarters tried various
|
||||
strategies for resolving the schism, and it seems that few were willing to give
|
||||
up on violent coercion. In both Catholic and Protestant domains, magistrates
|
||||
burned books and burned people in an attempt to quell heresy.
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
title: What is an agnostic?
|
||||
description: >-
|
||||
pubDate: 2026-03-04
|
||||
---
|
||||
|
||||
I learned today that the first agnostic was 'Darwin's Bulldog', Thomas Henry
|
||||
Huxley. He attended the Metaphysical Society, an extremely broad selection of
|
||||
England's foremost thinkers who gathered in London nine times a year throughout
|
||||
the 1870s to discuss the ultimate questions. He tried all the usual
|
||||
appellations: atheist, theist, pantheist, materialist, idealist, Christian. He
|
||||
found all of them wanting. All the various '-ists', he felt, 'were quite sure
|
||||
they had attained a certain "gnosis,"-had, more or less successfully, solved the
|
||||
problem of existence; while I was quite sure I had not, and had a pretty strong
|
||||
conviction that the problem was insolube.' Thus, negating the term 'gnostic', he
|
||||
coined 'agnostic'.
|
||||
|
||||
Thus for Huxley, as with all the first agnostics, the term did not intend the
|
||||
metaphysical neutrality it's often taken to mean today. For Huxley, it's a
|
||||
positive epistemological assertion: sure, I don't know, but neither do you: the
|
||||
matter is in principle unknowable. 'Agnostic' is not a way for Huxley to
|
||||
diplomatically sidestep metaphysical debates without having to take a side, it's
|
||||
a confrontational view which contradicts the theist, the atheist, and all the
|
||||
rest.
|
||||
|
||||
I wonder what people in my life think of this, who have described themselves as
|
||||
'agnostic'. Did they mean what Huxley meant, or did they mean something more
|
||||
irenic? Does Huxley's approach challenge them? Is neutrality really an adequate
|
||||
stance?
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
title: Subscribing to this blog
|
||||
description:
|
||||
I've added a page to this Website describing how you can subscribe to this
|
||||
blog.
|
||||
pubDate: 2026-04-16
|
||||
---
|
||||
|
||||
Hi all! Since I started this blog, I've been publishing an RSS file to go
|
||||
alongside it. If you don't know, an RSS file is a really old and really simple
|
||||
and really fantastic way to subscribe to updates on any Website that publishes
|
||||
one. You can use it to subscribe to my Website. You don't have to remember to
|
||||
look at it every once in a while. RSS is all over the Web, by the way, and you
|
||||
can use it for way cooler stuff than my blog. If that's news to you, have a
|
||||
look!
|
||||
|
||||
=> <a href="/blog/subscribe">How to subscribe to this blog</a><br> =>
|
||||
<a href="/blog/rss.xml">My RSS file</a><br> =>
|
||||
<a href="https://doctorow.medium.com/you-should-be-using-an-rss-reader-76aed31151f9">Cory
|
||||
Doctorow explaining why RSS is ridiculously good</a>
|
||||
@@ -1 +0,0 @@
|
||||
../../../../common/longlog/
|
||||
@@ -1 +0,0 @@
|
||||
../../../common/microlog/
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
/// <reference path="../.astro/types.d.ts" />
|
||||
/// <reference types="astro/client" />
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import FormattedDate from '../components/FormattedDate.astro';
|
||||
import Navbar from '../components/Navbar.astro';
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
description?: string;
|
||||
updatedDate?: Date;
|
||||
pubDate: Date;
|
||||
}
|
||||
|
||||
const { title, description, pubDate, updatedDate } = Astro.props;
|
||||
|
||||
const canonicalUrl = new URL(Astro.url.pathname, Astro.site);
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<BaseHead title={`${title} | joeac’s blog`} description={description} />
|
||||
<link rel="stylesheet" href="/css/post.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<Navbar />
|
||||
<article class="h-entry">
|
||||
<aside>
|
||||
<span>
|
||||
This is a blog post by
|
||||
<a class="p-author h-card" href="/">Joe Carstairs</a>.
|
||||
</span>
|
||||
{ updatedDate
|
||||
? (
|
||||
<span>Updated: <FormattedDate date={updatedDate} className="dt-updated"/>.</span>
|
||||
<span>Originally published: <FormattedDate date={pubDate} className="dt-published"/>.</span>
|
||||
) : <span>Published: <FormattedDate date={pubDate} className="dt-published"/>.</span>
|
||||
}
|
||||
<span hidden><a class="u-url uid" href={canonicalUrl}>Permalink</a></span>
|
||||
</aside>
|
||||
|
||||
<header>
|
||||
<h1 class="h-name">{title}</h1>
|
||||
<p class="p-summary" set:html={description} />
|
||||
</header>
|
||||
|
||||
<section class="e-content">
|
||||
<slot />
|
||||
</section>
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import FormattedDate from '../components/FormattedDate.astro';
|
||||
import Navbar from '../components/Navbar.astro';
|
||||
|
||||
type Props = {
|
||||
pubDate: Date;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { pubDate, title } = Astro.props;
|
||||
|
||||
const canonicalUrl = new URL(Astro.url.pathname, Astro.site);
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<BaseHead title={`${title} | joeac’s microlog`} description={`${title} | joeac's microlog`} />
|
||||
<link rel="stylesheet" href="/css/post.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<Navbar />
|
||||
<article class="h-entry">
|
||||
<aside>
|
||||
<span>
|
||||
This is a <a href="/microlog">microlog</a> post by
|
||||
<a class="p-author h-card" href="/">Joe Carstairs</a>.
|
||||
</span>
|
||||
<span>Published: <FormattedDate date={pubDate} className="dt-published"/>.</span>
|
||||
<span hidden><a class="u-url uid" href={canonicalUrl}>Permalink</a></span>
|
||||
</aside>
|
||||
|
||||
<header>
|
||||
<h1 class="h-name">{title}</h1>
|
||||
</header>
|
||||
|
||||
<section class="e-content">
|
||||
<slot />
|
||||
</section>
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
import BaseHead from "../components/BaseHead.astro";
|
||||
import Navbar from "../components/Navbar.astro";
|
||||
|
||||
const { title, description } = Astro.props;
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-GB">
|
||||
<head>
|
||||
<BaseHead title={title} description={description} />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<Navbar />
|
||||
<main>
|
||||
<slot />
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* This file is edited from astro/loaders/glob.d.ts
|
||||
*/
|
||||
|
||||
import type { glob, Loader } from "astro/loaders";
|
||||
type GlobOptions = Parameters<typeof glob>[0];
|
||||
/**
|
||||
* Loads multiple entries, using a glob pattern to match files.
|
||||
* @param pattern A glob pattern to match files, relative to the content directory.
|
||||
* @param ignore Glob patterns to exclude from the matched results.
|
||||
*/
|
||||
export declare function extendedGlob(
|
||||
globOptions: GlobOptions & {
|
||||
postprocessSlug?: (slug: string) => string;
|
||||
ignore?: string[];
|
||||
},
|
||||
): Loader;
|
||||
export {};
|
||||
@@ -1,306 +0,0 @@
|
||||
/**
|
||||
* This file is edited from astro/loaders/glob.js
|
||||
*/
|
||||
|
||||
import { existsSync, promises as fs } from "node:fs";
|
||||
import { relative } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import pLimit from "p-limit";
|
||||
import colors from "piccolore";
|
||||
import picomatch from "picomatch";
|
||||
import { glob as tinyglobby } from "tinyglobby";
|
||||
import {
|
||||
getContentEntryIdAndSlug,
|
||||
posixRelative,
|
||||
} from "../../node_modules/astro/dist/content/utils.js";
|
||||
function generateIdDefault({ entry, base, data }, postprocessSlug, isLegacy) {
|
||||
if (data.slug) {
|
||||
return data.slug;
|
||||
}
|
||||
const entryURL = new URL(encodeURI(entry), base);
|
||||
if (isLegacy) {
|
||||
const { id } = getContentEntryIdAndSlug({
|
||||
entry: entryURL,
|
||||
contentDir: base,
|
||||
collection: "",
|
||||
});
|
||||
return id;
|
||||
}
|
||||
const { slug } = getContentEntryIdAndSlug({
|
||||
entry: entryURL,
|
||||
contentDir: base,
|
||||
collection: "",
|
||||
});
|
||||
if (postprocessSlug) {
|
||||
return postprocessSlug(slug);
|
||||
}
|
||||
return slug;
|
||||
}
|
||||
function checkPrefix(pattern, prefix) {
|
||||
if (Array.isArray(pattern)) {
|
||||
return pattern.some((p) => p.startsWith(prefix));
|
||||
}
|
||||
return pattern.startsWith(prefix);
|
||||
}
|
||||
const secretLegacyFlag = /* @__PURE__ */ Symbol("astro.legacy-glob");
|
||||
function extendedGlob(globOptions) {
|
||||
if (checkPrefix(globOptions.pattern, "../")) {
|
||||
throw new Error(
|
||||
"Glob patterns cannot start with `../`. Set the `base` option to a parent directory instead.",
|
||||
);
|
||||
}
|
||||
if (checkPrefix(globOptions.pattern, "/")) {
|
||||
throw new Error(
|
||||
"Glob patterns cannot start with `/`. Set the `base` option to a parent directory or use a relative path instead.",
|
||||
);
|
||||
}
|
||||
const isLegacy = !!globOptions[secretLegacyFlag];
|
||||
const generateId =
|
||||
globOptions?.generateId ??
|
||||
((opts) => generateIdDefault(opts, globOptions?.postprocessSlug, isLegacy));
|
||||
const fileToIdMap = /* @__PURE__ */ new Map();
|
||||
const ignore = globOptions.ignore || [];
|
||||
return {
|
||||
name: "extended-glob-loader",
|
||||
load: async ({
|
||||
config,
|
||||
collection,
|
||||
logger,
|
||||
watcher,
|
||||
parseData,
|
||||
store,
|
||||
generateDigest,
|
||||
entryTypes,
|
||||
}) => {
|
||||
const renderFunctionByContentType = /* @__PURE__ */ new WeakMap();
|
||||
const untouchedEntries = new Set(store.keys());
|
||||
async function syncData(entry, base, entryType, oldId) {
|
||||
if (!entryType) {
|
||||
logger.warn(`No entry type found for ${entry}`);
|
||||
return;
|
||||
}
|
||||
const fileUrl = new URL(encodeURI(entry), base);
|
||||
const contents = await fs.readFile(fileUrl, "utf-8").catch((err) => {
|
||||
logger.error(`Error reading ${entry}: ${err.message}`);
|
||||
return;
|
||||
});
|
||||
if (!contents && contents !== "") {
|
||||
logger.warn(`No contents found for ${entry}`);
|
||||
return;
|
||||
}
|
||||
const { body, data } = await entryType.getEntryInfo({
|
||||
contents,
|
||||
fileUrl,
|
||||
});
|
||||
const id = generateId({ entry, base, data });
|
||||
if (oldId && oldId !== id) {
|
||||
store.delete(oldId);
|
||||
}
|
||||
untouchedEntries.delete(id);
|
||||
const existingEntry = store.get(id);
|
||||
const digest = generateDigest(contents);
|
||||
const filePath2 = fileURLToPath(fileUrl);
|
||||
if (
|
||||
existingEntry &&
|
||||
existingEntry.digest === digest &&
|
||||
existingEntry.filePath
|
||||
) {
|
||||
if (existingEntry.deferredRender) {
|
||||
store.addModuleImport(existingEntry.filePath);
|
||||
}
|
||||
if (existingEntry.assetImports?.length) {
|
||||
store.addAssetImports(
|
||||
existingEntry.assetImports,
|
||||
existingEntry.filePath,
|
||||
);
|
||||
}
|
||||
fileToIdMap.set(filePath2, id);
|
||||
return;
|
||||
}
|
||||
const relativePath2 = posixRelative(
|
||||
fileURLToPath(config.root),
|
||||
filePath2,
|
||||
);
|
||||
const parsedData = await parseData({
|
||||
id,
|
||||
data,
|
||||
filePath: filePath2,
|
||||
});
|
||||
if (
|
||||
existingEntry &&
|
||||
existingEntry.filePath &&
|
||||
existingEntry.filePath !== relativePath2
|
||||
) {
|
||||
const oldFilePath = new URL(existingEntry.filePath, config.root);
|
||||
if (existsSync(oldFilePath)) {
|
||||
logger.warn(
|
||||
`Duplicate id "${id}" found in ${filePath2}. Later items with the same id will overwrite earlier ones.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (entryType.getRenderFunction) {
|
||||
let render = renderFunctionByContentType.get(entryType);
|
||||
if (!render) {
|
||||
render = await entryType.getRenderFunction(config);
|
||||
renderFunctionByContentType.set(entryType, render);
|
||||
}
|
||||
let rendered = void 0;
|
||||
try {
|
||||
rendered = await render?.({
|
||||
id,
|
||||
data,
|
||||
body,
|
||||
filePath: filePath2,
|
||||
digest,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(`Error rendering ${entry}: ${error.message}`);
|
||||
}
|
||||
store.set({
|
||||
id,
|
||||
data: parsedData,
|
||||
body: globOptions.retainBody === false ? void 0 : body,
|
||||
filePath: relativePath2,
|
||||
digest,
|
||||
rendered,
|
||||
assetImports: rendered?.metadata?.imagePaths,
|
||||
});
|
||||
} else if ("contentModuleTypes" in entryType) {
|
||||
store.set({
|
||||
id,
|
||||
data: parsedData,
|
||||
body: globOptions.retainBody === false ? void 0 : body,
|
||||
filePath: relativePath2,
|
||||
digest,
|
||||
deferredRender: true,
|
||||
});
|
||||
} else {
|
||||
store.set({
|
||||
id,
|
||||
data: parsedData,
|
||||
body: globOptions.retainBody === false ? void 0 : body,
|
||||
filePath: relativePath2,
|
||||
digest,
|
||||
});
|
||||
}
|
||||
fileToIdMap.set(filePath2, id);
|
||||
}
|
||||
let baseDir;
|
||||
if (isLegacy && !globOptions.base) {
|
||||
baseDir = new URL(`./src/content/${collection}`, config.root);
|
||||
} else {
|
||||
baseDir = globOptions.base
|
||||
? new URL(globOptions.base, config.root)
|
||||
: config.root;
|
||||
}
|
||||
if (!baseDir.pathname.endsWith("/")) {
|
||||
baseDir.pathname = `${baseDir.pathname}/`;
|
||||
}
|
||||
const filePath = fileURLToPath(baseDir);
|
||||
const relativePath = relative(fileURLToPath(config.root), filePath);
|
||||
const exists = existsSync(baseDir);
|
||||
if (!exists) {
|
||||
logger.warn(
|
||||
`The base directory "${fileURLToPath(baseDir)}" does not exist.`,
|
||||
);
|
||||
}
|
||||
const files = await tinyglobby(globOptions.pattern, {
|
||||
cwd: fileURLToPath(baseDir),
|
||||
expandDirectories: false,
|
||||
ignore,
|
||||
});
|
||||
if (exists && files.length === 0) {
|
||||
logger.warn(
|
||||
`No files found matching "${globOptions.pattern}" in directory "${relativePath}"`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
function configForFile(file) {
|
||||
const ext = file.split(".").at(-1);
|
||||
if (!ext) {
|
||||
logger.warn(`No extension found for ${file}`);
|
||||
return;
|
||||
}
|
||||
return entryTypes.get(`.${ext}`);
|
||||
}
|
||||
const limit = pLimit(10);
|
||||
const skippedFiles = [];
|
||||
const contentDir = new URL("content/", config.srcDir);
|
||||
const configFiles = new Set(
|
||||
["config.js", "config.ts", "config.mjs"].map(
|
||||
(file) => new URL(file, contentDir).href,
|
||||
),
|
||||
);
|
||||
function isConfigFile(file) {
|
||||
const fileUrl = new URL(file, baseDir);
|
||||
return configFiles.has(fileUrl.href);
|
||||
}
|
||||
await Promise.all(
|
||||
files.map((entry) => {
|
||||
if (isConfigFile(entry)) {
|
||||
return;
|
||||
}
|
||||
return limit(async () => {
|
||||
const entryType = configForFile(entry);
|
||||
await syncData(entry, baseDir, entryType);
|
||||
});
|
||||
}),
|
||||
);
|
||||
const skipCount = skippedFiles.length;
|
||||
if (skipCount > 0) {
|
||||
const patternList = Array.isArray(globOptions.pattern)
|
||||
? globOptions.pattern.join(", ")
|
||||
: globOptions.pattern;
|
||||
logger.warn(
|
||||
`The glob() loader cannot be used for files in ${colors.bold("src/content")} when legacy mode is enabled.`,
|
||||
);
|
||||
if (skipCount > 10) {
|
||||
logger.warn(
|
||||
`Skipped ${colors.green(skippedFiles.length)} files that matched ${colors.green(patternList)}.`,
|
||||
);
|
||||
} else {
|
||||
logger.warn(
|
||||
`Skipped the following files that matched ${colors.green(patternList)}:`,
|
||||
);
|
||||
skippedFiles.forEach((file) =>
|
||||
logger.warn(`\u2022 ${colors.green(file)}`),
|
||||
);
|
||||
}
|
||||
}
|
||||
untouchedEntries.forEach((id) => store.delete(id));
|
||||
if (!watcher) {
|
||||
return;
|
||||
}
|
||||
watcher.add(filePath);
|
||||
const matchesGlob = (entry) =>
|
||||
!entry.startsWith("../") &&
|
||||
picomatch.isMatch(entry, globOptions.pattern);
|
||||
const basePath = fileURLToPath(baseDir);
|
||||
async function onChange(changedPath) {
|
||||
const entry = posixRelative(basePath, changedPath);
|
||||
if (!matchesGlob(entry)) {
|
||||
return;
|
||||
}
|
||||
const entryType = configForFile(changedPath);
|
||||
const baseUrl = pathToFileURL(basePath);
|
||||
const oldId = fileToIdMap.get(changedPath);
|
||||
await syncData(entry, baseUrl, entryType, oldId);
|
||||
logger.info(`Reloaded data from ${colors.green(entry)}`);
|
||||
}
|
||||
watcher.on("change", onChange);
|
||||
watcher.on("add", onChange);
|
||||
watcher.on("unlink", async (deletedPath) => {
|
||||
const entry = posixRelative(basePath, deletedPath);
|
||||
if (!matchesGlob(entry)) {
|
||||
return;
|
||||
}
|
||||
const id = fileToIdMap.get(deletedPath);
|
||||
if (id) {
|
||||
store.delete(id);
|
||||
fileToIdMap.delete(deletedPath);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
export { extendedGlob, secretLegacyFlag };
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
import { type CollectionEntry, getCollection, render } from 'astro:content';
|
||||
import BlogPost from '../../layouts/BlogPost.astro';
|
||||
import { renderGemtextToHtml } from '../../renderGemtextToHtml';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection('blog');
|
||||
return posts.map((post) => ({
|
||||
params: { slug: post.id },
|
||||
props: post,
|
||||
}));
|
||||
}
|
||||
type Props = CollectionEntry<'blog'>;
|
||||
|
||||
const post = Astro.props;
|
||||
const Content = post.filePath?.endsWith('.gmi')
|
||||
? renderGemtextToHtml(post.body ?? '', post.data.title)
|
||||
: (await render(post)).Content;
|
||||
---
|
||||
|
||||
<BlogPost
|
||||
title={post.data.title}
|
||||
description={post.data.description}
|
||||
pubDate={post.data.pubDate ?? new Date(post.id)}
|
||||
updatedDate={post.data.updatedDate}
|
||||
>
|
||||
{ post.filePath?.endsWith('.gmi') ? <Fragment set:html={Content}></Fragment> : <Content />}
|
||||
</BlogPost>
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
import BaseHead from '../../components/BaseHead.astro';
|
||||
import { SITE_TITLE, SITE_DESCRIPTION } from '../../consts';
|
||||
import BlogFeed from '../../components/BlogFeed.astro';
|
||||
import Navbar from '../../components/Navbar.astro';
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
|
||||
</head>
|
||||
<body>
|
||||
<Navbar />
|
||||
<main>
|
||||
<BlogFeed headingLevel={1}>
|
||||
<section>
|
||||
<p><a href="/blog/subscribe">How to subscribe to this blog</a></p>
|
||||
</section>
|
||||
</BlogFeed>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,37 +0,0 @@
|
||||
import path from 'node:path';
|
||||
import rss from '@astrojs/rss';
|
||||
import type { APIContext } from 'astro';
|
||||
import { getCollection } from 'astro:content';
|
||||
import MarkdownIt from 'markdown-it';
|
||||
|
||||
const mdParser = new MarkdownIt({
|
||||
html: true
|
||||
});
|
||||
|
||||
export async function GET(context: APIContext) {
|
||||
// `site` is guaranteed to exist because we define it in our Astro config
|
||||
const site = context.site!;
|
||||
const posts = await getCollection('blog');
|
||||
|
||||
return rss({
|
||||
title: 'Joe Carstairs’ blog',
|
||||
description: 'Short posts on random topics I find interesting',
|
||||
customData: `
|
||||
<image>/images/headshot.webp</image>
|
||||
<language>en-GB</language>
|
||||
`,
|
||||
site: path.join(site.toString(), 'blog'),
|
||||
trailingSlash: false,
|
||||
items: posts.map((post) => ({
|
||||
link: `/blog/${post.id}`,
|
||||
title: post.data.title,
|
||||
content: mdParser.render(post.body ?? ''),
|
||||
pubDate: post.data.pubDate,
|
||||
description: post.data.description,
|
||||
author: 'Joe Carstairs',
|
||||
|
||||
// A page for displaying comments related to the item
|
||||
/* commentsUrl: `${post.slug}/comments`, */
|
||||
})),
|
||||
})
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
---
|
||||
import Page from "../../layouts/Page.astro";
|
||||
|
||||
---
|
||||
|
||||
<Page
|
||||
title="How to subscribe to joeac's blog"
|
||||
description="How to subscribe to joeac's blog"
|
||||
>
|
||||
<section>
|
||||
<h1>How to subscribe to my blog</h1>
|
||||
|
||||
<p>
|
||||
The short version: use my <a href="/blog/rss.xml">RSS file</a> or my
|
||||
<a href="gemini://joeac.net/logs/longlog.gmi">gemlog</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If neither of those things means anything to you, no worries. You could
|
||||
just look at my website every once in a while, but that gets old. A better
|
||||
way is to use my RSS file. Here's how.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An RSS file, if you don't know, is a file containing a list of posts in a
|
||||
format that's so stupid even computers can understand it. Mine is at
|
||||
<a href="https://joeac.net/blog/rss.xml">https://joeac.net/blog/rss.xml</a>.
|
||||
Since computers can understand it, you can get software to read it
|
||||
automatically and tell you when I've made a new blog post. That's much less
|
||||
hassle than having to check manually yourself!
|
||||
</p>
|
||||
|
||||
<p>
|
||||
I'm not the only person serving RSS files, of course. You might not have
|
||||
heard of them, but they're actually all over the Web. In the early days of
|
||||
the Web, everyone was using them, so they've ended up built in to a whole
|
||||
load of foundational Web technology, and hence ubiquitous, even if most
|
||||
Web users have forgotten they exist. Once you've subscribed to my blog,
|
||||
you can subscribe to basically any blog, podcast, or YouTube channel, and
|
||||
a lot of other Websites for news, organisations, whatever. Point a
|
||||
well-designed RSS aggregator or RSS reader at most Websites, and it'll
|
||||
automatically find an associated RSS feed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you're not persuaded, try reading
|
||||
<a href="https://doctorow.medium.com/you-should-be-using-an-rss-reader-76aed31151f9">
|
||||
Cory Doctorow explaining why RSS is ridiculously good
|
||||
</a>. He's terrifyingly persuasive. Also, read his novels!
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you just want to give it a go quickly, probably the quickest way is to
|
||||
use someone else's RSS aggregator that they'll let you use as a service.
|
||||
<a href="https://feedly.com/news-reader">Feedly</a> and
|
||||
<a href="https://www.inoreader.com">Inoreader</a> have free tiers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you want to have a little more control, you can self-host an RSS
|
||||
reader, like <a href="https://tt-rss.org">Tiny Tiny RSS</a>,
|
||||
<a href="https://miniflux.app">Miniflux</a>, or
|
||||
<a href="https://freshrss.org">FreshRSS</a>. But why would you do that?
|
||||
Self-hosting is complicated! Why not just use a normal, local app? Here are
|
||||
some options for that you might want to investigate. All these are active
|
||||
free and open-source software projects at the time of writing.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://hyliu.me/fluent-reader">Fluent Reader</a> (Linux, Windows, Mac, also mobile I think?)</li>
|
||||
<li><a href="https://www.rssowl.org">RSSOwl</a> (Linux, Windows, Mac)</li>
|
||||
<li><a href="https://capyreader.com">Capy Reader</a> (Android)</li>
|
||||
<li><a href="https://apps.kde.org/en-gb/akregator">Akregator</a> (Linux, Windows (unstable))</li>
|
||||
<li><a href="https://gfeeds.gabmus.org">GFeeds</a> (Linux)</li>
|
||||
<li><a href="https://lzone.de/liferea">Liferea</a> (Linux)</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
For the terminally geeky, there is also
|
||||
<a href="https://newsboat.org">Newsboat</a>. I used it for ages, it works
|
||||
fabulously, but it's all in the terminal, so you have to be OK with that.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You can also just enter 'RSS feed reader' into your favourite search
|
||||
engine, software distribution, or app store and see what comes up. Try
|
||||
adding 'FOSS' into the query to prioritise free, open-source software.
|
||||
</p>
|
||||
</section>
|
||||
</Page>
|
||||
@@ -1,97 +0,0 @@
|
||||
---
|
||||
import OtpDialog from "../components/OtpDialog.astro";
|
||||
import Page from "../layouts/Page.astro";
|
||||
export const prerender = false;
|
||||
---
|
||||
|
||||
<Page title="Contact" description="Contact Joe Carstairs">
|
||||
<OtpDialog />
|
||||
|
||||
<form class="contact-form">
|
||||
<h1>Contact me</h1>
|
||||
<p hidden class="error"/>
|
||||
<label for="name">Name</label>
|
||||
<input id="name" name="name" type="text" required>
|
||||
<label for="email">Email</label>
|
||||
<input id="email" name="email" type="email" required>
|
||||
<label for="message">Message</label>
|
||||
<textarea id="message" name="message" required></textarea>
|
||||
<input type="submit" value="Send">
|
||||
</form>
|
||||
|
||||
<section class="success" hidden="true">
|
||||
<h1>You sent me a message!</h1>
|
||||
<p>Thanks for that. I may be in touch.</p>
|
||||
<p>In case you forgot, your message was this:</p>
|
||||
<hr>
|
||||
<dl>
|
||||
<dt>Name</dt> <dd class="sentname">???</dd>
|
||||
<dt>Email</dt> <dd class="sentemail">???</dd>
|
||||
<dt>Message</dt> <dd class="sentmessage">???</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
import { resendOtp } from '../scripts/contact/resend-otp';
|
||||
import { submitContactForm } from '../scripts/contact/submit-contact-form';
|
||||
import { submitOtpForm } from '../scripts/contact/submit-otp-form';
|
||||
import type { Selectors } from '../scripts/contact/selectors';
|
||||
|
||||
function locateOrPanic<T extends Element>(selector: string, desc: string, root?: Element): T {
|
||||
const elem = (root ?? document).querySelector<T>(selector);
|
||||
if (!elem) {
|
||||
alert(`Technical error: could not locate ${desc}. Please let Joe know if you have another means of contacting him.`);
|
||||
throw new Error(`Could not locate ${desc}`);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
const contactForm = locateOrPanic<HTMLFormElement>('form.contact-form', 'contact form');
|
||||
const otpDialog = locateOrPanic<HTMLDialogElement>('dialog.otp-dialog', 'OTP dialog');
|
||||
const otpForm = locateOrPanic<HTMLFormElement>('form.otp-form', 'OTP form');
|
||||
const successSection = document.querySelector('section.success');
|
||||
let resendButtonInterval: undefined | NodeJS.Timeout = undefined;
|
||||
|
||||
const selectors: Selectors = {
|
||||
contactForm: {
|
||||
emailElem: () => locateOrPanic<HTMLInputElement>('input[name="email"]', 'email input', contactForm),
|
||||
errorElem: () => contactForm.querySelector('.error'),
|
||||
nameElem: () => locateOrPanic<HTMLInputElement>('input[name="name"]', 'name input', contactForm),
|
||||
messageElem: () => locateOrPanic<HTMLTextAreaElement>('textarea[name="message"]', 'message textarea', contactForm),
|
||||
self: () => contactForm,
|
||||
submitButton: () => contactForm.querySelector('input[type="submit"]'),
|
||||
},
|
||||
otpDialog: {
|
||||
allOtpInputs: () => otpForm.querySelectorAll('input:not([type="submit"])'),
|
||||
errorElem: () => otpDialog.querySelector('.error'),
|
||||
firstOtpInput: () => otpForm.querySelector('input:not([type="submit"]):first-child'),
|
||||
otpForm: () => otpForm,
|
||||
otpRecipient: () => otpDialog.querySelector('.otp-recipient'),
|
||||
otpValidUntil: () => otpDialog.querySelector('.otp-valid-until'),
|
||||
resendButton: () => otpDialog.querySelector<HTMLButtonElement>('button.resend-button'),
|
||||
self: () => otpDialog,
|
||||
submitButton: () => otpForm.querySelector('input[type="submit"]'),
|
||||
},
|
||||
successSection: {
|
||||
email: () => successSection?.querySelector('.sentemail') ?? null,
|
||||
name: () => successSection?.querySelector('.sentname') ?? null,
|
||||
message: () => successSection?.querySelector('.sentmessage') ?? null,
|
||||
self: () => successSection,
|
||||
}
|
||||
};
|
||||
|
||||
contactForm.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
({ resendButtonInterval } = await submitContactForm(selectors, resendButtonInterval));
|
||||
});
|
||||
|
||||
selectors.otpDialog.resendButton()?.addEventListener('click', async () => {
|
||||
({ resendButtonInterval } = await resendOtp(selectors, resendButtonInterval));
|
||||
});
|
||||
|
||||
otpForm.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
await submitOtpForm(selectors);
|
||||
});
|
||||
</script>
|
||||
</Page>
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
import Page from '../layouts/Page.astro';
|
||||
---
|
||||
|
||||
<Page title="Got lost?" description="Error page for Joe's personal website">
|
||||
<section>
|
||||
<h1>Got lost?</h1>
|
||||
|
||||
<p>
|
||||
If you’re on this page, something’s probably gone wrong. Try going to
|
||||
my <a href="/">homepage</a> instead.
|
||||
</p>
|
||||
</section>
|
||||
</Page>
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
import BlogFeed from '../components/BlogFeed.astro';
|
||||
import LinksFeed from '../components/LinksFeed.astro';
|
||||
import Me from '../components/Me.astro';
|
||||
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
|
||||
import Page from '../layouts/Page.astro';
|
||||
---
|
||||
|
||||
<Page title={SITE_TITLE} description={SITE_DESCRIPTION}>
|
||||
<Me />
|
||||
</Page>
|
||||
@@ -1,33 +0,0 @@
|
||||
import path from 'node:path';
|
||||
import rss from '@astrojs/rss';
|
||||
import type { APIContext } from 'astro';
|
||||
import LINKS from '../../data/links.ts';
|
||||
import MarkdownIt from 'markdown-it';
|
||||
|
||||
const mdParser = new MarkdownIt({
|
||||
html: true
|
||||
});
|
||||
|
||||
export async function GET(context: APIContext) {
|
||||
// `site` is guaranteed to exist because we define it in our Astro config
|
||||
const site = context.site!;
|
||||
|
||||
return rss({
|
||||
title: 'Joe Carstairs’ links',
|
||||
description: 'An assortment of links I’m accumulating.',
|
||||
customData: `
|
||||
<image>/images/headshot.webp</image>
|
||||
<language>en-GB</language>
|
||||
`,
|
||||
site: path.join(site.toString(), 'links'),
|
||||
trailingSlash: false,
|
||||
items: LINKS.map((link) => ({
|
||||
link: link.href,
|
||||
title: link.title,
|
||||
content: mdParser.render(link.description),
|
||||
pubDate: new Date(link.isoDateAdded),
|
||||
description: mdParser.render(link.description),
|
||||
author: 'Joe Carstairs',
|
||||
})),
|
||||
})
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
import { type CollectionEntry, getCollection, render } from 'astro:content';
|
||||
import MicrologPost from '../../layouts/MicrologPost.astro';
|
||||
import { renderGemtextToHtml } from '../../renderGemtextToHtml';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection('microlog');
|
||||
return posts.map((post) => ({
|
||||
params: { slug: post.id },
|
||||
props: post,
|
||||
}));
|
||||
}
|
||||
type Props = CollectionEntry<'microlog'>;
|
||||
|
||||
const { id: slug, body } = Astro.props;
|
||||
const pubDateStr = slug.replaceAll(/\.[0-9]+/g, '');
|
||||
const pubDate = new Date(pubDateStr);
|
||||
if (isNaN(pubDate.valueOf())) {
|
||||
throw new Error(`Could not construct a valid publication date for microlog post: ${slug}`);
|
||||
}
|
||||
const Content = renderGemtextToHtml(body ?? '', pubDateStr);
|
||||
---
|
||||
|
||||
<MicrologPost pubDate={pubDate} title={pubDateStr}>
|
||||
<Fragment set:html={Content}></Fragment>
|
||||
</MicrologPost>
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
import { SITE_TITLE, SITE_DESCRIPTION } from '../../consts';
|
||||
import MicrologFeed from '../../components/MicrologFeed.astro';
|
||||
import Page from '../../layouts/Page.astro';
|
||||
---
|
||||
|
||||
<Page title={SITE_TITLE} description={SITE_DESCRIPTION}>
|
||||
<MicrologFeed headingLevel={1}>
|
||||
<!-- <section>
|
||||
<p><a href="/blog/subscribe">How to subscribe to this blog</a></p>
|
||||
</section> -->
|
||||
</MicrologFeed>
|
||||
</Page>
|
||||
@@ -1,29 +0,0 @@
|
||||
import path from "node:path";
|
||||
import rss from "@astrojs/rss";
|
||||
import type { APIContext } from "astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import { renderGemtextToHtml } from "../../renderGemtextToHtml";
|
||||
|
||||
export async function GET(context: APIContext) {
|
||||
// `site` is guaranteed to exist because we define it in our Astro config
|
||||
const site = context.site!;
|
||||
const posts = await getCollection("microlog");
|
||||
|
||||
return rss({
|
||||
title: "Joe Carstairs’ microlog",
|
||||
description: "My private X feed I guess?",
|
||||
customData: `
|
||||
<image>/images/headshot.webp</image>
|
||||
<language>en-GB</language>
|
||||
`,
|
||||
site: path.join(site.toString(), "microlog"),
|
||||
trailingSlash: false,
|
||||
items: posts.map((post) => ({
|
||||
link: `/microlog/${post.id}`,
|
||||
title: post.id,
|
||||
content: renderGemtextToHtml(post.body ?? ""),
|
||||
pubDate: new Date(post.id.replace(/\.[0-9]+$/g, "")),
|
||||
author: "Joe Carstairs",
|
||||
})),
|
||||
});
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
import * as Gemtext from "gemtext";
|
||||
|
||||
export function renderGemtextToHtml(gemtext: string, title?: string): string {
|
||||
gemtext = title ? gemtext.replace(`# ${title}`, "") : gemtext;
|
||||
return postProcessGemtextToHtml(
|
||||
Gemtext.parse(gemtext).generate(GemtextHTMLRenderer),
|
||||
);
|
||||
}
|
||||
|
||||
const GemtextHTMLRenderer: Gemtext.Renderer<string> = {
|
||||
preamble: function (): string {
|
||||
return "";
|
||||
},
|
||||
|
||||
postamble: function (): string {
|
||||
return "";
|
||||
},
|
||||
|
||||
text: function (content: string): string {
|
||||
content = content.trim();
|
||||
if (content === "") {
|
||||
return "";
|
||||
}
|
||||
return `<p>${htmlEscape(content)}</p>`;
|
||||
},
|
||||
|
||||
link: function (url: string, alt: string): string {
|
||||
const imgExtensions: (string | undefined)[] = [
|
||||
"webp",
|
||||
"png",
|
||||
"svg",
|
||||
"gif",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"apng",
|
||||
];
|
||||
if (imgExtensions.includes(url.split(".").at(-1)?.toLowerCase())) {
|
||||
return `<img src="${url}" alt="${alt}" />`;
|
||||
}
|
||||
return `<p>=> <a href="${url}">${alt}</a></p>`;
|
||||
},
|
||||
|
||||
preformatted: function (content: string[], alt: string): string {
|
||||
return `<pre alt="${alt}">${htmlEscape(content.join("\n"))}</pre>`;
|
||||
},
|
||||
|
||||
heading: function (level: number, text: string): string {
|
||||
return `<h${level}>${htmlEscape(text)}</h${level}>`;
|
||||
},
|
||||
|
||||
unorderedList: function (content: string[]): string {
|
||||
return `<ul>${content.map((li) => `<li>${htmlEscape(li)}</li>`).join("")}</ul>`;
|
||||
},
|
||||
|
||||
quote: function (content: string): string {
|
||||
return `<blockquote>${htmlEscape(content)}</blockquote>`;
|
||||
},
|
||||
};
|
||||
|
||||
function htmlEscape(str: string) {
|
||||
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
}
|
||||
|
||||
function postProcessGemtextToHtml(html: string): string {
|
||||
html = mergeAdjacentBlockquotes(html);
|
||||
return html;
|
||||
}
|
||||
|
||||
function mergeAdjacentBlockquotes(html: string): string {
|
||||
return html.replaceAll(/\<\/blockquote\>\<blockquote\>/gm, "<br>");
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import type { Selectors } from "./selectors";
|
||||
|
||||
export function postErrorMessageOnContactForm(
|
||||
{ contactForm }: Selectors,
|
||||
errorMsg: string,
|
||||
) {
|
||||
const errorElem = contactForm.errorElem();
|
||||
if (errorElem) {
|
||||
errorElem.textContent = errorMsg;
|
||||
errorElem.removeAttribute("hidden");
|
||||
} else {
|
||||
alert(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
export function postErrorMessageOnOtpForm(
|
||||
{ otpDialog }: Selectors,
|
||||
errorMsg: string,
|
||||
) {
|
||||
const errorElem = otpDialog.errorElem();
|
||||
if (errorElem) {
|
||||
errorElem.textContent = errorMsg;
|
||||
errorElem.removeAttribute("hidden");
|
||||
} else {
|
||||
alert(errorMsg);
|
||||
}
|
||||
for (const input of otpDialog.allOtpInputs()) {
|
||||
(input as HTMLInputElement).value = "";
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import { actions } from "astro:actions";
|
||||
import { resetResendButton } from "./reset-resend-button";
|
||||
import { postErrorMessageOnOtpForm } from "./post-error-message";
|
||||
import type { Selectors } from "./selectors";
|
||||
|
||||
const fallbackErrorMsg =
|
||||
"No can do. I'm afraid joeac.net is a bit broken right now - sorry about that.";
|
||||
|
||||
export async function resendOtp(
|
||||
selectors: Selectors,
|
||||
resetButtonInterval: NodeJS.Timeout | undefined,
|
||||
): Promise<Result> {
|
||||
const result = resetResendButton(selectors, resetButtonInterval);
|
||||
const name = selectors.contactForm.nameElem()?.value;
|
||||
const email = selectors.contactForm.emailElem().value;
|
||||
|
||||
const sendOtpResult = await actions.otp.send({ type: "email", name, email });
|
||||
if (sendOtpResult.error) {
|
||||
const errorMsg = sendOtpResult.error?.toString() ?? fallbackErrorMsg;
|
||||
postErrorMessageOnOtpForm(selectors, errorMsg);
|
||||
throw sendOtpResult.error;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
type Result = {
|
||||
resendButtonInterval: NodeJS.Timeout | undefined;
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
import type { Selectors } from "./selectors";
|
||||
|
||||
export function resetResendButton(
|
||||
{ otpDialog }: Selectors,
|
||||
resendButtonInterval: NodeJS.Timeout | undefined,
|
||||
): Result {
|
||||
clearInterval(resendButtonInterval);
|
||||
|
||||
const resendButton = otpDialog.resendButton();
|
||||
if (resendButton) {
|
||||
resendButton.setAttribute("data-countdown", "60");
|
||||
resendButton.setAttribute("disabled", "");
|
||||
|
||||
resendButtonInterval = setInterval(() => {
|
||||
const countdown = +(resendButton.getAttribute("data-countdown") ?? 1) - 1;
|
||||
resendButton.setAttribute("data-countdown", countdown.toString());
|
||||
resendButton.textContent = `Resend (${countdown}s)`;
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
clearInterval(resendButtonInterval);
|
||||
resendButton.textContent = "Resend";
|
||||
resendButton.removeAttribute("disabled");
|
||||
}, 1000 * 60);
|
||||
}
|
||||
|
||||
return { resendButtonInterval };
|
||||
}
|
||||
|
||||
type Result = {
|
||||
resendButtonInterval: NodeJS.Timeout | undefined;
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
export type Selectors = {
|
||||
contactForm: {
|
||||
emailElem: () => HTMLInputElement;
|
||||
errorElem: () => Element | null;
|
||||
nameElem: () => HTMLInputElement;
|
||||
messageElem: () => HTMLTextAreaElement;
|
||||
self: () => HTMLFormElement | null;
|
||||
submitButton: () => HTMLInputElement | null;
|
||||
};
|
||||
otpDialog: {
|
||||
allOtpInputs: () => NodeListOf<HTMLInputElement>;
|
||||
errorElem: () => Element | null;
|
||||
firstOtpInput: () => HTMLInputElement | null;
|
||||
otpForm: () => HTMLFormElement | null;
|
||||
otpRecipient: () => Element | null;
|
||||
otpValidUntil: () => Element | null;
|
||||
resendButton: () => HTMLButtonElement | null;
|
||||
self: () => HTMLDialogElement;
|
||||
submitButton: () => HTMLInputElement | null;
|
||||
};
|
||||
successSection: {
|
||||
email: () => Element | null;
|
||||
message: () => Element | null;
|
||||
name: () => Element | null;
|
||||
self: () => Element | null;
|
||||
};
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
import { actions } from "astro:actions";
|
||||
import { postErrorMessageOnContactForm } from "./post-error-message";
|
||||
import { resetResendButton } from "./reset-resend-button";
|
||||
import type { Selectors } from "./selectors";
|
||||
|
||||
const fallbackErrorMsg =
|
||||
"No can do. I'm afraid joeac.net is a bit broken right now - sorry about that.";
|
||||
|
||||
export async function submitContactForm(
|
||||
selectors: Selectors,
|
||||
resendButtonInterval: NodeJS.Timeout | undefined,
|
||||
): Promise<Result> {
|
||||
const { contactForm, otpDialog } = selectors;
|
||||
|
||||
const name = contactForm.nameElem()?.value;
|
||||
const email = contactForm.emailElem().value;
|
||||
|
||||
contactForm.submitButton()?.setAttribute("disabled", "");
|
||||
const sendOtpResult = await actions.otp.send({ type: "email", name, email });
|
||||
if (sendOtpResult.error) {
|
||||
const errorMsg = sendOtpResult.error?.toString() ?? fallbackErrorMsg;
|
||||
postErrorMessageOnContactForm(selectors, errorMsg);
|
||||
throw sendOtpResult.error;
|
||||
}
|
||||
|
||||
const otpRecipient = otpDialog.otpRecipient();
|
||||
email && otpRecipient && (otpRecipient.textContent = `<${email}>`);
|
||||
const otpValidUntil = otpDialog.otpValidUntil();
|
||||
const validUntil = new Date(Date.now() + 1000 * 60 * 5);
|
||||
otpValidUntil &&
|
||||
(otpValidUntil.textContent = `until ${validUntil.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`);
|
||||
|
||||
const dialog = otpDialog.self();
|
||||
dialog.showModal();
|
||||
contactForm.submitButton()?.removeAttribute("disabled");
|
||||
dialog.addEventListener("click", function (event) {
|
||||
const rect = dialog.getBoundingClientRect();
|
||||
const isInDialog =
|
||||
rect.top <= event.clientY &&
|
||||
event.clientY <= rect.top + rect.height &&
|
||||
rect.left <= event.clientX &&
|
||||
event.clientX <= rect.left + rect.width;
|
||||
if (!isInDialog) {
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
return resetResendButton(selectors, resendButtonInterval);
|
||||
}
|
||||
|
||||
type Result = {
|
||||
resendButtonInterval: NodeJS.Timeout | undefined;
|
||||
};
|
||||
@@ -1,72 +0,0 @@
|
||||
import { actions } from "astro:actions";
|
||||
import type { Selectors } from "./selectors";
|
||||
import {
|
||||
postErrorMessageOnContactForm,
|
||||
postErrorMessageOnOtpForm,
|
||||
} from "./post-error-message";
|
||||
|
||||
const fallbackErrorMsg =
|
||||
"No can do. I'm afraid joeac.net is a bit broken right now - sorry about that.";
|
||||
|
||||
export async function submitOtpForm(selectors: Selectors) {
|
||||
const { contactForm, otpDialog, successSection } = selectors;
|
||||
const otpForm = otpDialog.otpForm();
|
||||
otpDialog.submitButton()?.setAttribute("disabled", "");
|
||||
|
||||
const otpFormData = new FormData(otpForm ?? undefined);
|
||||
const guess = [
|
||||
otpFormData.get("1"),
|
||||
otpFormData.get("2"),
|
||||
otpFormData.get("3"),
|
||||
otpFormData.get("4"),
|
||||
otpFormData.get("5"),
|
||||
otpFormData.get("6"),
|
||||
].join("");
|
||||
|
||||
const name = contactForm.nameElem()?.value;
|
||||
const email = contactForm.emailElem().value;
|
||||
const message = contactForm.messageElem()?.value;
|
||||
|
||||
const verifyResult = await actions.otp.verify({ guess, userId: email });
|
||||
if (verifyResult.error) {
|
||||
otpDialog.submitButton()?.removeAttribute("disabled");
|
||||
postErrorMessageOnOtpForm(
|
||||
selectors,
|
||||
verifyResult.error?.toString() ?? fallbackErrorMsg,
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!verifyResult.data) {
|
||||
otpDialog.submitButton()?.removeAttribute("disabled");
|
||||
postErrorMessageOnOtpForm(selectors, "Incorrect OTP. Check your email?");
|
||||
otpDialog.firstOtpInput()?.focus();
|
||||
return;
|
||||
}
|
||||
const sendmailToken = verifyResult.data;
|
||||
|
||||
const sendmailResult = await actions.sendmail({
|
||||
email,
|
||||
message: message,
|
||||
name: name,
|
||||
userId: email,
|
||||
token: sendmailToken,
|
||||
});
|
||||
if (sendmailResult.error) {
|
||||
const errorMsg = sendmailResult.error?.toString() ?? fallbackErrorMsg;
|
||||
postErrorMessageOnOtpForm(selectors, errorMsg);
|
||||
otpDialog.submitButton()?.removeAttribute("disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
const sentName = successSection.name();
|
||||
const sentEmail = successSection.email();
|
||||
const sentMessage = successSection.message();
|
||||
sentName && (sentName.textContent = name ?? "???");
|
||||
sentEmail && (sentEmail.textContent = email ?? "???");
|
||||
sentMessage && (sentMessage.textContent = message ?? "???");
|
||||
|
||||
contactForm.self()?.remove();
|
||||
successSection.self()?.removeAttribute("hidden");
|
||||
otpDialog.submitButton()?.removeAttribute("disabled");
|
||||
otpDialog.self().close();
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
class OtpForm extends HTMLElement {
|
||||
observer?: MutationObserver;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.observer = new MutationObserver(() => {
|
||||
this.clearInputs();
|
||||
this.configureInputs();
|
||||
});
|
||||
this.observer.observe(this, { childList: true, subtree: true });
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.observer?.disconnect();
|
||||
}
|
||||
|
||||
clearInputs() {
|
||||
console.log("clearing all inputs");
|
||||
const inputs = this.querySelectorAll(
|
||||
'input:not([type="submit"])',
|
||||
) as NodeListOf<HTMLInputElement>;
|
||||
for (const input of inputs) {
|
||||
input.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
configureInputs() {
|
||||
this.observer?.disconnect();
|
||||
const inputs = this.querySelectorAll(
|
||||
'input:not([type="submit"])',
|
||||
) as NodeListOf<HTMLInputElement>;
|
||||
const form = this.querySelector("form") as HTMLFormElement;
|
||||
|
||||
for (const input of inputs) {
|
||||
input.addEventListener("focus", () => {
|
||||
input.select();
|
||||
});
|
||||
|
||||
input.addEventListener("input", () => {
|
||||
if (input.value.length > 0) {
|
||||
input.value = input.value.slice(0, 1).toLocaleUpperCase();
|
||||
const nextInput = input.nextElementSibling as HTMLInputElement;
|
||||
if (nextInput) {
|
||||
nextInput.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
const submitButton = form.querySelector(
|
||||
'input[type="submit"]',
|
||||
) as HTMLInputElement;
|
||||
submitButton.focus();
|
||||
let areAllInputsEntered = true;
|
||||
inputs.forEach((input) => {
|
||||
areAllInputsEntered = areAllInputsEntered && input.value.length > 0;
|
||||
});
|
||||
if (areAllInputsEntered) {
|
||||
form.requestSubmit(submitButton);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("otp-form", OtpForm);
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"include": [
|
||||
".astro/types.d.ts",
|
||||
"**/*"
|
||||
],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
Reference in New Issue
Block a user