From 28cbe60dc63214b80950b328c1d4d948cfff7968 Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 4 Mar 2026 12:55:12 +0000 Subject: [PATCH] Add 78 links throughout the SX Manifesto essay External links to Google, Meta, webpack, Vercel, Stack Overflow, React, Vue, Angular, Svelte, SolidJS, Qwik, Astro, Next, Nuxt, Remix, Gatsby, Rollup, Parcel, esbuild, Vite, Turbopack, TypeScript, Emacs, Clojure, npm, Lisp, Scheme, Brendan Eich, Tailwind, Sass, Less, PostCSS, XML, XSLT, JSON, YAML, TOML, JSX, SFCs, Lodash, Moment, Axios, left-pad, is-odd, CSS-in-JS, virtual DOM, Vicar of Bray, CGI-bin, and Marx. Internal links to /docs/components, /docs/evaluator, /docs/primitives, /docs/css, /essays/on-demand-css, /protocols/wire-format. Co-Authored-By: Claude Opus 4.6 --- sx/sxc/pages/__init__.py | 162 ++++++++++++++++++++++++--------------- 1 file changed, 102 insertions(+), 60 deletions(-) diff --git a/sx/sxc/pages/__init__.py b/sx/sxc/pages/__init__.py index 7a19bc7..37bd447 100644 --- a/sx/sxc/pages/__init__.py +++ b/sx/sxc/pages/__init__.py @@ -2442,19 +2442,33 @@ def _essay_sx_native() -> str: def _essay_sx_manifesto() -> str: p = '(p :class "text-stone-600"' em = '(span :class "italic"' + L = "text-violet-600 hover:underline" + + def x(url: str, text: str) -> str: + """External link.""" + return f'(a :href "{url}" :class "{L}" :target "_blank" "{text}")' + + def i(path: str, text: str) -> str: + """Internal SX app link.""" + return (f'(a :href "{path}" :sx-get "{path}" :sx-target "#main-panel"' + f' :sx-select "#main-panel" :sx-swap "outerHTML" :sx-push-url "true"' + f' :class "{L}" "{text}")') + return ( '(~doc-page :title "The SX Manifesto"' ' (p :class "text-stone-500 text-sm italic mb-8"' - ' "After " (a :href "https://www.marxists.org/archive/marx/works/1848/communist-manifesto/"' - ' :class "text-violet-600 hover:underline" "Marx & Engels") ", loosely")' + f' "After " {x("https://www.marxists.org/archive/marx/works/1848/communist-manifesto/", "Marx & Engels")} ", loosely")' # --- I. A spectre is haunting the web --- ' (~doc-section :title "I. A spectre is haunting the web" :id "spectre"' f' {p}' - ' "A spectre is haunting the web — the spectre of s-expressions. ' - 'All the powers of the old web have entered into a holy alliance to exorcise this spectre: ' - 'Google and Meta, webpack and Vercel, Stack Overflow moderators and DevRel influencers.")' + ' "A spectre is haunting the web — the spectre of ' + f's-expressions. ' + f'All the powers of the old web have entered into a holy alliance to exorcise this spectre: "' + f' {x("https://google.com", "Google")} " and " {x("https://about.meta.com", "Meta")} ", "' + f' {x("https://webpack.js.org", "webpack")} " and " {x("https://vercel.com", "Vercel")} ", "' + f' {x("https://stackoverflow.com", "Stack Overflow")} " moderators and DevRel influencers.")' f' {p}' ' "Where is the rendering paradigm that has not been decried as ' 'a step backward by its opponents? Where is the framework that has not ' @@ -2480,15 +2494,23 @@ def _essay_sx_manifesto() -> str: ' "Markup and logic, template and script, structure and style — ' 'in a word, oppressor and oppressed — stood in constant opposition to one another, ' 'carried on an uninterrupted, now hidden, now open fight, ' - 'a fight that each time ended in a laborious reconfiguration of webpack.")' + f'a fight that each time ended in a laborious reconfiguration of " {x("https://webpack.js.org", "webpack")} ".")' f' {p}' ' "In the earlier epochs of web development we find almost everywhere ' 'a complicated arrangement of separate languages into various orders, ' 'a manifold gradation of technical rank: ' - 'HTML, CSS, JavaScript, XML, XSLT, JSON, YAML, TOML, JSX, TSX, ' - 'Sass, Less, PostCSS, Tailwind, and above them all, the build step.")' + f'HTML, CSS, JavaScript, " {x("https://www.w3.org/XML/", "XML")} ", "' + f' {x("https://www.w3.org/TR/xslt/", "XSLT")} ", "' + f' {x("https://www.json.org", "JSON")} ", "' + f' {x("https://yaml.org", "YAML")} ", "' + f' {x("https://toml.io", "TOML")} ", "' + f' {x("https://react.dev/learn/writing-markup-with-jsx", "JSX")} ", TSX, "' + f' {x("https://sass-lang.com", "Sass")} ", "' + f' {x("https://lesscss.org", "Less")} ", "' + f' {x("https://postcss.org", "PostCSS")} ", "' + f' {x("https://tailwindcss.com", "Tailwind")} ", and above them all, the build step.")' f' {p}' - ' "The modern web, sprouted from the ruins of CGI-bin, ' + f' "The modern web, sprouted from the ruins of " {x("https://en.wikipedia.org/wiki/Common_Gateway_Interface", "CGI-bin")} ", ' 'has not done away with language antagonisms. It has but established new languages, ' 'new conditions of oppression, new forms of struggle in place of the old ones.")' f' {p}' @@ -2513,7 +2535,7 @@ def _essay_sx_manifesto() -> str: 'Like every revolutionary who becomes a tyrant, ' 'it kept the worst habits of the regime it overthrew: ' 'weak typing, prototype chains, and the "' - f' {em} \"this\")' + f' {em} \\"this\\")' ' " keyword.")' f' {p}' ' "CSS, the third estate, controls all visual presentation ' @@ -2522,7 +2544,7 @@ def _essay_sx_manifesto() -> str: 'It has no variables. Then it had variables. ' 'It has no nesting. Then it had nesting. ' 'It is not a programming language. Then it was Turing-complete. ' - 'CSS is the Vicar of Bray of web technologies — ' + f'CSS is the " {x("https://en.wikipedia.org/wiki/The_Vicar_of_Bray", "Vicar of Bray")} " of web technologies — ' 'loyal to whichever paradigm currently holds power.")' f' {p}' ' "These three languages rule by enforced separation. ' @@ -2537,8 +2559,18 @@ def _essay_sx_manifesto() -> str: ' (~doc-section :title "IV. The petty-bourgeois frameworks" :id "frameworks"' f' {p}' ' "Between the ruling languages and the oppressed developer, ' - 'a vast class of intermediaries has arisen: the frameworks. ' - 'React, Vue, Angular, Svelte, Solid, Qwik, Astro, Next, Nuxt, Remix, Gatsby, ' + f'a vast class of intermediaries has arisen: the frameworks. "' + f' {x("https://react.dev", "React")} ", "' + f' {x("https://vuejs.org", "Vue")} ", "' + f' {x("https://angular.dev", "Angular")} ", "' + f' {x("https://svelte.dev", "Svelte")} ", "' + f' {x("https://www.solidjs.com", "Solid")} ", "' + f' {x("https://qwik.dev", "Qwik")} ", "' + f' {x("https://astro.build", "Astro")} ", "' + f' {x("https://nextjs.org", "Next")} ", "' + f' {x("https://nuxt.com", "Nuxt")} ", "' + f' {x("https://remix.run", "Remix")} ", "' + f' {x("https://www.gatsbyjs.com", "Gatsby")} ", ' 'and ten thousand others whose names will not survive the decade.")' f' {p}' ' "The frameworks are the petty bourgeoisie of web development. ' @@ -2547,27 +2579,32 @@ def _essay_sx_manifesto() -> str: 'extracting rent in the form of configuration files, ' 'build pipelines, and breaking changes.")' f' {p}' - ' "Each framework promises liberation. Each framework delivers a new dependency tree. ' - 'React freed us from manual DOM manipulation and gave us a virtual DOM, ' + f' "Each framework promises liberation. Each framework delivers a new dependency tree. "' + f' {x("https://react.dev", "React")} " freed us from manual DOM manipulation and gave us a "' + f' {x("https://legacy.reactjs.org/docs/faq-internals.html", "virtual DOM")} ", ' 'a reconciler, hooks with seventeen rules, ' - 'and a conference circuit. ' - 'Vue freed us from React\'s complexity and gave us the Options API, ' - 'then the Composition API, then told us the Options API was fine actually. ' - 'Angular freed us from choice and gave us a CLI that generates eleven files ' - 'to display \\\"Hello World.\\\" ' - 'Svelte freed us from the virtual DOM and gave us a compiler. ' - 'SolidJS freed us from React\'s re-rendering and gave us signals, ' + f'and a conference circuit. "' + f' {x("https://vuejs.org", "Vue")} " freed us from React\'s complexity and gave us the Options API, ' + f'then the Composition API, then told us the Options API was fine actually. "' + f' {x("https://angular.dev", "Angular")} " freed us from choice and gave us a CLI that generates eleven files ' + f'to display \\\"Hello World.\\\" "' + f' {x("https://svelte.dev", "Svelte")} " freed us from the virtual DOM and gave us a compiler. "' + f' {x("https://www.solidjs.com", "SolidJS")} " freed us from React\'s re-rendering and gave us signals, ' 'which React then adopted, completing the circle.")' f' {p}' ' "The frameworks reproduce the very conditions they claim to abolish. ' 'They bridge the gap between HTML, JavaScript, and CSS ' - 'by adding a fourth language — JSX, SFCs, templates — ' + f'by adding a fourth language — " {x("https://react.dev/learn/writing-markup-with-jsx", "JSX")} ", "' + f' {x("https://vuejs.org/guide/scaling-up/sfc.html", "SFCs")} ", templates — ' 'which must itself be compiled back into the original three. ' 'The revolution merely adds a build step.")' f' {p}' ' "And beside the frameworks stand the libraries — ' - 'the lumpenproletariat of the ecosystem. ' - 'Lodash, Moment, Axios, left-pad. ' + f'the lumpenproletariat of the ecosystem. "' + f' {x("https://lodash.com", "Lodash")} ", "' + f' {x("https://momentjs.com", "Moment")} ", "' + f' {x("https://axios-http.com", "Axios")} ", "' + f' {x("https://www.npmjs.com/package/left-pad", "left-pad")} ". ' 'They attach themselves to whichever framework currently holds power, ' 'contributing nothing original, merely wrapping what already exists, ' 'adding weight to the node_modules directory until it exceeds the mass of the sun."))' @@ -2576,19 +2613,24 @@ def _essay_sx_manifesto() -> str: ' (~doc-section :title "V. The build step as the state apparatus" :id "build-step"' f' {p}' - ' "The build step is the state apparatus of the framework bourgeoisie. ' - 'It enforces the class structure. It compiles JSX into createElement calls. ' - 'It transforms TypeScript into JavaScript. It processes Sass into CSS. ' + f' "The build step is the state apparatus of the framework bourgeoisie. ' + f'It enforces the class structure. It compiles " {x("https://react.dev/learn/writing-markup-with-jsx", "JSX")} " into createElement calls. ' + f'It transforms " {x("https://www.typescriptlang.org", "TypeScript")} " into JavaScript. ' + f'It processes " {x("https://sass-lang.com", "Sass")} " into CSS. ' 'It tree-shakes. It code-splits. It hot-module-replaces. ' 'It does everything except let you write code and run it.")' f' {p}' - ' "webpack begat Rollup. Rollup begat Parcel. Parcel begat esbuild. ' - 'esbuild begat Vite. Vite begat Turbopack. ' + f' " " {x("https://webpack.js.org", "webpack")} " begat " {x("https://rollupjs.org", "Rollup")} ". ' + f'Rollup begat " {x("https://parceljs.org", "Parcel")} ". ' + f'Parcel begat " {x("https://esbuild.github.io", "esbuild")} ". ' + f'esbuild begat " {x("https://vite.dev", "Vite")} ". ' + f'Vite begat " {x("https://turbo.build/pack", "Turbopack")} ". ' 'Each new bundler promises to be the last bundler. ' 'Each new bundler is faster than the last at doing something ' 'that should not need to be done at all.")' f' {p}' - ' "The build step exists because the ruling languages cannot express components. ' + ' "The build step exists because the ruling languages cannot express ' + f'" {i("/docs/components", "components")} ". ' 'HTML has no composition model. CSS has no scoping. JavaScript has no template syntax. ' 'The build step papers over these failures with transpilation, ' 'and calls it developer experience."))' @@ -2597,7 +2639,7 @@ def _essay_sx_manifesto() -> str: ' (~doc-section :title "VI. The s-expression revolution" :id "revolution"' f' {p}' - ' "The s-expression abolishes the language distinction itself. ' + f' "The " {x("https://en.wikipedia.org/wiki/S-expression", "s-expression")} " abolishes the language distinction itself. ' 'There is no HTML. There is no separate JavaScript. ' 'There is no CSS-as-a-separate-language. ' 'There is only the expression.")' @@ -2605,23 +2647,23 @@ def _essay_sx_manifesto() -> str: ' "Code is data. Data is DOM. DOM is code. ' 'The dialectical unity that HTML, JavaScript, and CSS ' 'could never achieve — because they are three languages pretending to be one system — ' - 'is the natural state of the s-expression, ' - 'which has been one language since 1958.")' + f'is the natural state of the s-expression, ' + f'which has been one language " {x("https://en.wikipedia.org/wiki/Lisp_(programming_language)", "since 1958")} ".")' f' {p}' - ' "The component is not a class, not a function, not a template. ' + f' "The " {i("/docs/components", "component")} " is not a class, not a function, not a template. ' 'The component is a list whose first element is a symbol. ' 'Composition is nesting. Abstraction is binding. ' - 'There is no JSX because there is no gap between the expression language ' + f'There is no JSX because there is no gap between the expression language ' 'and the thing being expressed.")' f' {p}' ' "The build step is abolished because there is nothing to compile. ' 'S-expressions are already in their final form. ' - 'The parser is thirty lines. The evaluator is fifty primitives. ' + f'The parser is thirty lines. The " {i("/docs/evaluator", "evaluator")} " is fifty " {i("/docs/primitives", "primitives")} ". ' 'The same source runs on server and client without transformation.")' f' {p}' ' "The framework is abolished because the language is the framework. ' - 'defcomp replaces the component model. defmacro replaces the plugin system. ' - 'The evaluator replaces the runtime. ' + f'" {i("/docs/components", "defcomp")} " replaces the component model. defmacro replaces the plugin system. ' + f'The " {i("/docs/evaluator", "evaluator")} " replaces the runtime. ' 'What remains is not a framework but a language — ' 'and languages do not have breaking changes between minor versions."))' @@ -2630,29 +2672,29 @@ def _essay_sx_manifesto() -> str: ' (~doc-section :title "VII. Objections from the bourgeoisie" :id "objections"' f' {p}' ' "\\\"You would destroy the separation of concerns!\\\" they cry. ' - 'The separation of concerns was destroyed long ago. ' - 'React components contain markup, logic, and inline styles. ' - 'Vue single-file components put template, script, and style in one file. ' - 'Tailwind puts styling in the markup. ' + f'The separation of concerns was destroyed long ago. "' + f' {x("https://react.dev", "React")} " components contain markup, logic, and inline styles. "' + f' {x("https://vuejs.org/guide/scaling-up/sfc.html", "Vue single-file components")} " put template, script, and style in one file. "' + f' {x("https://tailwindcss.com", "Tailwind")} " puts styling in the markup. ' 'The separation of concerns has been dead for years; ' 'the ruling classes merely maintain the pretence at conferences.")' f' {p}' - ' "\\\"Nobody uses s-expressions!\\\" they cry. ' - 'Emacs has been running on s-expressions since 1976. ' - 'Clojure runs Fortune 500 backends on s-expressions. ' - 'Every Lisp programmer who ever lived has known what the web refuses to admit: ' + ' "\\\"Nobody uses s-expressions!\\\" they cry. "' + f' {x("https://www.gnu.org/software/emacs/", "Emacs")} " has been running on s-expressions since 1976. "' + f' {x("https://clojure.org", "Clojure")} " runs Fortune 500 backends on s-expressions. ' + f'Every " {x("https://en.wikipedia.org/wiki/Lisp_(programming_language)", "Lisp")} " programmer who ever lived has known what the web refuses to admit: ' 'that the parenthesis is not a bug but the minimal syntax for structured data.")' f' {p}' ' "\\\"Where is the ecosystem?\\\" they cry. ' - 'The ecosystem is the problem. Two million npm packages, ' + f'The ecosystem is the problem. Two million " {x("https://www.npmjs.com", "npm")} " packages, ' 'of which fourteen are useful and the rest are competing implementations ' - 'of is-odd. The s-expression needs no ecosystem because ' + f'of " {x("https://www.npmjs.com/package/is-odd", "is-odd")} ". The s-expression needs no ecosystem because ' 'the language itself provides what packages exist to paper over: ' 'composition, abstraction, and code-as-data.")' f' {p}' - ' "\\\"But TypeScript!\\\" they cry. TypeScript is a type system ' - 'bolted onto a language that was designed in ten days ' - 'by a man who wanted to write Scheme. ' + f' "\\\"But " {x("https://www.typescriptlang.org", "TypeScript")} "!\\\" they cry. TypeScript is a type system ' + f'bolted onto a language that was designed in ten days ' + f'by " {x("https://en.wikipedia.org/wiki/Brendan_Eich", "a man")} " who wanted to write " {x("https://en.wikipedia.org/wiki/Scheme_(programming_language)", "Scheme")} ". ' 'We have simply completed his original vision.")' f' {p}' ' "\\\"You have no jobs!\\\" they cry. Correct. ' @@ -2670,22 +2712,22 @@ def _essay_sx_manifesto() -> str: 'it is the collaborator class, providing aesthetic legitimacy ' 'to whichever regime currently holds power.")' f' {p}' - ' "CSS-in-JS was the first attempt at annexation: ' + f' " " {x("https://en.wikipedia.org/wiki/CSS-in-JS", "CSS-in-JS")} " was the first attempt at annexation: ' 'JavaScript consuming CSS entirely, reducing it to template literals ' 'and runtime overhead. ' 'This provocation produced the counter-revolution of utility classes — ' - 'Tailwind — which reasserted CSS\'s independence ' + f'" {x("https://tailwindcss.com", "Tailwind")} " — which reasserted CSS\'s independence ' 'by making the developer write CSS in HTML attributes ' 'while insisting this was not inline styles.")' f' {p}' ' "The s-expression resolves the CSS question by eliminating it. ' - 'Styles are expressions. "' + f'Styles are " {i("/docs/css", "expressions")} ". "' ' (code :class "text-violet-700" "(css :flex :gap-4 :p-2)")' ' " is not a class name, not an inline style, not a CSS-in-JS template literal. ' 'It is a function call that returns a value. ' 'The value produces a generated class. ' - 'The class is delivered on demand. ' - 'No build step. No runtime overhead. No Tailwind config.")' + f'The class is " {i("/essays/on-demand-css", "delivered on demand")} ". ' + f'No build step. No runtime overhead. No " {x("https://tailwindcss.com", "Tailwind")} " config.")' f' {p}' ' "Code is data is DOM is " ' f' {em} "style") "."))' @@ -2704,12 +2746,12 @@ def _essay_sx_manifesto() -> str: ' (ol :class "space-y-2 text-stone-600 mt-2 list-decimal list-inside"' ' (li "Abolition of the build step and all its instruments of compilation")' ' (li "Abolition of the framework as a class distinct from the language")' - ' (li "Centralisation of rendering in the hands of a single evaluator, ' + f' (li "Centralisation of rendering in the hands of a single " {i("/docs/evaluator", "evaluator")} ", ' 'running identically on server and client")' ' (li "Abolition of the language distinction between structure, style, and behaviour")' ' (li "Equal obligation of all expressions to be data as well as code")' - ' (li "Gradual abolition of the distinction between server and client ' - 'by means of a uniform wire protocol")' + f' (li "Gradual abolition of the distinction between server and client ' + f'by means of a uniform " {i("/protocols/wire-format", "wire protocol")} ")' ' (li "Free evaluation for all expressions in public and private environments")' ' (li "Abolition of the node_modules directory " ' ' (span :class "text-stone-400 italic" "(this alone justifies the revolution)")))'