See this is why I never understood LISP people proudly proclaiming that “code is data and data is code”… we were doing this in BASIC for decades already!
The thing is in Lisp, data with a nice structure that you can easily work with is evaluatable as code; and all the code that runs has a nice structure and is easy to work with! You cannot easily manipulate and transform BASIC programs from within BASIC, and you cannot easily do anything in machine code.
But maybe this is part of what Gerald Sussman was talking about when he called Lisp a "low level language": like machine code, Lisp has the nice property that its default data representation is used for building directly executable programs.
“code is data and data is code” is a fact of computing. What LISP does is to make it an official feature of the language and provide nice abstraction for it. A lot of languages want you to use some cumbersome reflection library, a dangerous eval function, or a crippled macro mechanism. With LISP, you just use the language mechanism in order to write code that process code.
> “code is data and data is code” is a fact of computing
The general purpose computers we have today all follow that principal, yes. However it's not a fundamental fact of computing. Turing machines, cellular automata provide other paradigms. And if those aren't practical enough for you, ASIC programming is Turing complete but cannot access its code as data.
State transition in the turing machine are not modifiable, but one of the core advantages of the TM is that it's powerful enough to emulate state transition. So you can model the states of the new machine as data, add the transition mechanism as code, feed those to the TM and you have a new machine that can interpret input that was unrecognizable by the previous one. That's how programming languages works.
So yes, you can't modify the actual embodiment of the state transition if it does not offer you the capability to do so. But as long as it interprets data in a TM manner (input and output are colocated and the alphabet is the same), you can write code that will interpret data as code and manipulate code as data. Not by modifying the base substrate, but by adding a virtualization layer on top.
At the base of it, the TM is an abstraction built with sets and relations. Just like most computers are merely signals flowing around a circuit that get generated from other physical phenomena and will be transformed to other physical phenomenas. You can't hack around physical laws, or ignore the axiomatical rules in mathematics. The code that is not data are those things.
You are redefining both the term "code" and the term "data" in ways that I don't think most people would agree with - and more importantly, in ways that make it impossible to talk about von Neumann architecture.
But maybe this is part of what Gerald Sussman was talking about when he called Lisp a "low level language": like machine code, Lisp has the nice property that its default data representation is used for building directly executable programs.