4 ms·
Counterpoints as someone considering writing a language that targets LLVM, and as someone who has used Rust a bunch: - Your compile times will be a lot slower
by trishume 10y ago
Counterpoints as someone considering writing a language that targets LLVM, and as someone who has used Rust a bunch:
- Your compile times will be a lot slower than they would otherwise be. This is a big one for me.
- If your type system is materially different than Rust's, you don't gain any benefits since you have to write your own type checker anyways.
- LLVM is designed to be easy to machine generate, including having a library API for generating code. Rust doesn't yet.
- You can't necessarily re-use Cargo if your language requires type info to link that wouldn't be in the Rust source files generated.
- If you have semantic differences in memory model you'll need to give up the advantage of Rust's safety by having your code generate unsafe pointers, for example if you want to have shared mutability in a single-threaded context, which Rust doesn't handle nicely.
- If you do re-use Rust's type checker the error messages you get out will be terrible and point into generated Rust code.
- Debug info and debugging get even harder.
- If you want Rust interoperability you have to replicate Rust's enormous type system in your language's FFI, which is hard if you also have your own type checker, see above.
Basically it is a good idea, if your language has semantics and type system very close to Rust.
A much better idea IMO is to target LLVM and then write an LLVM plugin that can link to Golang object files and generate Golang struct metadata. Golang's FFI and type system are much much simpler and more likely to be able to graft onto new languages. Also Go's library ecosystem is larger.
- Hitard 10y agoVery new to Rust ecosystem, but I wondered, regarding this last point about using an LLVM plugin to generate structs, etc... would this also be a better way to do clean FFI to functions that use C-style unions? I have been struggling to see how the Rust bindings for Vulkan can be improved.
- jdmichal 10y ago> You can't necessarily re-use Cargo if your language requires type info to link that wouldn't be in the Rust source files generated. As a supporting point, TypeScript requires definition files (.d.ts) for JavaScript libraries to properly type them. Unless the language has a 1:1 correspondence to Rust types, something similar will probably need to happen.
- wcrichton 10y agoThanks for the good counterpoints. Some thoughts: - When you say "materially different," how different are we talking? I'll admit that if you want to implement Haskell (or anything with HKT) that it's a long shot, but if you want to implement Javascript, it shouldn't be that hard, yes? - Can you give an example of when you need type info to link? - RE: debug info and error messages, do you disagree with what's written in the post? I agree this is an issue, but it doesn't seem unsolvable. Generally, I guess I don't see how most languages have semantics terribly different from Rust. You don't need unsafe pointers for shared mutability with a single thread because you can use a RefCell (see: my language linked in the post). In my experience, most type systems for general-purpose languages have roughly the same feature set as Rust. I buy that implementing a language completely different from Rust in semantics/types makes Rust not a good target, but for most languages we use nowadays, isn't that not the case?
- DasIch 10y agoYou need type info, if the language has its own type system which has more information than Rust. Imagine you have machine code generated by compiling a C program and now want to figure out what struct some function takes as an argument. As you go down towards machine code you lose information that you cannot easily recover. Solving all of these issues is also only practical, if the Rust developers themselves cooperate. It seems to me the very purpose of creating a new language, is in freeing yourself of the limits existing ones have. Building a new language on technology that are restrictive doesn't really make sense from that perspective.
- panic 10y agoHow will you implement exceptions?
- Manishearth 10y agocatch_unwind, probably? Its not supposed to be used for exceptions and if you try to use it for them there are some barriers in the way. But these are not fundamental barriers and can be solved through codegen, which is how the language is planning to work anyway.
- haberman 10y agoJust to add another one: - almost nobody has Rust installed already, and it's a ~100MB download. With a new version every six weeks or so.
- exDM69 10y agoIt is pretty easy to embed LLVM into an app and use it to generate IR code and then JIT and run it. The Kaleidoscope tutorial creates a JITting repl in just a few hundred lines of code. Embedding the Rust compiler would be pretty difficult, especially if your compiler isn't written in Rust. I think that using Rust as a compiler target is a completely goofy idea. But perhaps Rust's MIR intermediate representation could work for other source languages.
- lomnakkus 10y agoI was nodding along, but I think you lost me with the Goland object file thing. What would be the purpose of linking against Go object files? (As opposed to, say, C?)
- trishume 10y agoA nice big ecosystem with both a simple ABI and type system, but with a nice safe type system that doesn't need manual memory management. Interfacing to C libraries from more modern languages is generally a huge impedance mismatch and necessitates some kind of wrapper. Also C libraries vary wildly in how they are built, if they use macros, how difficult their headers are to parse, etc... Linking to Go libraries from a certain type of language could be super easy and the libraries would be nice enough to use to not need a wrapper layer. I talked about that because IMO a really important part of having a usable language is an ecosystem, and if you're going to start a new language today piggybacking off of Go's sounds like a good plan.