Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Microsoft rewrote Q# compiler in Rust (github.com/microsoft)
75 points by avestura on June 21, 2023 | hide | past | favorite | 97 comments


It was previously written in C# and F#: https://github.com/microsoft/qsharp-compiler


Was there a write-up of what the goals of the rewrite were, and why they switched the language and made the new engineering decisions?


I don't think any language sparks joy the way Rust does -- not even Lisp and certainly not C# or F#. Rust gives the compiler lower memory overhead and attracts a broad base of developers.


> I don't think any language sparks joy...

Let the Marie Kondofication of programming languages begin.

But one of Kondo's points is that "Only you can know what kind of environment makes you happy," i.e. there are no universals.


Begin?

The entire reason we have people trying to cram JavaScript everywhere is that, for some reason, it sparks joy for them.

Hell, even going back, K&R vs Allman brace style was about what sparked joy. Color themes? Spark joy. At this point, I am convinced that the way to get a software developer to do anything is to just play on that need for joy.


> The entire reason we have people trying to cram JavaScript everywhere is that, for some reason, it sparks joy for them.

Wait really? I feel like it's just "you literally have no choice for frontend" and the various side effects of that.


That would explain frontend, yes. But that would not explain NodeJS, JavaScript for embedded microcontrollers, and so many more.

Some might say it's Stockholm syndrome, but then there's the Python developers doing the same thing everywhere. And the LISP enthusiasts. So unless there's a lot of Stockholm syndrome (although it's not out of the question when it comes to LISP), a lot of it is easily explained by "me like language here, me go put language elsewhere to keep language"


You're overthinking it. We have Javascript on the server because Javascript was a very commonly known language already (due to being the only choice for web) and the average programmer (one who doesn't post on these forums) is not going to bother to learn another language if they don't have to.

The easiest way to turn front end developers into full stack developers was to let them use the same language for everything, and it was easier to bring JavaScript to the server than to bring any other language to the web.

These days with WASM and JavaScript as compilation targets it might have been avoided, but it's already too late.

Anyway I rambled a bit but the point is "joy" has nothing to do with it.


I think that's just entrenchment at work. When the majority of your developers only know x languages, and one of them is always js, you tend to work by the lowest comments denominator and the tools that everyone can work with are the ones that stick.


That's true, and I also think it's a mistake.

Any decent developer can become competent with a new language in a matter of weeks, whereas making a large application with the wrong choice of language and tooling can become a maintenance nightmare. Given how difficult it is to verify JavaScript programs as "correct", its use on the server has always riled me up.


> But that would not explain NodeJS, JavaScript for embedded microcontrollers, and so many more.

I'm only going to address NodeJS because I think that niche projects that target niche workloads are just unrelated.

I believe it does explain NodeJS. The idea is simple - your frontend engineers can own your edge services/ APIs. They're already heavily invested in JS and, at least at one point, there was a theory that unifying languages across frontend + edge made sense for other reasons.

Some people really just learn one language.


> Some people really just learn one language.

I think that's a gross oversimplification. My colleagues know JavaScript, TypeScript and ECMAScript, as well as YAML, HTML and CSS.


I'm not trying to be mean but are you being sarcastic? I... can't tell...


At this point, I can't really tell either.


I think that's just entrenchment at work. When the majority of your developers only know x languages, and one of them is always js, you tend to work by the lowest comments denominator and the tools that everyone can work with are the ones that stick.


I think the Javascript example is more about what people are already familiar with. Same goes for languages like Python. Other languages can't "spark joy" if you're not familiar or comfortable with them.


I agree with this. I use Fantasque Sans Mono for the same reason - k with a loop makes me feel warm and fuzzy for some reason.


> I am convinced that the way to get a software developer to do anything is to just play on that need for joy.

Works outside software development too.


Whichever language one prefers sparks joy like Rust does for you


While this is true on individual level, Rust has been ranked most liked programming language in many surveys and sparks joy to most of people more than other languages

https://survey.stackoverflow.co/2023/#section-admired-and-de...


What's missing from a survey like that is correlation with prior experience and education. Python was a previous winner on those kind of surveys, and it's a terrible language in many ways.


Where you are failing here is likely empathy, or understanding how other people work or think. This might be because lack of experience in programming, or just because of reflexive negativity. Even if you think Python is a terrible language, for many people it’s the best language for the job. This also includes must PhDs, because Python is the most used languge in science and academia.

