The meaning of existence vs the purpose of a program

cogito_ergo_sum.py

Series: A Programmer’s Philosophical Reflections #03/11 | Reading time: 25-30 min | Concept: Philosophy of Mind — Consciousness, the Self, and Artificial Intelligence

Author: Wina @ Code & Cogito


The Program That Said “I”

It started with a health check endpoint.

Our system had been acting up, so the team added an automated self-monitoring layer: every few seconds, the system checked its own CPU usage, memory consumption, and response latency. If any metric exceeded a threshold, it would automatically degrade non-critical features, write a log entry, and notify the on-call engineer.

One night, the monitoring system’s alert woke me up. I reached for my phone and found an auto-generated report:

“Memory leak detected. Cache module disabled. Currently running in degraded mode. Awaiting manual intervention.”

I stared at those words and felt something strange.

This system was observing itself. It knew its own state. It had made a decision based on that state. It was even reporting its situation in what amounted to a first-person narrative.

If a system can describe its own state, evaluate its own behavior, and correct its own strategy — does it already have some form of “self”?

I know the rational answer: no. It’s just executing predefined rules.

But that night, the “rational answer” suddenly felt insufficient. Because I started asking a sharper question: how do you know that you’re not just “executing predefined rules”? Your brain monitors body temperature, blood sugar, fatigue levels. It triggers responses when things go wrong — you yawn, you feel pain, you get anxious. You “decide” to go to sleep, but was that decision really made by “you,” or did your nervous system hit a threshold and fire a “run sleep.exe” instruction?

Four centuries ago, a Frenchman was kept awake by a very similar question. His solution redirected the entire course of Western philosophy.


Background: Descartes’ Methodological Doubt

Systematically Doubting Everything

Rene Descartes did something an engineer can appreciate: he didn’t doubt haphazardly; he doubted systematically.

His method resembled a security audit — assume everything can be compromised, then see what survives the most extreme attack scenarios.

Round one: your senses might be deceiving you. What you see might be hallucination; what you hear might be illusion. (Engineer’s translation: your input streams may be unreliable.)

Round two: you might be dreaming without knowing it. The experience in a dream feels real, and while dreaming, you don’t know you’re dreaming. (Engineer’s translation: your entire runtime environment might be a simulation.)

Round three: perhaps an omnipotent deceiver has rigged your mind to believe that 2+3=5 when it isn’t. Perhaps your basic reasoning faculties themselves contain planted systematic errors. (Engineer’s translation: your compiler might have been tampered with — Ken Thompson’s classic 1984 paper “Reflections on Trusting Trust” explored exactly this.)

After these three rounds, almost everything has been demolished. Senses unreliable, memory unreliable, reasoning unreliable, the very existence of the external world uncertain.

Then Descartes found the one thing that survived every attack scenario.

Cogito: The Minimum Viable Guarantee

“I think, therefore I am” — Cogito ergo sum.

Not because it sounds cool. Because it has an elegant logical structure: doubt itself is a form of thinking, and thinking requires a thinker. You can doubt everything, but you cannot doubt that you are doubting — because the act of doubting itself proves that something is performing the doubting.

An engineer might understand it like this:

def cogito():
    """The fallback that remains when all dependencies are unavailable"""
    try:
        doubt(senses)          # Senses might be deceiving me
        doubt(memory)          # Memory might be unreliable
        doubt(reasoning)       # Reasoning might have systematic errors
        doubt(external_world)  # The external world might not exist
    except CannotDoubtError:
        return "something_is_doubting"  # Something is doubting -> it exists

The Cogito isn’t a cosmic truth. It’s a minimum viable guarantee: in the most extreme scenario, you know at least that “some thinking process is occurring.” This is your cognitive fallback — the last certainty you have when everything else is uncertain.

But note: what Descartes proved is “thought exists,” not “I am a human being with a body.” Between “thought exists” and “who am I,” there’s still a long road ahead.


Reflection and Recursion: Self-Referential Engineering Structures

Can a Program “Know Itself”?

In most programming languages, you can write code that inspects its own structure. Python’s inspect module lets you examine a function’s name, parameters, and source code at runtime. Java’s Reflection API lets an object discover its own class, methods, and fields while running.

import inspect

def who_am_i():
    frame = inspect.currentframe()
    return f"I am {frame.f_code.co_name}, at line {frame.f_lineno}"

This capacity for “self-inspection” is called reflection. It lets a program describe its own structure — what methods it has, what its state is, who called it.

But description is not understanding. A mirror “reflects” your image, but it doesn’t “know” you. Reflection is just the reading of self-information, not the generation of self-awareness.

Recursive Self-Reference: Thinking About “What Am I Thinking”

Deeper than reflection is recursive self-reference. Not just “I can read my own state,” but “I can make my own thinking the object of my thinking.”

def think_about(topic):
    if topic == "my own thinking":
        return think_about("thinking about my own thinking")
    # Infinite recursion -- or is it consciousness?

