4 ms·
That is not an important facet at all. It's not a thing your users see. The "syntactic sugar", as you call it, is the interface between you and your users. N
by DannyBee 8y ago
That is not an important facet at all.
It's not a thing your users see. The "syntactic sugar", as you call it, is the interface between you and your users.
No amount of pretending otherwise will change that.
No amount of separation will change this. It does not give you any more ability to change the syntax over time, or get it righter.
Your users care only about this syntactic interface.
In a good world, they do not care how the rest happens in practice.
Worse than this, the idea that a mid level IR should be the "thing that keeps the syntax in check" seems beyond broken.
The lower levels do not drive the higher level in roughly any case.
Instead, they exist to serve the higher levels.
First you understand what users want at a high level, then you try to understand how to make it fast/well.
If you need to change the mid level IR to do so, you do.
There are nothing but tradeoffs in mid level IRs, and those tradeoffs change over time based on the needs of languages, not the other way around.
Driving a language based on what you can accomplish in a mid level IR would be incredibly silly - "Welp, we better use this form of parallelism at a high level because we chose coroutines in the mid level IR" should never occur.
Instead, the answer is "we change the mid level IR to best support the form of high level parallelism we want in the language"
- Ericson2314 8y agoOK yours is the second comment to talk about "Users". IMO this first-impression-based design methodology, like we're writing some consumer CRUD app for the startup [proverbial] you're gonna quit in <= 3 years, is a terrible skeumorphic philosophy for designing languages. Languages are for more terrible; programs last (too?) long; long-future readers may be expert or knowledge. Let me response point-by-point > It's not a thing your users see. The "syntactic sugar", as you call it, is the interface between you and your users. Users can and should learn the core language too. It's can allow compressing the information in the brain just as it allows reducing the code in the implementation. > In a good world, they do not care how the rest happens in practice. Again, I believe the core language is a meaningful thing to study and learn, not just some shove-under-the-rug implementation detail. You clearly don't, and your conclusion is indeed implied by that presupposition. It's hard to argue either from other principles so let me say it is widely held by those that study programming languages and work with cutting-edge programming languages: My axiom has more buy-in by the relevant in-groups. Maybe out-groups with yours are right and we are bad designers, or maybe those out-groups should accept a non-trivial learning curve vs permanent complexity. > The lower levels do not drive the higher level in roughly any case. This is wrong. As someone active with RFC discussion for both Rust and Haskell, this empirically not the case. Ideas are constantly proposed and vetted based on whether they fundamentally extend expressiveness or are just sugar. > First you understand what users want at a high level Yes, languages changes should and are be driven by end goals, but end goals != surface syntax!! > There are nothing but tradeoffs in mid level IRs What does this even mean? Surface syntax is full of tradeoffs too. > those tradeoffs change over time based on the needs of languages, not the other way around. Again, once the MIR/core exists, RFCs heavily reference them so this is false. > Driving a language based on what you can accomplish in a mid level IR would be incredibly silly - "Welp, we better use this form of parallelism at a high level because we chose coroutines in the mid level IR" should never occur. Instead, the answer is "we change the mid level IR to best support the form of high level parallelism we want in the language". This leads me to think you don't know much about IRs in these langauges in practice. Neither Rust's or Haskell's IR has any notion of concurrency precisely because nothing good enough has presented itself. Both language use syntactic / "encapsulation tricks" (See Haskell using the IO monad to avoid the value restriction of OCaml, Rust's Send and Sync) to chew off some safe subset that works with many modules. An IR with a deep/"semantic" understanding of concurrency doesn't exist for these "production" languages, though I hope http://plv.mpi-sws.org/rustbelt/ http://plv.mpi-sws.org/rustbelt/ could get Rust there someday.
- dbaupp 8y ago"User" refers to someone writing code in the programming language---someone "using" the compiler. It's not some project-management-y jargon. ----- Extending expressiveness vs sugar is fundamentally a property of the high level language, not the mid-level IR. It happens that talking about a mid-level IR is sometimes a nice way to "prove" that something is new or sugar. As the parent said, the programmer using the compiler only truly cares about the high-level language when writing code. They may dip into the mid-level for optimising their code etc., but they won't write it directly: to a non-compiler author, IRs are implementation details of the programming languages that happen give insight into how some detail of the language works or how a particular piece of code is optimised. To hammer home this point: if there's some major change required/desired in the high-level language, the current details of the mid-level language shouldn't affect the overall design. The mid-level IR can change to accommodate the desired surface behaviour.
- Ericson2314 8y ago- New program writers (more writing) - Old program maintainers (more reading) - Language implementers You leave out the 3rd and conflate the second. Others have conceive of PLs as some sort of bargain between human and machine, or human and pure math. Either way, there's multiple interests at stake. Or, even simpler, what if Rust becomes way harder to learn, but mastery gives one correspondingly way more productivity? Is that a fair trade in your eyes? (I do not believe in practice it will become way harder to learn, but I accept the situation I describe as fair and not a failure of Rust). ----- You may not write it directly, but you will still think about it. Again the IR of these good languages is like some platonic ideal that sacrifices concision of programs for concision of the language. It is not just an inplementation detail. Hell, if you insist on thinking that is just some crufty implementation detail, sure. But then let me show you how it's an abstraction that leaks badly, hahaha. - "Non lexical lifetimes" are probably the most anticipated Rust change lately (see rest of thread). But crucially, they are lexical at the level of MIR. The easiest way to precisely define them is desugar to an explicit control flow language. Otherwise you are forced to look at the a combinatorial explosion of surface-level constructs, or just handwave based in the intuition of control flow. - https://github.com/thepowersgang/mrustc/tree/master/src/mir https://github.com/thepowersgang/mrustc/tree/master/src/mir this is the alternative Rust implementation's MIR. It's pretty close to the same thing! (Not so with LLVM IR and GCC's RTL.) If mrustc gets to implementing NLLs, it will probably get even closer. - mrustc does not implement old borrow checking probably because it's sort of an arbitrary spec against the surface syntax. Surface syntax is much more boilerplate to go through all the cases, and while old lifetimes may have a simple enough rough intuition, they are very arbitrary when considered precisely. And yes, the core language can change underneath the hood, but this is highly unlikely in practice. GHC's core has certainly changed, but this is evolution more than revolution. I think the heart of what I'm saying is two things: 1. Formal reasoning is the only way to constrain complexity. Humans alone inevitably don't fully graps the entire thing (it's just too big!), and even when they do don't have identical mental models. The results is always contradictory design if any change at all is permitted. 2. Human PLs have lots of conveniences and other fluff (yes, even Scheme, Nix, or your other favorite minimalist language), so the only efficient way to reason about them formally is by desugaring to a core language.
- qznc 8y agoWhile I generally agree with your point, D/Walter Bright slightly disagrees with the sentiment. One constraint for D is "must not require data flow analysis" because that incurs a cost on compilation time. Afaik this was mostly inspired by Javas definite assignment rule [0]. If fast compilation is a goal, then a language is constrained by implementation and IR aspects. [0] https://docs.oracle.com/javase/specs/jls/se6/html/defAssign.html https://docs.oracle.com/javase/specs/jls/se6/html/defAssign....
- zbentley 8y agoThis is a perhaps over-fine semantic distinction, but I would argue that there's a qualitative difference between IR/language implementation and compilation speed. The former should not drive the language's features; the latter is a language feature.
- Ericson2314 8y agoIMO most discussion of the compilation speed is incredibly narrow-minded. We incremental compilation more than anything else. Programs barely change each rebuild, so that should solve all the performance problems without having to maim ourselves.