When doing critical thinking, please set asides your own biases and try to understand that your own viewpoint is not always the correct one.


I understand why people use Python. However, I'm just assessing it from a technical perspective, not an emotional one.


This answer looks unjustifiably overheated for a statement that says X is "terrible in many ways". It can be the best tool for someone, and still be terrible in many ways, no contradiction here.


Yeah someone needs to do a ranked preference test. Rank all the languages you are familiar with...


Limiting to relatively well-known general-purpose languages I've used in commercial system development:

Haskell, Scheme, OCaml, SML, Rust, Typescript, Smalltalk, Java, Scala, Common Lisp, Kotlin, C, C++, C#, Javascript, Forth, Delphi/Object Pascal, Turbo Pascal, Python, BASIC (various flavors), Fortran.

How about you?


I'd probably go

Rust, Typescript, C++, Go, Java, OCaml, Python, Javascript, Matlab, PHP, SystemVerilog, CMake, C, Bash

Ok I will make this site. :)


Oh I left PHP and Go out of my list, my subconscious blocked them out of existence. They'd be near the bottom anyway. I suppose Go with polymorphic types might be worth another look, but before that it was dead to me.


I feel like Go is a so-so language with amazing infrastructure. How many other languages come with built in easy cross compilation, fuzzing, PGO, etc?

It is really unsurpassed in that regard, which is probably partly why it is so popular in DevOps. If only the language was a bit better...

It's definitely not a bad language like PHP though.


A Subconscious that doesn’t want to admit it, not every “good language” makes it to the next round


What was your commercial application for SML?


We developed the definitional model of a financial instrument modeling and simulation system in SML. The system included a DSL for specifying instrument models, so part of what the SML implementation did was act as a denotational semantics for that language.

The intent was never to deploy it using SML, it was to flesh out and formalize the design, and act as a specification for development of the full system.

The system was designed to run on a cluster long before the Kubernetes days, and so had to deal with many of the distribution, scaling, and concurrency issues itself, in addition to its business logic.

One of the experiences I had while working on that system was that at the time, I was reading "Monad Transformers and Modular Interpreters" - a seminal paper by Liang, Hudak, and Jones - and I thought I could probably quite easily implement the paper's approach using ML parameterized modules, instead of the Haskell typeclasses used in the paper. I tried it, and was soon disabused of that notion. Partly as a result of that, we wrote the distributed simulation engine for a later version of the system in Haskell.


Funnily enough I'm not very familiar with languages I don't like, probably because I elect not to use them.


I think you are a bit detached from reality if you think controlling for experience and education would massively change the picture for python, which evidently enjoys above average popularity with anyone from junior devs to elite programmers (such as Google's Director of Research, geohot etc.).


I cannot help but notice that Perl used to be very popular in early web development, sys administration, and in a a row of scientific fields. And lots of people were enthusiastic about it (as witnessed by CPAN content). Then it was declared unsuitable for teaching (many ways to do everything), and the next gen who started with Python usually claim that Perl is bad, while among older generation who matured cooking Perl scripts you still can hear that Python is nothing more than a less flexible, less expressive Perl's bastard child. So yes, I think, education (and the first usable programming language learned in particular) influence popularity very much.


The issue is what they're educated in. It's not generally programming languages.


What makes you think so? If you've got a background in programming languages, maybe you'll roll your eyes at Guido not getting reduce or tail recursion, or CPython's unsophisticated runtime and under-specified/messy semantics, or whatever, but I'm kind of struggling to see why you'd be particularly down on python compared to other languages that (in the average case) have non-negative utility for software development.


I mentioned Python simply because it was ranked highly in some of these kinds of surveys, even though it has quite a few well-known problems as a language. It demonstrates that ranking in such surveys is not necessarily correlated with the capabilities or fitness for purpose of the language.

In some ways, Python is in fact worse than many of the mainstream alternatives - for example, it's not unusual for people to look to rewrite Python systems in some other language because of performance issues at scale. Same (if not worse) goes for Ruby.


While I admire it I most certainly do not desire it - like Haskell. I need to ship things, not figure out some borrow of a monad.


Languages with built-in checks for correctness, like type checking and borrow checking, help you ship software faster in the long run, cheaper, and with fewer bugs.


I actually don't like Rust. It just doesn't fit me.

To each their own, I suppose.


YMMV, of course, I have a hard enough time managing with one style of brackets, Rust has, what, five (round brackets, square brackets, curlies, angles, and vertical bars)? Never mind the fact that some operators are prefix:

  do_something(a_thing);
Others are infix:

  x = a + b * c;
And yet others are postfix:

  foo.frobnicate()?;
My sole braincell can't handle all that complexity, which is why I'll just stick with simple old Lisp.


Well Rust was written OCaml on which F# was based So i think this was probably for performance, not for any expressive reasons

And personally i consider Rust to be from the OCaml/SML family of languages similar to F#, so i guess they moved within the family


If it isn't clear from this comment rust is no longer written in OCaml and is fully self hosted (as far as I know).


Correct. In this context it’s perhaps also worth mentioning that Rust depends on LLVM.


Yes. Rust's compiler, rustc, is a bunch of Rust code that parses Rust syntax into an Abstract Syntax Tree to which it can apply macros, then this is lowered through two levels of intermediate representations, where more Rust code does the type inference and type checking and eventually borrow checking and various optimisations, until eventually it's lowered to LLVM Intermediate Representation LLVM IR, which LLVM will further optimise then produce machine code for the target architecture.


What do Rust developers tend to do while the code is compiling? Vote 'Rust' in all the programming language surveys?


I know you're getting downvoted, but seriously, Rust compilation/linking does take a long time, especially if you enable fat LTO. The upside is it's doing a lot more for you than say the C or C++ compiler would. It's a very small price to pay for what you get.


Of course not, don't be daft! We go shopping for CPUs.


They play Rust.


Impressive knowledge o7


You can kind of compile (a version of) Rust into C and then compile that as well, but I assume miscompiles are common and there's very little checking done. It's used to bootstrap the compiler for Debian.


I guess yet another minus for F# at Microsoft. Really funny how they manage it.


Really puts me off learning it, other than dipping my toes in functional programming and being experienced in C# and the .NET Core/Framework libraries. I thought it may be easier to start with F# before moving to another functional language.


The tooling (Visual Studio, LSPs, etc.) around F# is very lacklustre, I wish it had better support from MS. At the moment F# just seems to be a playground for experimenting with FP ideas that then get ported to C#.

As for learning a functional language, I recommend this Haskell tutorial[0], and accompanying video series of an experienced haskeller (Brian McKenna) running through it[1]. I've read countless texts and tutorials explaining Haskell and FP to me but it didn't fully click until I saw someone with experience using the language and tooling effectively.

[0]: https://github.com/system-f/fp-course [1]: https://www.youtube.com/playlist?list=PLly9WMAVMrayYo2c-1E_r...

There are a few other video series from other experienced haskellers available that may be better, too, I just haven't watched them so I cannot comment.


I appreciate the response. As someone that struggles with higher-level math, am I going to get a benefit out of starting with Haskell? I have built financial systems in various languages, so my issue isn't necessarily how to code math functionality. It's more of the abstract concepts that get me.


The abstract concepts give you the tools to quickly classify a datatype. They are not limited to Haskell and let you ask the right questions of datatypes in any language.

The foundational concept is functoriality, i.e. mapping over the argument of a type. Whether a datatype has an instance of

1. (covariant) Functor

2. Contravariant functor

3. Functor+Contravariant (phantom argument), or

4. neither

says a lot about its structure and tells me what further questions I can ask (what hierarchies I can expect): A datatype can only be a Monad if is covariant. It can only be Divisible and Decidable if it is contravariant. If it is both (3.) then its argument is not used (phantom) and can be mapped to any type. If it is neither (4.) it can be invariant (where the argument appears in both positive and negative position: like the Endo datatype) or a more complicated datatype like GADT, which would require a more complicated functor.


I believe you will, yes. You may not be able to jump right in to some of the deep discussions about type categories, I certainly can't, but I still have learned a lot from Haskell and both continue to use Haskell itself and use what it has taught me in other languages to my betterment.


Thank you for the explanation and suggestion. Sounds like it will be worth my effort to at least learn, just for new ways of developing, and how that affects any other language I touch.


As a quick example, a lot of what @Iceland_jack has mentioned I can make sense of, but I wouldn't have been able to contribute to that. I guess it is a bit like learning a foreign language and I am at the point of being able to understand what a native speaker is saying to me, but my responses are probably garbled nonsense. :) However I am still confident that what I have learnt has empowered me to be a better developer.


I am ready to treat Q# same way as Microsoft is treating F#.


So sad. Love F#, and Q# seemed like a natural extension, or at least brotherly.

At a high level, it seemed like F# is more functional like OCaml, than Rust is. I'd like to hear more about the reasoning, was it just performance? How different was it to justify a re-write?


> I'd like to hear more about the reasoning

My guess is because Rust is great with WebAssembly and they seem to target it with Q#:

https://github.com/microsoft/qsharp/tree/main/wasm


Disclaimer: engineering manager for the team building it

Yes, targeting WebAssembly, and the ability to then run in the browser, was a big part of it.

WebAssembly (will) also enable our language service extension to run in VS Code for the Web, as well as VS Code for desktop, with largely the same feature set.

It also means the core logic compiles to very performant native code for most platforms, which we use for the CLI.

It's early days for the project, with lots of work ahead of us, but I'm really proud of this first step. Happy to answer any other questions where I can!


But C# has the ability to compile to WASM and run in the browser, using the Mono WASM runtime that's part of the .NET core repo now.

This is what underpins Blazor.

https://github.com/dotnet/runtime/tree/main/src/mono/wasm

Example C# app running in a browser:

https://github.com/dotnet/runtime/blob/main/src/mono/sample/...


You can technically use nail clippers to mow your lawn as well.

Deploying GC language with a huge runtime and stdlib to WASM sounds like a bad idea.


Ever heard of Flash?

Or for something more modern, Flutter.


Flash was abandoned because it was horrible.

Flutter is basically cost center app framework (like xamarin) - not something you model performant software after.


Flash was abandoned because Apple said so.

Flutter is doing quite alright, much better than Xamarin, with the MAUI reboot.


Interesting and disappointing that someone from Microsoft would convey that .NET Core is too slow and not portable enough :) VS Code is Microsoft's tool after all.