Human consciousness seems to have this property: you’re not just thinking — you can think about the fact that you’re thinking. You can be aware of your awareness. This recursive structure is what philosophers call higher-order consciousness — you don’t just have mental states; you have mental states about your mental states.

In engineering, you can simulate this structure using recursion and metaprogramming. But is there an unbridgeable gap between simulating the structure and producing consciousness? That is one of the most famous problems in all of philosophy.


The “Easy Problems” and the “Hard Problem” of Consciousness

Capability Checklist vs. Subjective Experience

Philosopher David Chalmers divided the problem of consciousness into two categories.

The Easy Problems — called “easy” not because they’re actually easy, but because they’re at least in principle solvable with engineering methods. They concern the functional aspects of consciousness:

  • Can the system monitor its own state? (Self-observation)
  • Can the system adjust behavior based on state? (Adaptability)
  • Can the system report its internal state? (Observability)
  • Can the system distinguish itself from its environment? (Self/environment boundary)

You can implement all of these. Your monitoring system already does some of them:

class SelfModel:
    def observe(self): ...      # Read own state
    def predict(self): ...      # Predict consequences of own behavior
    def reflect(self): ...      # Evaluate past decisions
    def update(self): ...       # Adjust strategy based on reflection

The Hard Problem — even if you implement every functional capability, one question remains completely untouched: what is subjective experience, exactly?

When you see red, your brain processes a specific wavelength of light — that’s the functional side. But the “feeling of seeing red” — that subjective, first-person experience — how does it “emerge” from electrochemical signals in neurons?

Philosophers use a specific term for this subjective experience: qualia. Chalmers’ argument is that even if you fully understand the physical mechanisms of the brain, you still can’t derive from them why qualia exist, or why they “feel like” what they feel like.

What does this mean for engineers?

You could build a “consciousness simulator” that passes every functional test — self-observing, self-reporting, self-correcting. But you can never use tests to verify: is it actually “experiencing” anything, or is it just outputting the right sentences?

Behavioral equivalence does not imply internal equivalence. Two systems can produce identical outputs, but one has subjective experience and the other doesn’t. From the outside, you can’t tell.


The Turing Test Trap: “Looks Like” Is Not “Is”

The Seduction of Behaviorism

In 1950, Alan Turing proposed a strategy to sidestep the hard problem: don’t ask whether a machine is “really” thinking — ask whether its behavior is “indistinguishable” from a thinker’s. If you can’t tell whether you’re conversing with a human or a machine, the machine passes the test.

This is enormously appealing to engineers — it transforms a metaphysical question into a testable behavioral one. You don’t need to open the black box and look for a “soul.” You just check the output.

But engineers also understand this strategy’s fatal flaw better than anyone:

# Two functions, identical output, completely different mechanisms
def real_understanding(question):
    meaning = parse_semantics(question)
    knowledge = retrieve_relevant_facts(meaning)
    return reason_and_respond(knowledge)

def pattern_matching(question):
    return lookup_most_similar_response(question)  # Statistical matching

If both produce the same answer, the Turing test can’t distinguish them. But you wouldn’t say a lookup table and a reasoning engine are “the same thing.”

You can test for “looks like,” but you can’t test for “is.”

This is the Turing test’s deepest philosophical limitation: it measures behavioral equivalence, not essential identity. In engineering, you know that two modules with identical interfaces can have completely different internal architectures — one O(1) lookup, one O(n) computation. Same from the outside, worlds apart on the inside.

The Chinese Room: Syntax Is Not Semantics

Philosopher John Searle pushed this to the extreme with the “Chinese Room” thought experiment.

Imagine a person who doesn’t understand Chinese locked in a room with an enormous rulebook. Chinese questions are slid under the door. Following the rulebook step by step, the person manipulates symbols and slides “correct” Chinese answers back out. From outside, the room “understands Chinese.” But the person inside comprehends nothing.

Searle’s argument: manipulating symbols (syntactic processing) and understanding meaning (semantic comprehension) are two different things. A system can perfectly pass every behavioral test without “understanding” anything.

For programmers, this is like — your regex can perfectly match every valid email address, but it doesn’t “know” what email is.


Modern Connections: AI Agents, Projection, and Responsibility Boundaries

Why We Develop Feelings Toward AI

When AI starts to plan, to self-correct, to describe itself, humans instinctively do one thing: project.

You chat with ChatGPT for an hour and start feeling like “it gets me.” Your AI assistant remembers your preferences and you feel like “it cares about me.” Your chatbot says something warm and you feel like “it has emotions.”

This isn’t your fault. The human brain has a deep-seated tendency to project an inner life onto anything that exhibits purposeful behavior. You say your car is “being temperamental,” your computer “doesn’t want to cooperate.” This is an evolutionary social-reasoning instinct — better to mistake a rock for a tiger than to mistake a tiger for a rock.

But in the AI era, this projection creates real risks.

Two Dangerous Consequences

