Component names now reflect filesystem location using / as path separator and : as namespace separator for shared components: ~sx-header → ~layouts/header ~layout-app-body → ~shared:layout/app-body ~blog-admin-dashboard → ~admin/dashboard 209 files, 4,941 replacements across all services. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
104 lines
22 KiB
Plaintext
104 lines
22 KiB
Plaintext
(defcomp ~essays/s-existentialism/essay-s-existentialism ()
|
|
(~docs/page :title "S-Existentialism"
|
|
(p :class "text-stone-500 text-sm italic mb-8"
|
|
"Existence precedes essence — and s-expressions exist before anything gives them meaning.")
|
|
(~docs/section :title "I. Existence precedes essence" :id "existence-precedes-essence"
|
|
(p :class "text-stone-600"
|
|
"In 1946, Jean-Paul " (a :href "https://en.wikipedia.org/wiki/Jean-Paul_Sartre" :class "text-violet-600 hover:underline" "Sartre") " gave a lecture called \"" (a :href "https://en.wikipedia.org/wiki/Existentialism_Is_a_Humanism" :class "text-violet-600 hover:underline" "Existentialism Is a Humanism") ".\" Its central claim: " (em "existence precedes essence") ". A paper knife is designed before it exists — someone conceives its purpose, then builds it. A human being is the opposite — we exist first, then define ourselves through our choices. There is no blueprint. There is no human nature that precedes the individual human.")
|
|
(p :class "text-stone-600"
|
|
"A React component is a paper knife. Its essence precedes its existence. Before a single line of JSX runs, React has decided what a component is: a function that returns elements, governed by the rules of hooks, reconciled by a virtual DOM, managed by a scheduler. The framework defines the essence. The developer fills in the blanks. You exist within React's concept of you.")
|
|
(p :class "text-stone-600"
|
|
"An s-expression exists before any essence is assigned to it. " (code "(div :class \"card\" (h2 title))") " is a list. That is all it is. It has no inherent meaning. It is not a component, not a template, not a function call — not yet. It is raw existence: a nested structure of symbols, keywords, and other lists, waiting.")
|
|
(p :class "text-stone-600"
|
|
"The evaluator gives it essence. " (code "render-to-html") " makes it HTML. " (code "render-to-dom") " makes it DOM nodes. " (code "aser") " makes it wire format. " (code "quote") " keeps it as data. The same expression, the same existence, can receive different essences depending on what acts on it. The expression does not know what it is. It becomes what it is used for.")
|
|
(~docs/code :lang "lisp" :code
|
|
";; The same existence, different essences:\n(define expr '(div :class \"card\" (h2 \"Hello\")))\n\n(render-to-html expr) ;; → <div class=\"card\"><h2>Hello</h2></div>\n(render-to-dom expr) ;; → [DOM Element]\n(aser expr) ;; → (div :class \"card\" (h2 \"Hello\"))\n(length expr) ;; → 4 (it's just a list)\n\n;; The expression existed before any of these.\n;; It has no essence until you give it one."))
|
|
(~docs/section :title "II. Condemned to be free" :id "condemned"
|
|
(p :class "text-stone-600"
|
|
"\"Man is condemned to be free,\" Sartre wrote in " (a :href "https://en.wikipedia.org/wiki/Being_and_Nothingness" :class "text-violet-600 hover:underline" "Being and Nothingness") ". Not free as a gift. Free as a sentence. You did not choose to be free. You cannot escape it. Every attempt to deny your freedom — by deferring to authority, convention, or nature — is " (a :href "https://en.wikipedia.org/wiki/Bad_faith_(existentialism)" :class "text-violet-600 hover:underline" "bad faith") ". You are responsible for everything you make of yourself, and the weight of that responsibility is the human condition.")
|
|
(p :class "text-stone-600"
|
|
"SX condemns you to be free. There is no framework telling you how to structure your application. No router mandating your URL patterns. No state management library imposing its model. No convention-over-configuration file tree that decides where your code goes. You have a parser, an evaluator, and fifty primitives. What you build is your responsibility.")
|
|
(p :class "text-stone-600"
|
|
"React developers are not free. They are told: components must be pure. State changes must go through hooks. Side effects must live in useEffect. The render cycle must not be interrupted. These are the commandments. Obey them and the framework rewards you with a working application. Disobey them and the framework punishes you with cryptic errors. This is not freedom. This is " (a :href "https://en.wikipedia.org/wiki/Fear_and_Trembling" :class "text-violet-600 hover:underline" "Kierkegaard's") " knight of faith, submitting to the absurd authority of the framework because the alternative — thinking for yourself — is terrifying.")
|
|
(p :class "text-stone-600"
|
|
"The SX developer has no commandments. " (code "defcomp") " is a suggestion, not a requirement — you can build components with raw lambdas if you prefer. " (code "defmacro") " gives you the power to reshape the language itself. There are no rules of hooks because there are no hooks. There are no lifecycle methods because there is no lifecycle. There is only evaluation: an expression goes in, a value comes out. What the expression contains, how the value is used — that is up to you.")
|
|
(p :class "text-stone-600"
|
|
"This is not comfortable. Freedom never is. Sartre did not say freedom was pleasant. He said it was inescapable."))
|
|
(~docs/section :title "III. Bad faith" :id "bad-faith"
|
|
(p :class "text-stone-600"
|
|
(a :href "https://en.wikipedia.org/wiki/Bad_faith_(existentialism)" :class "text-violet-600 hover:underline" "Bad faith") " is Sartre's term for the lie you tell yourself to escape freedom. The waiter who plays at being a waiter — performing the role so thoroughly that he forgets he chose it. The woman who pretends not to notice a man's intentions — denying her own awareness to avoid making a decision. Bad faith is not deception of others. It is self-deception about one's own freedom.")
|
|
(p :class "text-stone-600"
|
|
"\"We have to use React — it's the industry standard.\" Bad faith. You chose React. The industry did not force it on you. There were alternatives. You preferred the comfort of the herd.")
|
|
(p :class "text-stone-600"
|
|
"\"We need TypeScript — you can't write reliable code without a type system.\" Bad faith. " (a :href "https://en.wikipedia.org/wiki/Lisp_(programming_language)" :class "text-violet-600 hover:underline" "Lisp") " has been writing reliable code without static types since 1958. " (a :href "https://en.wikipedia.org/wiki/Erlang_(programming_language)" :class "text-violet-600 hover:underline" "Erlang") " runs telephone networks on dynamic types. You chose TypeScript because you are afraid of your own code, and the type system is a security blanket.")
|
|
(p :class "text-stone-600"
|
|
"\"We need a build step — modern web development requires it.\" Bad faith. A " (code "<script>") " tag requires no build step. An s-expression evaluator in 3,000 lines of JavaScript requires no build step. You need a build step because you chose tools that require a build step, and now you have forgotten that the choice was yours.")
|
|
(p :class "text-stone-600"
|
|
"\"Nobody uses s-expressions for web development.\" Bad faith. " (em "You") " do not use s-expressions for web development. That is a fact about you, not a fact about web development. Transforming your personal preference into a universal law is the quintessential act of bad faith.")
|
|
(p :class "text-stone-600"
|
|
"SX does not prevent bad faith — nothing can. But it makes bad faith harder. When the entire language is fifty primitives and a page of special forms, you cannot pretend that the complexity is necessary. When there is no build step, you cannot pretend that the build step is inevitable. When the same source runs on server and client, you cannot pretend that the server-client divide is ontological. SX strips away the excuses. What remains is your choices."))
|
|
(~docs/section :title "IV. Nausea" :id "nausea"
|
|
(p :class "text-stone-600"
|
|
"In " (a :href "https://en.wikipedia.org/wiki/Nausea_(novel)" :class "text-violet-600 hover:underline" "Nausea") " (1938), Sartre's Roquentin sits in a park and stares at the root of a chestnut tree. He sees it — really sees it — stripped of all the concepts and categories that normally make it comprehensible. It is not a \"root.\" It is not \"brown.\" It is not \"gnarled.\" It simply " (em "is") " — a brute, opaque, superfluous existence. The nausea is the vertigo of confronting existence without essence.")
|
|
(p :class "text-stone-600"
|
|
"Open " (code "node_modules") ". Stare at it. 47,000 directories. 1.2 gigabytes. For a to-do app. Each directory contains a " (code "package.json") ", a " (code "README.md") ", a " (code "LICENSE") ", and some JavaScript that wraps some other JavaScript that wraps some other JavaScript. There is no reason for any of it. It is not necessary. It is not justified. It simply accumulated — dependency after dependency, version after version, a brute, opaque, superfluous existence. This is " (code "node_modules") " nausea.")
|
|
(p :class "text-stone-600"
|
|
"SX has its own nausea. Stare at a page of s-expressions long enough and the same vertigo hits. Parentheses. Symbols. Lists inside lists inside lists. There is nothing behind them — no hidden runtime, no compiled intermediate form, no framework magic. Just parentheses. The s-expression is Roquentin's chestnut root: it simply " (em "is") ". You cannot unsee it.")
|
|
(p :class "text-stone-600"
|
|
"But SX's nausea is honest. The chestnut root is really there — it exists, bare and exposed. The " (code "node_modules") " nausea is different: it is nausea at something that should not exist, that has no reason to exist, that exists only because of accumulated accidents of dependency resolution. SX's nausea is existential — the dizziness of confronting raw structure. The JavaScript ecosystem's nausea is absurd — the dizziness of confronting unnecessary complexity that no one chose but everyone maintains."))
|
|
(~docs/section :title "V. The absurd" :id "absurd"
|
|
(p :class "text-stone-600"
|
|
(a :href "https://en.wikipedia.org/wiki/Albert_Camus" :class "text-violet-600 hover:underline" "Camus") " defined the " (a :href "https://en.wikipedia.org/wiki/Absurdism" :class "text-violet-600 hover:underline" "absurd") " as the gap between human longing for meaning and the universe's silence. We want the world to make sense. It does not. The absurd is not in us or in the world — it is in the confrontation between the two.")
|
|
(p :class "text-stone-600"
|
|
"Web development is absurd. We want simple, composable, maintainable software. The industry gives us webpack configurations, framework migrations, and breaking changes in minor versions. We want to write code and run it. The industry gives us transpilers, bundlers, minifiers, tree-shakers, and hot-module-replacers. The gap between what we want and what we get is the absurd.")
|
|
(p :class "text-stone-600"
|
|
"Writing a Lisp for the web is also absurd — but in a different register. Nobody asked for it. Nobody wants it. The parentheses are off-putting. The ecosystem is nonexistent. The job market is zero. There is no rational justification for building SX when React exists, when Vue exists, when Svelte exists, when the entire weight of the industry points in the other direction.")
|
|
(p :class "text-stone-600"
|
|
"Camus said there are three responses to the absurd. " (a :href "https://en.wikipedia.org/wiki/The_Myth_of_Sisyphus" :class "text-violet-600 hover:underline" "Suicide") " — giving up. " (a :href "https://en.wikipedia.org/wiki/Leap_of_faith" :class "text-violet-600 hover:underline" "Philosophical suicide") " — leaping into faith, pretending the absurd has been resolved. Or " (em "revolt") " — continuing without resolution, fully aware that the project is meaningless, and doing it anyway.")
|
|
(p :class "text-stone-600"
|
|
"Most developers commit philosophical suicide. They adopt a framework, declare it The Way, and stop questioning. React is the truth. TypeScript is salvation. The build step is destiny. The absurd disappears — not because it has been resolved, but because they have stopped looking at it.")
|
|
(p :class "text-stone-600"
|
|
"SX is revolt. It does not resolve the absurd. It does not pretend that s-expressions are the answer, that parentheses will save the web, that the industry will come around. It simply continues — writing components, specifying evaluators, bootstrapping to new targets — with full awareness that the project may never matter to anyone. This is the only honest response to the absurd."))
|
|
(~docs/section :title "VI. Sisyphus" :id "sisyphus"
|
|
(p :class "text-stone-600"
|
|
"\"" (a :href "https://en.wikipedia.org/wiki/The_Myth_of_Sisyphus" :class "text-violet-600 hover:underline" "One must imagine Sisyphus happy") ".\"")
|
|
(p :class "text-stone-600"
|
|
"Sisyphus pushes a boulder up a hill. It rolls back down. He pushes it up again. Forever. Camus argues that Sisyphus is the absurd hero: he knows the task is pointless, he does it anyway, and in the doing — in the conscious confrontation with futility — he finds something that transcends the futility.")
|
|
(p :class "text-stone-600"
|
|
"The framework developer is Sisyphus too, but an unconscious one. React 16 to 17 to 18. Class components to hooks to server components. Each migration is the boulder. Each major version is the hill. The developer pushes the codebase up, and the next release rolls it back down. But the framework developer does not " (em "know") " they are Sisyphus. They believe each migration is progress. They believe the boulder will stay at the top this time. This is philosophical suicide — the leap of faith that the next version will be the last.")
|
|
(p :class "text-stone-600"
|
|
"The SX developer is conscious Sisyphus. The boulder is obvious: writing a Lisp for the web is absurd. The hill is obvious: nobody will use it. But consciousness changes everything. Camus's Sisyphus is happy not because the task has meaning but because " (em "he") " has chosen it. The choice — the revolt — is the meaning. Not the outcome.")
|
|
(p :class "text-stone-600"
|
|
"One must imagine the s-expressionist happy."))
|
|
(~docs/section :title "VII. Thrownness" :id "thrownness"
|
|
(p :class "text-stone-600"
|
|
(a :href "https://en.wikipedia.org/wiki/Martin_Heidegger" :class "text-violet-600 hover:underline" "Heidegger's") " " (a :href "https://en.wikipedia.org/wiki/Thrownness" :class "text-violet-600 hover:underline" "Geworfenheit") " — thrownness — describes the condition of finding yourself already in a world you did not choose. You did not pick your language, your culture, your body, your historical moment. You were " (em "thrown") " into them. Authenticity is not escaping thrownness but owning it — relating to your situation as yours, rather than pretending it was inevitable or that you could have been elsewhere.")
|
|
(p :class "text-stone-600"
|
|
"SX is thrown into the web. It did not choose HTTP, the DOM, CSS, JavaScript engines, or browser security models. These are the givens — the facticity of web development. Every web technology is thrown into this same world. The question is how you relate to it.")
|
|
(p :class "text-stone-600"
|
|
"React relates to the DOM by replacing it — the virtual DOM is a denial of thrownness, an attempt to build a world that is not the one you were thrown into, then reconcile the two. Angular relates to JavaScript by replacing it — TypeScript, decorators, dependency injection, a whole parallel universe layered over the given one. These are inauthentic responses to thrownness: instead of owning the situation, they construct an alternative and pretend it is the real one.")
|
|
(p :class "text-stone-600"
|
|
"SX owns its thrownness. It runs in the browser's JavaScript engine — not because JavaScript is good, but because the browser is the world it was thrown into. It produces DOM nodes — not because the DOM is elegant, but because the DOM is what exists. It sends HTTP responses — not because HTTP is ideal, but because HTTP is the wire. SX does not build a virtual DOM to escape the real DOM. It does not invent a type system to escape JavaScript's types. It evaluates s-expressions in the given environment and produces what the environment requires.")
|
|
(p :class "text-stone-600"
|
|
"The s-expression is itself a kind of primordial thrownness. It did not choose to be the minimal recursive data structure. It simply is. Open paren, atoms, close paren. It was not designed by committee, not optimised by industry, not evolved through market pressure. It was " (a :href "https://en.wikipedia.org/wiki/Lisp_(programming_language)#History" :class "text-violet-600 hover:underline" "discovered in 1958") " as a notational convenience and turned out to be the bedrock. SX was thrown into s-expressions the way humans are thrown into bodies — not by choice, but by the nature of what it is."))
|
|
(~docs/section :title "VIII. The Other" :id "the-other"
|
|
(p :class "text-stone-600"
|
|
"Sartre's account of " (a :href "https://en.wikipedia.org/wiki/Being_and_Nothingness#The_Other_and_the_Look" :class "text-violet-600 hover:underline" "the Other") " in Being and Nothingness: I am alone in a park. I am the centre of my world. Then I see another person. Suddenly I am seen. I am no longer just a subject — I am an object in someone else's world. The Other's gaze transforms me. \"Hell is other people,\" Sartre wrote in " (a :href "https://en.wikipedia.org/wiki/No_Exit" :class "text-violet-600 hover:underline" "No Exit") " — not because others are cruel, but because they see you, and their seeing limits your freedom to define yourself.")
|
|
(p :class "text-stone-600"
|
|
"Every framework exists under the gaze of the Other. React watches what Vue does. Vue watches what Svelte does. Svelte watches what Solid does. Each framework defines itself partly through the Other — \"we are not React,\" \"we are faster than Vue,\" \"we are simpler than Angular.\" The benchmark is the Other. The identity is relational. No framework is free to be purely itself, because the Others are always watching.")
|
|
(p :class "text-stone-600"
|
|
"SX has no Other. There is no competing s-expression web framework to define itself against. There is no benchmark to win, no market to capture, no conference talk to rebut. This is either pathetic (no ecosystem, no community, no relevance) or liberating (no gaze, no comparison, no borrowed identity). Sartre would say it is both.")
|
|
(p :class "text-stone-600"
|
|
"But there is another sense of the Other that matters more. The Other " (em "evaluator") ". SX's self-hosting spec means that the language encounters itself as Other. " (code "eval.sx") " is written in SX — the language looking at itself, seeing itself from outside. The bootstrap compiler reads this self-description and produces a working evaluator. The language has been seen by its own gaze, and the seeing has made it real. This is Sartre's intersubjectivity turned reflexive: the subject and the Other are the same entity."))
|
|
(~docs/section :title "IX. Authenticity" :id "authenticity"
|
|
(p :class "text-stone-600"
|
|
"For both Heidegger and Sartre, " (a :href "https://en.wikipedia.org/wiki/Authenticity_(philosophy)" :class "text-violet-600 hover:underline" "authenticity") " means facing your situation — your freedom, your thrownness, your mortality — without evasion. The inauthentic person hides in the crowd, adopts the crowd's values, speaks the crowd's language. Heidegger called this " (a :href "https://en.wikipedia.org/wiki/Heideggerian_terminology#Das_Man" :class "text-violet-600 hover:underline" "das Man") " — the \"They.\" \"They say React is best.\" \"They use TypeScript.\" \"They have build steps.\" The They is not a conspiracy. It is the comfortable anonymity of doing what everyone does.")
|
|
(p :class "text-stone-600"
|
|
"Authenticity in web development would mean confronting what you are actually doing: arranging symbols so that a machine produces visual output. That is all web development is. Not \"building products.\" Not \"crafting experiences.\" Not \"shipping value.\" Arranging symbols. The frameworks, the methodologies, the Agile ceremonies — all of it is das Man, the They, the comfortable obfuscation of a simple truth.")
|
|
(p :class "text-stone-600"
|
|
"SX is more authentic than most — not because s-expressions are morally superior, but because they are harder to hide behind. There is no CLI that generates boilerplate. No convention that tells you where files go. No community consensus on the Right Way. You write expressions. You evaluate them. You see what they produce. The gap between what you do and what happens is as small as it can be.")
|
|
(p :class "text-stone-600"
|
|
"De Beauvoir added something Sartre did not: authenticity requires that you " (a :href "https://en.wikipedia.org/wiki/The_Ethics_of_Ambiguity" :class "text-violet-600 hover:underline" "will the freedom of others") ", not just your own. A language that locks you into one runtime, one vendor, one ecosystem is inauthentic — it denies others the freedom it claims for itself. SX's self-hosting spec is an act of de Beauvoirian ethics: by defining the language in itself, in a format that any reader can parse, any compiler can target, any host can implement, it wills the freedom of every future evaluator. The spec is public. The language is portable. Your freedom to re-implement, to fork, to understand — that freedom is not a side effect. It is the point.")
|
|
(p :class "text-stone-600"
|
|
"Existence precedes essence. The s-expression exists — bare, parenthesised, indifferent — before any evaluator gives it meaning. What it becomes is up to you. This is not a limitation. It is the only freedom there is."))))
|