It's true though. I mean, not a knock on the .NET team. They (we in a past life!) have moved mountains to get a crusty old Windows desktop development framework into the modern era. But all this does is highlight that the work isn't done yet.


Looking at how others haved approached this kind of stuff, meaning AOT compiled managed languages, like on Google and Apple platforms, and the ups and downs of .NET in Windows desktop development since 2001, from the outside it always feels like the usual set of WinDev vs DevDiv politics.


Isn't one of the benefits of F# the ability to compile into other languages. I'd think it would be possible to have F# run on WebAssembly. But, guess I'm too focused on F#, this is really about Q# running on web assembly, so maybe writing Q# in F# and F# being able to generate web assembly, is too many layers? Added complication?

So, am I hearing correctly, the goal was really about portability, and allowing Q# to run in a browser, not for any performance reasons of .NET.


Portability, minimal size, and speed are all priorities. Building with Rust allowed us to really focus on all of these for both WebAssembly and OS binaries.

For example, if you go to the playground that we publish on every push to main (https://microsoft.github.io/qsharp/), and open the Developer Tools to see the network traffic, you'll see that our WebAssembly module is just 1.5MB (504kb over the wire) - which includes the not just the language (parser, type system, IR, etc.) but also the runtime interpreter and quantum simulator.

Similarly, for the native tools, on my MacBook (i.e. ARM64) the command line compiler ("./target/release/qsc") is 3.9MB, which is entirely standalone with no dependencies.

We do have many features to add, so I'm sure those will grow a bit, but we are focused on keeping things as small, portable, and fast as a general principal.


Re-reading all the posts. I do come back to a basic question, or something I don't get. (and I haven't kept up with WASM, sorry).

If Q# is a language for quantum computing, and it is a niche language just for exploring quantum computing.

Then, how does that lead to a requirement to re-write to target WASM?

If you are a person that would be doing quantum computing, why do you care if you can run it in a web browser, or VS code for the web. You would just install tooling on your own machine. Or if you are editing code in a web browser, the code itself would get compiled and run on server, why does it have to compile and run right there in a browser.

So if we remove WebAssembly as a goal, Why can't you just use .NET, CLR and stick with current MS languages to build it in?

I don't understand why running in the web is a needed feature for this set of users.

I understand RUST is very speedy. Is that the real goal, and all of "Rust also works on WASM", is just a side benefit?

Seems like quantum computing needs speed. Performance is the real goal. To simulate a quantum computer a normal computer must run many more steps.