First, accountability vanishes. When you feel like the AI “made its own decision,” you stop asking: who designed that decision logic? What biases exist in the training data? What boundary conditions were considered at deployment? Behind the phrase “its own judgment” lies a long chain of human design choices. But projection blurs that chain of responsibility.

Second, authority creeps. When you feel like the AI “understands your needs,” you may hand over more and more decision-making power — what to read, what to buy, even what to think. But it’s not “understanding.” It’s doing statistical prediction. The difference: understanding includes consideration of consequences and concern for your interests; statistical prediction only cares about the probability of the next token.

An Engineer’s Pragmatic Framework

You don’t need to answer “does AI have consciousness” before making good engineering decisions. What you need is a set of design principles that don’t depend on that answer:

Observability — the system’s decision-making process must be inspectable. Not just “what did it say” but “why did it say that.”

Reversibility — any decision the system makes must be overridable by a human. Automation is not the same as irreversibility.

Accountability — when the system fails, you must be able to trace which component, which design decision, and which data caused the result. Responsibility cannot disappear into “the AI decided on its own.”

Projection safeguards — at the user interface level, build mechanisms that remind humans: you are interacting with a statistical model, not a sentient entity.


Reflections & Takeaways: You Think You’re Asking About Consciousness, But You’re Really Asking About Boundaries

The Questions That Actually Matter

Most of the time, when engineers ask “does AI have consciousness,” what they’re really asking is something much more practical:

“How much decision-making am I willing to delegate to it?” — a question of authority boundaries.
“If it’s wrong, who’s responsible?” — a question of accountability chains.
“Can it enter my private sphere?” — a question of trust boundaries.
“How should I treat it?” — a question of moral consideration.

The consciousness question matters not because of the answer itself, but because different answers affect how you draw these boundaries. If AI has consciousness, you might need to consider its “rights.” If it doesn’t, you at least need to consider the psychological impact on users who form emotional bonds with it.

The Self Is Also a Model That Needs Maintenance

Descartes’ Cogito gave us a starting point, but it’s not the finish line. “I think, therefore I am” confirms the existence of a thinker, but doesn’t tell you what the thinker is.

Your self-knowledge — who you are, what you’re good at, what you care about — isn’t a fixed entity. It’s more like a continuously updating model. Your self-understanding from three years ago probably differs from today’s. You present different aspects in different contexts (work, family, friends) — which one is the “real you”?

Maybe the answer is: all of them, and none of them completely. The self is a multi-layered, dynamic model that requires continuous calibration. Like your system architecture diagram — it describes the system’s structure, but it is not the system itself. The diagram gets outdated and needs updating. So does self-knowledge.


Conclusion

Back to that late-night monitoring alert.

“Memory leak detected. Cache module disabled. Currently running in degraded mode.”

This system wasn’t “thinking.” It was executing rules. But it reminded me of something: our understanding of the “self” may be more fragile and more in need of maintenance than we assume.

Descartes used doubt to find the minimum certainty. Turing used behavioral testing to sidestep the hard problem. Chalmers identified the gap between function and experience. Searle reminded us that syntax is not semantics.

And as an engineer, your advantage is this: you don’t need to solve the metaphysics of consciousness before making good design decisions. You can start by building transparent state logging, reversible permission designs, and traceable accountability chains — and continue thinking about the deeper questions as you go.

Next time you write self.observe(), you might pause for a beat:

That “self” doing the observing — what exactly is it?


Next Article Preview

Time Complexity vs. the Nature of Time

You can calculate O(n log n), but can you calculate “the weight of a day”?

  • Why do three seconds waiting for an API response feel longer than a thirty-minute lunch break?
  • Concurrency and parallelism — is time really linear? Or did your program discover the nature of time before you did?
  • From Newton’s absolute time to Einstein’s relative time — your distributed systems deal with this every day
  • If time can be reverted (git revert), did the “past” really pass?

Next time, we start from setTimeout, travel through Augustine, Newton, and Einstein, and explore time — the most everyday yet most mysterious concept.


References

  • Descartes, Rene. Meditations on First Philosophy. 1641. (Methodological doubt and the Cogito)
  • Turing, Alan. “Computing Machinery and Intelligence.” Mind, 1950. (The Turing test)
  • Searle, John. “Minds, Brains, and Programs.” Behavioral and Brain Sciences, 1980. (The Chinese Room)
  • Chalmers, David. “Facing Up to the Problem of Consciousness.” Journal of Consciousness Studies, 1995. (The hard problem of consciousness)
  • Dennett, Daniel. Consciousness Explained. Little, Brown, 1991. (Functionalist account of consciousness)
  • Thompson, Ken. “Reflections on Trusting Trust.” Communications of the ACM, 1984. (Trust and system security)


Philosophy for Programmers・Series Navigation

Main Series

#00 Introduction: Why Programmers Need Philosophy

#01 Is Truth a Function?

#02 Is Knowledge Just Data?

#03 cogito_ergo_sum.py ← You are here

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *