Being a foss enthusiast I can configure most of my software in way too many ways. However I noticed that this is not true for most compilers. Which got me thinking: why isn’t that the case. In gcc (or your favorite compiler tool) I have a shitload of options about what are errors and warnings and how the code should be compiled and tons of other options. But not on how the code should be interpreted and what the code should look like.
Why can’t I simply add a module to a compiler to make it [objective oriented | have indentation for brackets | automatically allocate memory | automatically assume types | auto forward-declarate | some other thing that differentiates one language from another]* ? Its so weird that I have a pdf reader that has an option to set the window icon, a mail client that lets me specify regex to search for a mentioned but forgotten attachment and play a game that lets me set my texture picmip resolution. But that the tool (gcc) to build these things has not even got a config file build in. We have build tools around them to supply arguments.
This could look like the following: ( oversimplified )
-
preprocess
-
compile
-
assemble
-
link
v
-
add brackets from indentation
-
preprocess
-
check if objective oriented constraints are all satisfied
-
do something else
-
compile
-
assemble
-
run assembly through as an example ai for antivirus scanning
-
link
-
run test
There could also be a fork in this process: sending for example the source code both to a compiler and an interpreter to detect edge case behavior while compiling. Or compile with both automatic typing and your defined typing so that when rounding errors are big you can instantly compare with a dynamically typed version of your program. Or the other way around, maybe you want different parts of your code to be handled with different preprocessors.
The compiling process should be configured per project for things about the input like syntax and per computer for things about the output like optimizations.
There are of course some drawbacks, one being a trust issue where someone pulls in a obscure module to build malicious releases. It probably also is harder to maintain stability when you have to keep in mind that your preprocessor isn’t the first to be run. And your compiling process can take a lot longer if you have to go through multiple pre, post or even compilation phases.
If you know such a compiler, or c (: haha :) some obvious reasons that this should not exist, please let me know. Thank you for reading this lenghty post.
jeffhykin@lemm.ee 11 months ago
I agree with the general idea, but I think there are lots of misconceptions. Gcc does allow doing things before the preprocess step, after the preprocess step, before the linking step, etc. It’s possible, but not easy, to run your own programs inbetween those kinds of steps. As for why there’s no config file, it’s probably cause gcc is really old, but I’ll have to let someone else comment on that.
However, syntax support is effectively a completely different feature request. For example the “adding brackets to indentation” couldn’t really/correctly come before the preprocessing step. I mean a really hacky solution like my indent experiment from a long time ago can, but it will never be even slightly reliable because of the preprocessor, multi-line strings, comments and other edgecases. Let me explain.
But note, preprocessor strings just coincidentally parse the same as C strings. There’s already a limitation of the preprocessor failing on, lets say, python where python has triple-quote strings.
That said, preprocessing is actually highly unusual in the sense that it can be done as a separate step. Usually parsing needs to be done as a unified operation. Not to say it can’t be modular, but rather the module must be given to a central controller that knows about everything rather than just having a code-transformaiton step.
With those misconceptions out of the way, now I want to talk about the parts I agree with.
IMO the perfect language is the one that has an “engine” that is completely separate from the syntax. And then the language/compiler should allow for different syntax.
The closest current thing to what you’re talking about is almost certainly Rust macros. Unlike the preprocessor, Rust macros fully understand rust and are a part of the parsing process. They are decently close to what you’re saying, instead of compiler flags it’s just imports within Rust. You can write HMTL, SQL, and other code just right in the middle of a rust program (and it’s not a string either, it’s actual syntax support). Not only is it possible, but I have been eagerly awaiting for someone to create a garbage-collected syntax within a Rust macro. People have already created garbage collectors, it’s just a matter of making a nice wrapper and inter-op.
That said, and even though Rust macros are head-and-sholders above basically every other language, I personally still think rust macros don’t go far enough. Indent-based code isn’t really possible within rust macros, rust macros can’t have imbalanced braces, and there can be escaping issues that prevent things like YAML syntax from ever being possible. They also can’t allow for extensions like units, e.g.
10gallons
without wrapping it with some kind of delimiter (which defeats the point)AFAIK currently there is no compiler that supports a composable syntax like that. I’ve worked on designing such a system, and while I don’t think it’s impossible, it is extremely hard. There’s a lot of complications, like parsing precedence, lookaheads, operator precedence. Two syntax modules that don’t know about each other can easily break each other. Like I said, I don’t think it’s impossible, but it is difficult.
porgamrer@programming.dev 11 months ago
I mentioned it elsewhere here but I think the Terra research language has explored this area more thoroughly than Rust, just because that its only purpose. The website and academic papers are definitely worth a skim: terralang.org
It’s basically a powerful LLVM-based compilation library exposed where everything is exposed through Lua bindings. The default Terra compiler is just a Lua script that you can pull apart, extend, rearrange, etc. It’s all designed for ease of experimentation, whereas Rust has to worry about being a rock-solid production compiler.
spykyvenator@programming.dev 11 months ago
I think you nailed this.
jeffhykin@lemm.ee 11 months ago
also if you’re interested in languages join c/programminglanguages!