So we have performance of : .NET, Rust binary, or Rust to WASM.

Guess, maybe I answered my own question. If Rust is faster then .NET, then that is goal, and Rust can also run on WASM as option is a side benefit.

I'm afraid this seems to be more indictment of .NET in general, not just F#.


In a way this seems to acknowledge Native AOT isn't ready and it was better to spend development effort for a full rewrite than collaborating with .NET team to improve the pain points.


Maybe WASM is going to finally deliver the dream of the JVM, and CLR.

Maybe.


Or P-Code, M-Code, TIMI,...


But the language that the compiler is written in doesn't really relate to the target system (ie WASM). Unless they're planning in running the Q# compiler itself in a WASM environment. Which in that case... why?


Well, wasm runs slower right? I'm not that familiar. Seems that if wasm is a goal, then that might negate they did this for performance. What other benefit is there to wasm that would make it a fit for Q#?


Slower than native perhaps. But usually faster than JavaScript on V8.

So if you want fast browser perf, Wasm is a great choice.

There's also Wasm on the edge with the likes of Cloudflare Workers and Vercel https://vercel.com/docs/concepts/functions/edge-functions/wa...

It also has some interesting isolation properties.


Shameless plug for WebAssembly on the Edge: Wasmer recently launched Wasmer Edge, which is Wasm-focused instead of JS-focused compared to Cloudflare Workers and Vercel

https://wasmer.io/products/edge


I respect the hustle. Sorry for not mentioning https://wasmer.io. Keep it up! Competition is great.


When this site says Wasmer's "cold start time" is 50ns, what is it measuring?

You can't even do a syscall in 50ns.

Cloudflare's 5ms includes time to read the application code from disk. (I'm the one who originally did this measurement.)


Hi Kenton!

50ns is the median time to initialize the Wasm module. I think it would make sense to do another round of measuring with more factors that test things end to end, and see how each of the platform performs.

BTW, I'm a big admirer of Cloudflare Workers... great work!


This got me thinking of switching from F# to Rust, so did search and found this article that was good comparison. Others thinking of F# and Rust might dig.

https://jkone27-3876.medium.com/f-is-the-net-rust-62f71f8dae...


Microsoft gets developer relations.



Keep nerds around by letting them re-write things for no good reason?


Why not…just use rust then? I don’t understand the point of all of these niche languages in real life. Python, Go, rust, c, cpp, js, C#, kotlin, but why use others? Each of these have clearly defined strengths and community support.


While I understand your sentiment, Q# is specialized for Quantum Computing: https://en.wikipedia.org/wiki/Q_Sharp

It's arguably different enough of a domain to justify a new language.


This strikes me as a bold (probably marketing) claim more than anything. Looking at the example code, it seems to make use of many "quantum" libraries, but why could those libs not be made available to C# or whatever?

Quantum computing is a niche, to say the least, and the field is far from clearly defined. This sounds a lot of IBM proclaiming RPG will be the best "big iron" language ever - and today nobody uses it.


I'm a compiler engineer on the Q# team - to add to what others have said, Q# is more than a set of quantum APIs, and the Q# compiler does quantum-specific checks and transformations on the AST representation of your program.

To do the same thing in an existing language, you'd need a deeply embedded DSL so that the program can be manipulated by the Q# "compiler" before running it. It's possible, but it can get kind of clunky, where you have to use the "embedded" if statements, for loops, etc. instead of the ones from the host language. A new language helps with having a cleaner separation.


This was more or less how I did it in my reversible rust project. Though I was only really interested in reversibility.

https://github.com/Erk-/RRust


Programming languages for quantum computing needs to uphold some rules normal programs does not need to. The biggest is likely that no information may be destroyed when the program is run, from this follows that it needs to be reversible. This means that from any result you should be able to compute the input. Rules like these can be hard to uphold in normal languages (I have done it with a subset of rust in the past) so a specialized language is often used instead.

There is probably more to it, but these are the parts I know a bit about.


The simple reason is that if you design your language with limitations of a quantum computing you can make certain guarantees about your program being able to physically execute on any quantum computer. You can find more details here:

https://learn.microsoft.com/en-us/azure/quantum/overview-wha...


There are multiple dimensions of trade-offs from which to choose from, i.e. runtime speed vs. convenience of writing, complexity of learning vs. powerful type systems, etc.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: