Earlier quoted context omitted.
Split the syntax into whether it 1) emits no code (compiler-facing); 2) emits weakly-related code (eg., macros, etc.); 3) emits code close to what's written abstractly (eg., value operations); 4) emits code close to what the machine needs (eg., unsafe code) -- etc. And you'll find about "4 languages" all mixed together.
I still have no idea what you're talking about. Can you give an example? Most "syntax" in AOT, statically typed languages does not directly generate machine code, but it does directly impact what machine code is generated. So there's not a clear distinction in practice. For example, a lot of the syntax is used to control method selection and verification - that's not a "different" syntax or language by most folks' de…
Or below, let's invent a language where there's (in my sense) "one syntax for everything",
Eg., consider something like,
const SimpleTrait = trait with:
val name
def GenericApiTrait(type T) =
return new trait with:
def response : self -> str
const MyAPI = GenericApiTrait(SimpleTrait(new class)) with:
val name = "World"
def response : self -> str = f"Hello $name!"
# later on, in the app,
def calc(x, y) : int, int -> int =
return x + y
# ie., the **same** syntax as that earlier which targets compile-time
Here you can see that code with ordinary run-time semantics is used for the compile-time operations of generating a trait and specifying that a class implements that trait (ie., we call the trait-defining function on the class).Whereas in Rust, the syntax for returning values and "quantifying over types" is radically different.
This is the historical approach (C++, C# .. almost all langs) -- but not one modern innovative langs follow.
I think with as much desire for novelty rust has, cramming it all into its "compile-time syntax" has hobbled it.
A simple uniform language for both c-time and r-time could be used