Think of some foundation things.
C's great, just add a library to do ______ .
I think you are not asking some thing simple here.
What is the difference when you use C's version of array vs a matching library? Just simple things like compile time _____.
Adding a library lets C compile something to do more while putting more work on programmer using library.
free_electron's complaining about header files.
Think here you need to ask, is it a language problem, a compiler problem or the tool used to create the program source?
How about it's all three for an answer.
A header file or section lets a programmer know what hooks can be used with this code with out having to read and understand all the code. To me that is a good thing. It lets many programmers work on separate parts of a program. It allows for a simpler faster compiler.
One problem is where is the key word that states this has a matching part in the header.
Some languages have a flag or key word that states this is a header part so you no longer need a separate header. Removes the need to match the header part to where it's defined, but also puts more work on programmer as you have to read all code and build the header part your self. One simple fix is normally missing, the command to Compiler/language to build a separate header.
With out flag or key word in language, programmers work load also increases with the need to match some things in header and code.
the tool used to create the program source
This is the really sad part of the whole process. If the editor understands the language, then when you add the flag or key word stating it's part of header, the editor could maintain the matching part in the header. Programmer gets the best of it. You have a header for compiler and programmer to use with just the cost of adding flag or key word.
Need to remember that what is currently called a compiler is translator. If you look at C, A poor translator. It is too low level and too high level not counting the other bad parts. Some of the hiding at low level causes big problems or compiler bloat. Look binary integer math for example. At the binary level it's and array of bits that you do math on. Some math can create results larger then the input array of bits. Some CPU's supply almost zero cost functions when doing binary math to reduce need for some instruction steps. With C's hiding this, higher level code has problems. Note here that an array of bits does not just = integer.
A CPU works with bits with some instructions working with array of bits.
Starting at this level gives the compiler options on how to get job done. It actually makes programmers job easer.
With array of bits, any bit size math is possible. Some will use one CPU instruction, while others can still be done using many CPU instructions.
With array of bits, any bit size logic is possible. Some will use one CPU instruction, while others can still be done using many CPU instructions. As the compiler gets smarter everything improves, Little simple things in compiler. The smart compiler knows that an array of bits of size ___ can have ___ states. It can create the bit masks when needed removing one source of programmer errors.
Also need to think of what a macro preprocessor really is.
For C it's a hack to patch a poor language using text editing. A hack that can result in all source needing to be checked and recompiled again. For a language that uses type names & headers a lot of the need vanishes with proper language use.
A simple what CPU is this code to run on at compile time removes more need. Note here that it is not a choice of one, it is a list of CPU's. In source then a case statement can then select what is needed.
I worked with a pascal compiler that had modules and a few added key words for system programming back in the 80's. The output of compiler was one file that contained the header for other pascal source to use this module, The machine code & the linking/patch information needed. The one file removed many problems like does header match the code. The header was simple to get as it looked like a text file but contained more after the end of the text. Pascal to assembly was also very easy, a simple command to compiler would take a text header as input and create a file containing assembly code needed for linking to pascal. Add needed assembly code and run through assembler and done. Assembly code that linked with pascal.
By fixing the low level problems, you have something you can easily build on. No big steps to run compiler on one CPU and generate output that can run on many different types of CPU's. The question becomes do you include code generator for all CPU's, A few or just one in the new compiler program.
If you have source for compiler, the hard part becomes what key or key word to use to add more smarts to compiler. What parts of compiler to include in editor.
Stop the compiler hiding things as only option. For binary math, an overflow error is a fact. Question is does compiler handle it here and/or does source program. For an object you then have many options. For garbage collection you have option of NONE. Compiler then knows what to show as an error when trying to use garbage collection based things with no garbage collection enabled. When you create an object, you also have options, Use default, Heap, stack, special memory area.
When you think of this foundation, not hard to add option to change rules for a section of code as long as lower level matches up at some point and helps other sections of code. It's just a key word that is needed stating what language follows.
Why create a new language when the editor makes a mess of it.
New language should be part of editor and part of compiler, interpreter with choice of may types of outputs in one program. All have a need at times.
Adding compile time checks and code generation should be part of language.
Hacking the hack needs to stop.