Hacker News new | ask | show | jobs
by jeffdavis 3423 days ago
It's about the runtime. I think that's probably the most important reason, even more so than memory management or performance.

If you need to write a library to implement the latest protocol, or render the latest image format, or parse the latest serialization format, then Haskell seems great. Unfortunately, the resulting library will be useless except to other Haskell programmers. Nobody wants to link in libXYZ.a and get the entire Haskell runtime, starting threads and doing GC and sending and catching signals.

I tried implementing a handler in postgresql so that you could write user-defined functions in Haskell. I made little progress, even with help on IRC and elsewhere. Any non-trivial function would need to define its own types and use some libraries, but it was far from clear how to do that and the best advice I got was to dig into ghci and try to use some ideas from that. I started down that path, ran into runtime issues, and that was the last straw and I ran out of steam. And that was only to get the most basic functionality: call into haskell to do some computation and return.

1 comments

Honestly for most programmers, no GC is a red herring.
That may be true, but for programmers that can use GC, there are already very good solutions out there.

New products succeed based on how much better they are than the other solutions in their market. Rust's genius is going after the market that can't use GC, which has seen few innovations in programming language design over the last 25 years. (C++11/14/17 has helped this situation immensely, but C++ is still beholden to backwards-compatibility, which makes it unable to adopt several of Rust's more interesting features.)

> Rust's genius is going after the market that can't use GC

But the problem with that is that the market that really really can't use GC is vanishingly tiny. Rust throws the baby out with the bathwater and tries to pressure others into thinking that they are in this market. Most developers on most projects aren't.

And then Rust implements reference-counted pointers in the library, which is the slowest possible way of collecting some, but not all, garbage.

Honestly, if Rust is to become popular, it needs (a) to get rid of this elitist "we are awesome systems programmers" mindset, and (b) a good, optional way to use a GC where it makes sense, with good support for migrating away from it (i.e., by giving you a list of "I cannot determine the lifetime of this object, so it will be allocated on the GC heap" diagnostics on request).

Good cases can be made for having a no-GC mode, but having it exclusively is just premature optimization.

> But the problem with that is that the market that really really > can't use GC is vanishingly tiny.

It's huge, but specialized so may not be on your radar: small embedded devices. Think RAM size from 10s to 100s kB, and Flash from 100s kB to few MBs as rough ranges.

The interest for IoT, and the need for battery operated devices with lifetime of 10+ years, make such platforms very important. And cost and process constraints (like embedded Flash) lead them to be implemented in conservative nodes: 55 to 40 nm typical, will go to 28nm in time but unlikely to go lower. So the amount of processing won't change much in this space I believe. An any gain would not be used to get a bigger CPU/RAM, but to reduce cost and power (less power is smaller batteries => cost too). So this space will stay on the very small side for the foreseeable future.

These are devices that run on very small micro-controller cores and are too small even for a striped down embedded Linux distro. It's either RTOS, or even simple run-to-completion preemptive schedulers, or even bare metal. No room for GC here, and Rust with its focus on performance, leanness and safety is very well suited as a language.

As a platform, the fact that there's only one LLVM based compiler for Rust is a limitation in this space. In the deep embedded space there are a lot of architectures for which there's no LLVM support (Cortus, Andes, BA Semi, LM32, Nios, ...). But I hope this as temporary. GCC is the most common toolchain there, and hopefully at one point GCC will gain a Rust front end. Or maybe LLVM will become more popular in this area? We'll see.

> No room for GC here

True, if you're talking about tiny embedded systems where you would not use GC (nor any dynamic allocation), you shouldn't have much difficulty using Rust. Nor many of its benefits.

> But the problem with that is that the market that really really can't use GC is vanishingly tiny.

If you write a library in C#, you can use it from .NET languages. If you write a library in Java, you can use it from JVM-based languages. If you write a library in Python, you can use it from Python. If you write a library in Rust, you can use it from any language that can bind to C, which is virtually every language that matters.

That is not a "vanishingly tiny" market. It might not be your market, but that's okay: Rust doesn't have to be for everyone in order to be important.

> And then Rust implements reference-counted pointers in the library, which is the slowest possible way of collecting some, but not all, garbage.

That might be the case if you were to replace the JVM's GC with reference-counting, but Rust enables a data layout strategy in which a lot fewer allocations of larger individual objects take place (because not every object requires its own heap allocation). This way, RC in Rust is probably not slower (maybe even faster) than the GC in the JVM, while having a lower memory overhead at the same time.

> If you write a library in Python, you can use it from Python.

Or from C. Or from any language that can bind to C. Like Rust. I'm fairly sure the other languages you listed also allow calling from C and hence from Rust, as well as among each other.

> not every object requires its own heap allocation

Sure. That doesn't change if you add a GC to Rust: Objects won't magically become non-stack-allocable if they were stack-allocable before.

> Or from C. Or from any language that can bind to C. Like Rust. I'm fairly sure the other languages you listed also allow calling from C and hence from Rust, as well as among each other.

But then you have to include a foreign language runtime! Together with all the headaches and interoperability complications that entails. How many .NET applications do you know which include a JVM runtime, or how man Java libraries include on the Python runtime? Now compare that to the number of applications or libraries (in any language) that directly or indirectly depend on a library written in C or C++. Rust will have the same advantage.

> That doesn't change if you add a GC to Rust: Objects won't magically become non-stack-allocable if they were stack-allocable before.

My point is that a GC probably won't have a positive effect on most programs written in idiomatic Rust, therefore there's no need for it (contrary to what you claim).

"But the problem with that is that the market that really really can't use GC is vanishingly tiny."

Even if that's true (which I don't believe), tiny markets have a way of expanding when new offerings are available.

