TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Compiler Development: Rust or OCaml?

154 点作者 bshanks将近 2 年前

18 条评论

nu11ptr将近 2 年前
The article has fair points, but after trying OCaml and Rust... I chose Rust. Without going into huge amounts of detail, a compiler is more than simply a parser/ast/code generator and there are other aspects to consider such as the richness of the ecosystem, editor support, etc. Also, I suspect the author is more familiar with OCaml than Rust as you wouldn't typically box everything but likely use an arena for the AST. In the same way, I am more familiar with Rust than OCaml, so some of the warts I observed may be to lack of familiarity. As such I suspect the authors perspective is biased...as is mine. Nothing wrong with that.
评论 #37039621 未加载
评论 #37040015 未加载
telios将近 2 年前
I don&#x27;t quite follow the algorithm here, but I&#x27;m not sure the `gensym` Rust implementation works as expected. `RefCell::clone` does not return a copy of the reference; it returns a new `RefCell` with the current `RefCell`&#x27;s value, resulting in duplicate IDs. However, a `RefCell` isn&#x27;t even necessary here, since a `Cell` would do just fine - and you&#x27;d pass around a reference to that `Cell` instead of cloning it.<p>It does feel like the code was ported as-is to Rust, and only adjusted slightly to compile; there are going to be pain points as a result of this process. I suspect this is the source of some of the author&#x27;s complaints, especially given:<p>&gt; Although it provides us with a greater sense of how the code is executing, it brings very little value to the algorithm itself.<p>Rust is, in general, for people who find value in having that information; it is okay to not want to have to worry about ownership, borrowing, safety, etc., but it seems a bit odd to complain about this when that&#x27;s what Rust is for? If you want to focus on just the algorithm, and not how it&#x27;s executing, then OCaml is definitely a valid choice.<p>However, the point about GADTs - can Rust&#x27;s recently-stabilized GATs not work in the same way? Though I will admit that Rust&#x27;s GATs don&#x27;t seem nearly as powerful as OCaml&#x27;s GADTs in this regard.
评论 #37040842 未加载
hardwaregeek将近 2 年前
I skimmed the article, and comparing the two programs, yes, the OCaml one is shorter and more elegant. But it also reads like a math magic spell. There&#x27;s no type annotations for me to figure out what the heck each term is. The naming conventions lean extremely terse. Perhaps it&#x27;s my lack of experience with OCaml, but it doesn&#x27;t feel as legible.<p>The Rust one reads like...well a program. A program that&#x27;s not as beautiful, but is very much designed to be taken apart, debugged, improved, etc.<p>I fully agree that if you&#x27;re writing pure, recursive, data structure manipulations, OCaml is likely a better fit. It&#x27;s closer to mathematical notation and I see the elegance in that. But if I were to take that data structure manipulation and turn it into a compiler with thousands of lines that I navigate with an IDE, with logging, with annoying little edge cases, with dozens of collaborators, I&#x27;d choose Rust.
评论 #37041239 未加载
评论 #37040974 未加载
评论 #37046044 未加载
评论 #37042698 未加载
yberreby将近 2 年前
As someone who wrote a fair amount of Rust and OCaml code, I have to agree with the author.<p>While working at Routine (YC W21), I was tasked with porting our core library to iOS to minimize duplication of business logic. This was a lucky opportunity to write something resembling a compiler: it took in schemas described with our in-house data exchange library and generated C (for FFI) and Swift code (for the end users, i.e., iOS developers).<p>Since Routine uses OCaml for everything (which was a big motivator for joining the company—I wanted to see how that would work out), I wrote it in OCaml. The end result is a 3-5k LOC project. It&#x27;s by no means a full compiler, but it was lots of fun to write. The language got in the way incredibly rarely. On average, it made my life a lot easier. We did encounter our fair share of issues, mostly due to the cross-compilation tooling[1], third-party libraries, and intricacies of FFI. Those do take their toll on sanity.<p>I tried my hand at writing small compilers &#x2F; interpreters in Rust, and the experience was nowhere near as smooth. It was fun, and the runtime performance is definitely there, but the ergonomics aren&#x27;t the same. I especially miss first-class modules whenever I code in something other than OCaml now.<p><pre><code> [1]: we initially used esy [2], flirted with Nix, and eventually switched to opam-cross-ios [3]. [1]: https:&#x2F;&#x2F;github.com&#x2F;esy&#x2F;esy&#x2F; [2]: https:&#x2F;&#x2F;github.com&#x2F;ocaml-cross&#x2F;opam-cross-ios</code></pre>
beaub将近 2 年前
Compilers are in this weird spot where they are really mathematically defined programs (which OCaml excels at implementing), while also having high runtime efficiency as a requirement (the reason why C&#x2F;C++ are such prominent languages for compilers).<p>With such requirements, I think a point that is fair to make is that Rust acts as a great middle-ground. It avoids the cost of automatic memory management and provides low-level control while also having a more powerful type system and a more &quot;functional&quot; style.<p>Brushing off the actual efficiency of the produced binary seems like a huge oversight when dealing with a compiler.
评论 #37041730 未加载
评论 #37047377 未加载
评论 #37041844 未加载
devit将近 2 年前
The author doesn&#x27;t seem to have much experience in writing Rust.<p>For instance, passing RefCell&lt;u32&gt; by value as their code does makes no sense (just use u32...), and the code seems to have a lot of clones, most of which are probably unnecessary, while not having a single instance of the &quot;mut&quot; keyword.<p>In fact, I&#x27;m pretty sure it&#x27;s completely broken, since their gensym doesn&#x27;t do what they want, due to their wrong use of clones and refcells (it should take an &amp;mut u32 and just increment it).<p>And definitely not idiomatic at all.
CollinEMac将近 2 年前
Why does it seem like I&#x27;m hearing about OCaml all the time now? It could just be frequency bias but it wasn&#x27;t that long ago that I&#x27;d never heard of it and now it seems to be getting a lot of attention online.
评论 #37040123 未加载
评论 #37041784 未加载
评论 #37040879 未加载
评论 #37045259 未加载
pjmlp将近 2 年前
If one cares about productivity in typical compiler data structures, naturally OCaml.
medo-bear将近 2 年前
&gt; Lisps can be very flexible, but they usually lack static type safety, opening a wide and horrible door to run-time errors.<p>People should do basic research before writing something silly like this. Qualifying your statement with &#x27;usually&#x27; is just a chicken sh*t approach. Common Lisp and Racket have optional strong typing, leaving the responsibility and choice to the developer. Common Lisp is great for implementing compilers. You also have things like Typed Racket and Coalton. The latter is completely statically typed ala MLTON<p><a href="https:&#x2F;&#x2F;github.com&#x2F;coalton-lang&#x2F;coalton">https:&#x2F;&#x2F;github.com&#x2F;coalton-lang&#x2F;coalton</a>
yafbum将近 2 年前
This starts out as a fair comparison but evolves pretty quickly towards a one-sided recommendation for Ocaml. I&#x27;m quite sure that there are _some_ advantages of Rust that are not listed here and would be curious to learn more about them too.
评论 #37041396 未加载
nine_k将近 2 年前
A lot of people here say that the Rust version is non-idiomatic and likely not even working.<p>So the answer apparently is simple: between two languages, for an important project use the one which you wield best.
josephg将近 2 年前
I normally love articles comparing programming languages at real tasks, but this article seems very low quality to me. The author clearly doesn&#x27;t understand how rust thinks about programs. Instead, they&#x27;re trying to pretend that rust is an alternate syntax for ocaml and being surprised to find it comes up short.<p>The same article could easily be written the other way around. We could start with a high performance rust program (which makes use of arena allocators, internal mutation and any other rust features you love) and then try and convert it line by line into ocaml. We would find that many of rust&#x27;s concepts can&#x27;t be clearly expressed in ocaml. The ocaml code would end up uglier and measurably slower than rust. And just like that the article would reach the opposite conclusion - that rust is clearly the better language!<p>But this is silly.<p>In general, you obviously can&#x27;t translate between languages line by line like this and expect to have a good time. A beautiful C program is constructed using different ideas than a beautiful Lua program. And a beautiful Ocaml program is very different from a beautiful rust program.<p>Some obvious examples of ocaml ideas being overapplied to rust in this article:<p>1. The types don&#x27;t really need to be wrapped in Rc here.<p>2. Rust generally prefers mutable imperative code over applicative code. And if you insist on applicative patterns, functions should take a &amp;Foo.<p>3. Rust code usually doesn&#x27;t rely on recursion that much, so the lack of guaranteed TCO isn&#x27;t something people in the community care about.<p>4. Rust is optimized for runtime performance over code beauty or code size. Of course rust is less elegant looking than a garbage collected language! The trade is that it should also run faster. But where are the benchmarks to make the comparison fair?<p>The match example is just straight out bad rust code. This code:<p><pre><code> fn eval(term: &amp;Term) -&gt; Value { match term { Bool(b) =&gt; Value::Bool(*b), Not(m) =&gt; match eval(m) { Value::Bool(b) =&gt; Value::Bool(!b), _ =&gt; panic!(&quot;`Not` on a non-boolean value&quot;), }, &#x2F;&#x2F; ... lots more nested matches &amp; panics } } </code></pre> Can be flattened, to approximately halve the length of the program like this:<p><pre><code> fn eval(term: &amp;Term) -&gt; Value { match term { Bool(b) =&gt; Value::Bool(*b), Not(Value::Bool(b)) =&gt; Value::Bool(!b), &#x2F;&#x2F; ... (all other valid patterns) _ =&gt; panic!(&quot;{term} invalid&quot;), } } </code></pre> There&#x27;s an old saying: &quot;Every programming language you learn should teach you to see programs in a new way&quot;. Rust is not a crappy alternate syntax for ocaml any more than ocaml is a crappy, alternate syntax for rust. The only thing I learned from the article is that the author doesn&#x27;t know rust well enough to evaluate it.
评论 #37042406 未加载
评论 #37044746 未加载
评论 #37043659 未加载
smitty1e将近 2 年前
I was going to ask, but the author answers this in the end:<p>&gt; Other alternatives to consider is Haskell and various Lisp dialects. If you have already “tamed” Haskell (my congratulations and condolences), probably learning OCaml just for writing a compiler is not going to be worth it; if you have not, OCaml is a much more approachable language.<p>This is an interesting claim, as I thought Haskell and OCaml were more or less equivalently inscrutable.
norir将近 2 年前
Here are the features that I think are most important for compiler development:<p>1) built in eval -- this allows you to transpile to the host language which is invaluable for writing small tests<p>2) multiline string syntax -- for evaling more than just one liners<p>3) built in associative and sequential arrays (for the ast)<p>4) first class closures<p>5) panic support (for aborting early from unimplemented use cases)<p>The AST can be represented as an associative array. Each element type can have a &#x27;type&#x27; field and rather than pattern matching, you can use if&#x2F;else. Performance doesn&#x27;t really matter for the bootstrap compiler because it will only ever be run on relatively small input sets. To get started, you simply walk the ast to transpile to the host language. The snippet is then evaled in the host language to test functionality. Closures allow you to implement the visitor pattern for each ast node, which allows contextual information to be seamlessly interwoven amongst ast nodes during the analysis&#x2F;transpilation steps.<p>Keeping all of this in mind, I have identified luajit as my personal favorite language for compiler development. It checks the boxes above, has excellent all around performance for a dynamic language (particularly when startup time is included -- js implementations may beat it on many benchmarks but almost always have slow start up time relative to luajit) and provides a best in class ffi for host system calls. You can run 5000+ line lua scripts faster than most compilers can compile hello, world.<p>The other reason I like lua(jit) is the minimalism. Once you master lua (which is possible because of its small size) it becomes very obvious that if you can implement something in lua, you can translate the lua implementation to essentially any other language. In this way, there is a sense in which writing a lua implementation becomes almost like a rosetta stone in which a translation can be produced for nearly any other language. With more powerful languages, it is hard to resist the temptation to utilized features that can&#x27;t always be easily transported to another language. In other words, lua makes it easy to write portable code. This is true both in the sense that lua can be installed on practically any computer in at most a few minutes and in the sense that the underlying structure of a lua program that transcends the syntax of the language can be ported to another computing environment&#x2F;language.<p>Another benefit of transpiling to lua is that your new language can easily inherit lua&#x27;s best properties such as embeddability, fast start up time and cross platform support while removing undesirable features like global variables. Your language can then also be used to replace lua in programs like nginx, redis and neovim that have lua scripting engines. This of course extends to transpiling to any language, which again should be relatively easy if you have already transpiled to lua.
评论 #37041586 未加载
评论 #37041695 未加载
评论 #37041662 未加载
programmer_dude将近 2 年前
Neither, F# for the win!
评论 #37061222 未加载
convolvatron将近 2 年前
isn&#x27;t rust kind of a nonstarter for cfg representations which are irreducibly cyclic? yes, one can use the pointers are array-indices thing, but ..
评论 #37040042 未加载
zerr将近 2 年前
Real World OCaml book needs a second edition.
评论 #37041167 未加载
auggierose将近 2 年前
I suggest TypeScript.