While working on a parser and examining LLVM IR, I started wondering where the boundary between data and logic actually lies. Both are represented as bits and both seem to carry information. In some languages, programs can be treated as data, and data can sometimes be executed as code. Functions can be stored in objects, while functional programming can represent state through abstractions such as monads. Even at the machine level, the distinction seems partly based on how the processor interprets a sequence of bits. So from a mathematical or theoretical perspective, what does "information" mean, and are data and logic fundamentally different things or simply the same representation used in different ways?
3 Answers
There usually isn’t an inherent difference in the bit pattern itself. The difference comes from interpretation and context. A sequence of bits can represent an integer, an image, an instruction, or something else depending on the type system, encoding, and operation applied to it. Data is generally information intended to be operated on, while logic describes the rules or transformations used to operate on it. At a deeper level, both can be represented as information, but they play different semantic roles.
Some systems make the distinction especially blurry. In languages from the Lisp family, programs are represented using ordinary data structures, so code can be inspected and transformed like any other value before being evaluated. Lua has similar ideas in the sense that functions are first-class values and can be stored or passed around, although that does not mean every Lua value is executable. The important distinction is still what the runtime is instructed to do with a value.
The same memory can even be reused for different purposes. For example, executable machine-code bytes could be interpreted as pixel data for an image. Nothing about the physical bits changes; only the interpretation changes. In formal terms, data is often a value in some domain, while logic is a function, relation, or rule describing how values relate or change. A function can itself be encoded as data, but when it is evaluated, it takes on an operational role.

That is why the hardware-level explanation can feel unsatisfying: the CPU also relies on an agreed-upon interpretation. The instruction decoder treats certain bit patterns as operations, while a different program could treat the same patterns as ordinary data.