New people are getting involved in OS development in rust, for instance. We might see some really interesting stuff happen there. The same thing may happen with databases and rust.

And you didn't address my example, which was all of those "-devel" packages you need to install to get all of those libraries that so much software depends on: libssl, libjpeg, etc.

"Rust throws the baby out with the bathwater and tries to pressure others into thinking that they are in this market."

And this has what ill effect?

This will be my last post in this subthread because I think most of my points have now been made several times...

> New people are getting involved in OS development in rust, for instance.

Tiny market. Expanding it to be slightly less tiny doesn't make it non-tiny. More importantly, positioning Rust as an operating systems programming language will not get people to use it for more general application programming.

> The same thing may happen with databases and rust.

Also a tiny market. Also, not sure how wrestling with the Rust compiler will advance database theory or practice. Even more importantly, the implication (in the context of the thread) that it's impossible to write a database system in a GC language is false. To optimize the implementation, you may probably want to avoid GC in the innermost hot parts. That would be possible with the hypothetical Rust-with-optional-GC I mentioned above.

> And you didn't address my example, which was all of those "-devel" packages you need to install to get all of those libraries that so much software depends on: libssl, libjpeg, etc.

I don't know what exactly you mean by that since you even need those packages for C programming, and you need them (or something equivalent to the headers they provide) for Rust, but yes, language interoperability is hard, and yes, some language runtimes make it harder than it should ideally be.

> And this has what ill effect?

Many people will read stuff about OS kernels and database systems and vaguely elitist but never concretized ramblings about "systems programming", coupled with "OMG, everything must always be super-fast at the expense of programmer productivity" and decide that they are not in this market. And then they will keep using Python. Or, just to rub it in, Go for "systems programming" like NTPsec. <shrug> I never said that that's a bad thing; I just said that this will not drive more general Rust adoption.

Well, even though I'm totally for using a modern GC when I can, implementing an efficient GC (low pause, high throughput) requires a lot of effort and special hardware. This is still not available for a number of platforms, particularly the tiny ones, where you may only dream of things like memory virtualization. Also, reference counting may not be as bad as you think when objects are never shared between threads and when you have a smart compiler that can elide most of redundant increments/decrements.
I admit that I love C++. Of the time I spent learning programming, C++ took the lion's share. I think the language is making amazing progress since C++11. So, I started to make even more efforts to learn all the changes the language was getting.

Then, I saw rust. I fell in love with it. It is indeed what I see as the future for one who isn't tied to using C++ or C from legacy, programmer-knowledge or programmer-availability constraints. I, decided that I will place my bets on rust and am willingly giving up all the investment I made in C++. If I am their target audience, then they've definitely reached me!

Are the with-GC options really that much better? Rust or OCaml's advantages over C++ seem much the same as OCaml's advantages over, say, Java, no?
I don't quite follow the question and/or implication.
Nostrademons said "for programmers that can use GC, there are already very good solutions out there", which I understood to mean "the advantages of most ML-family languages over other languages that require GC are smaller than the advantages of Rust over other languages that do not require GC". Which I was questioning.
I wasn't thinking specifically of ML-family languages, though they could be included.

Rather, if you are in a problem domain like web-development or server-side microservices where a GC is fine, there are lots of decent options for programming languages. Python, Ruby, or PHP. Go. Any of the JVM languages - Java, Scala, Clojure, Kotlin. Swift or Objective-C. dot-NET. Many of these have had continuous attention over the last twenty years, they've got major corporate backers, and so a lot of the recent research in PL theory gets ported over to them.

If you are in a problem domain where you can't use GC - like computer graphics, games, databases, information retrieval, operating systems, or embedded - you have basically one option. C++. C++ has gotten a much-welcome facelift recently with C++11/14/17, but the core of the language is still 40 years old, and the language as a whole makes serious compromises (like memory safety) for backwards-compatibility. The excitement about Rust largely stems from its competition being C++; if you pit Rust against say Python or ES6 in the domains in which the latter are used, it's very much "Why would I use this?"

Interesting point.

I don't know if I'd pick Java as a comparison point because the ecosystem is unimaginably large, so it's hard to compare to Haskell/OCaml. A better one might be Golang or ruby.

I think ML languages just never made the case that other languages are bad enough for the particular thing someone is doing now, e.g. a web app. If you hit a NULL, you get an exception, track it down, probably not a huge issue. The best case could be made for ML on security grounds, but unfortunately nobody cares about security.

On the other hand, people were convinced that C/C++ were bad after decades of people saying so. But people didn't feel like they had an alternative until rust came along.

Try to get two programming languages to cooperate that use different GCs/runtimes. Not one combination out of the following works: C#, Java, Python, Ruby, Haskell. Because rust is runtime-less you can combine it with any of those programming languages.
This is one of those points that is so obvious that it has never occurred to me.