Ok, so FINALLY, here's my reply to some of David's questions:
1. High-level bootstrapping, UI to edit itself - How? Where's the machine code?
There's a set of low-level operations (+, -, get, set, etc.), end everything else (interpreter, compiler, bootstrapper, UI) is built on top of that. The interpreter is just a function that takes a "context" (dictionary) and an expression, and recursively looks up each operation by name in the given context. Each operation is either a high-level function, which is fed back into the interpreter, or a native-function which is invoked directly. Native code will either be directly editable, or (re)generatable from high level (or other) code. The system can "save itself" by generating a native executable that contains everything in the system stored in a statically initialized structure, with the native base operations nested within it, and a native version of the interpreter (generated by feeding the interpreter into the compiler), and a bit of code to start interpreting whatever is needed to "start" it up. A compiler (for some target) basically just needs to generate native code for calling a native function with arguments, and native-coded versions of the base operations.
2. Why put the IDE in your code? What about compatibility & updates?
I think the devision between "code" and "programming language" and also IDE is completely artifcial & unnecesary. There's more "language" describing a software system itself -- every function or API or UI has its own language (grammar and rules of application) that higher logic is composed from -- than is nececcary to describe the
few fundamental building blocks of programming (functions, variables, conditionals, etc). So instead of an IDE and editor for a "programming language", I'm looking to make it easy to bootstrap whatever language or editor or model for the specific software system, with PL being a relatively tiny, or using regular old programming abstractions to hide it's complexity away. It's a similar philosophy to this:
https://ngnghm.github.io/blog/2015/08/02/chapter-1-the-way-houyhnhnms-compute/
But also, I can stretch these ideas into the UI itself: In the same way that functions + data can replace "grammar" and code "written in" that grammar, so can a user interface and some other model.
3. Why not start with SmallTalk, or a LISP OS?
Maybe it could be done there, but that's also a full OS and not a thing that people use it for. In practice, it's still a specific language that locks you in like any other (notwithstanding its late-binding philosophy). What about JetBrains MPS? That's closer, but has similar problems: It's turned LOP into a specific locked down formalization of languages and tools (ironic), that I also think is far more complex than it needs to be. Do you need all that just to be and to say "when I say x y, I mean foo(y(x))". You can do that with ordinary programming paraphernalia (that's what programming is!). What about Racket or Scheme? Maybe that solves a lot, but is restricted once again to dead text, not a living model that may (for one example) have a visual representation instead of a textual syntax.
4. What about interop with a different runtime? Boostrapping this whole system into another runtime would create bloated and inefficient programs. Can I just make a
Java program in this?
Bootstrapping the system to another runtime was more about using the system itself as a replacement / reinvention for the computer or OS itself: A truly open-ended moldable thing that you can tap into and do whatever with, as needed. And for that, I'd want to be able to boostrap the system elsewhere. I'm starting this thing in JavaScript in a browser, but once it gets far enough, and given an implementation of some low-level ops somewhere else, I could take the exact thing I've developed and load it somewhere else, and keep working. And then have more capability than JavaScript in a browser. There's also other potential applications, like a system being able to "send itself" somewhere.
But using the system to create a product for another runtime, is a different idea. You would only
model your product in this system, and have other code to generate-out a built-product. The advantage is all the stuff I described in #2 (similar to those offered by JetBrains MPS). Also you could do something similar to what Dark lang is doing, and have a full system modeled in one place, with conditionals that effect parts of code that will end up on different machines or layers, but created in one place with one set of logic. For example, a single variable to control one aspect of everything, without having to have that extra logic embedded or repeated in any of the generated components of the built product. Also there's being able to version-control the whole thing as a single entity (so a feature change equates to exactly what changed in the WHOLE system being built).
5. "Getting the junk out of the way" will not suddenly make code simple.
It doesn't follow from "I can see everything, can now convert to and interp with Java" to "now everything is easy"
Code is as simple as we make it to be. There is a LOT wrong with how "professional" (and other) software code is composed. You could have the perfect language and tools etc. and still write horrible code. But I think much more of that is blamed on "software is just so complex!" than on all the overhead of language and code and tooling than is reality. I think that if it can be more easily possible to have the business logic be
the thing you are building and seeing, then this gets a lot easier. I also think that this stuff is much easier than it's often MADE to be, because of all the other noise, and because it's the LAST thing that programmers are thinking about. If we can make it easy to see, then this problem can become more visible, and it can be demonstrated how straight-forward programming CAN be. Yes, there are hard problems and circumstances where the logic is just not as easy as one would think; but that's more like 10% than like 90% of software. Even the simplest things are made horribly complex!
But also, If code is something that can be generated or specified more fluidly than basically giving a one-to-one specification for all the instructions in the code, than that can also help to make it much simpler.