Live data from Hacker News

The Rust I wanted had no future

graydon2.dreamwidth.org

381–390 of 523 posts

Re: The Rust I wanted had no future

#381
I wanted nearly the same language Gradyon wanted, but I also suspect that my tastes are insufficiently mainstream for a language to my tastes to be as popular as Rust has become (much less as C++ is).

Re: The Rust I wanted had no future

#382

Earlier quoted context omitted.

> I have always found that they are almost instant for incremental builds (assuming you use lld or mold) They are not almost instant once your project grows to a certain size, which is still well within the bounds of a realistic single company’s project (I work on Materialize which is all in rust).

And you have it set up with multiple compile units, shared generics, and lld (or mold ideally)?

> multiple compile units

Yes

> shared generics

I don't know what that is. Some googling suggests that it's a nightly-only feature, whereas we use the stable compiler. If it's something that can be done in stable, I'd appreciate a pointer.

> lld (or mold ideally)

    $ echo $RUSTFLAGS
    -C link-arg=-fuse-ld=lld -C debuginfo=0

Re: The Rust I wanted had no future

#383

Too bad graydon didn't get his way with build times. I've come to believe that the most important feature of any development environment is to minimize the built-test-debug cycle. Of course, a real system has many different ones, ranging from "language level" to "I have to redeploy and perform a complex series of actions in an app or 3". But at the language level I've found that build performance is of paramount impo…

I'm not here to advocate for Lombok. However, you are first that I saw here to complain about much slower compile times. Can you teach me more? On a multi-core 5GHz desktop PC with 64GB RAM, who is really thinking about Java compile times these days? And I have worked on 1M+ line projects. Sure, the first compile is slow, but after, everything is incremental.

It's not the compiler, in this case. Lombok generates code, and for reasons (which I have since forgotten) it always generates code and invalidates incremental builds in gradle, for example, at least when used in combination with ORM annotations. This happened at a previous contract on a company computer so I don't have the links, but IIRC the gradle docs mention the interaction(s).

I wanted to delombok to save 30s off of each build, but the rest of the team(s) refused to let it go. I thought, and still think, that was a short-sighted mistake.

Re: The Rust I wanted had no future

#384
post #18
post #6

Very interesting insight from Graydon, in hindsight I too would have loved something more towards ML than C++. I never liked the kitchen sink approach that I see first C++, now Rust moving towards, but I respect what Rust has managed to solidify into. It's a good language. That said, I still hate async with a passion, it makes the language more complex and not very elegant (i.e. function coloring). And now that I kno…

Function coloring article conflated two things: one was legitimate limitation of JS unable to wait for async result from sync call, and the other was just author's opinion how the syntax should look like. Rust's async doesn't have the limitation author described – you can spawn and block both (Tokio has some limits there, but that's Tokyo's choice, not language limitation), making "color" largely irrelevant. The seco…

JS has first class functions that you can pass around. The different colors debate was just a confusion - there where only one type of function, just that some functions took a function as an argument, althgough JS has no async functions. All async functions in JS comes from the runtime, like addEventListener for web DOM events. The "solution" to the non existing problem the committie came up with was to introduce 3 new types of function. So JS went from one type of function, to four types of functions.

Re: The Rust I wanted had no future

#385
post #217

Earlier quoted context omitted.

The fatal mistake is not enabling bounds checking, which most STL implementations support.

-Wabsolutely-everything I haven't written the Language of Kings in a while: does GCC -Wall truly enable all warnings yet?

Obviously not. It would be an instant scandal if they tried that.

Re: The Rust I wanted had no future

#386
post #311

Earlier quoted context omitted.

I blame a lack of tools. JS devs have been transpiling for years now and it works. Python should have released a conversion tool that could automatically convert most stuff and identify the stuff it couldn't convert. This kind of directed upgrade would have made the process much easier for developers to actually accomplish.

I'm confused, because isn't that exactly what they did? What was wrong with 2to3? https://docs.python.org/3/library/2to3.html

It didn't work well at all in my experience. Given how much code was thrown out rather than ported, I'm guessing that I'm not alone.

Re: The Rust I wanted had no future

#387
post #6

Very interesting insight from Graydon, in hindsight I too would have loved something more towards ML than C++. I never liked the kitchen sink approach that I see first C++, now Rust moving towards, but I respect what Rust has managed to solidify into. It's a good language. That said, I still hate async with a passion, it makes the language more complex and not very elegant (i.e. function coloring). And now that I kno…

> a zero-cost abstraction

It's just an abstraction, it's not zero-(runtime)-cost. It might be the "lowest possible cost", still nonzero.

Re: The Rust I wanted had no future

#388

Earlier quoted context omitted.

I'm interested in more on this. What can I do in C++ that I can't do in Rust?

This is just one example, but moves are always bitwise, correct? So if I want an object to track all users of it in C++, I can just make a smart pointer for it whose copy/move/destruction operations notify the object about each event. How would you do that in Rust? (Similarly, what if I want a relative pointer?)

You can track all of this (things like Rc or Arc do) except move.

Relative pointers are possible, depending on what you mean. Making this safe (e.g. preventing users of that type from breaking the relative addressing) is done via the Pin type.

Re: The Rust I wanted had no future

#389
> Environment capture. I often say (provocatively) that "I hate lambda", but lambda is actually (at least) two separate language features: one is a notation for anonymous function literals; another is equipping those anonymous function literals with environment capture. I don't really care either way about having such a literal syntax, but I really do dislike equipping it with environment capture and think it's a mistake, especially in a systems language with observable mutation. Early Rust had something called "bind expressions" which I copied from Sather and which I think are better (clunkier but better). Rust gained lambda-with-environment-capture in a single package which I didn't object to strongly enough, as part of trying to make interior iteration work on LLVM-with-no-coroutines, and this motivation was later removed when we moved to exterior iteration. But "if I were BDFL" I would probably roll back the environment capture part (it's easier to tolerate for non-escaping closures which many are, eg. in non-escaping coroutines / stack iterator bodies, but .. eh .. complex topic).

TFA loses me here. I rather like the Fn/FnMut/FnOnce business, though yeah, closures of dynamic extent are very limited unless you Box them to make them of indefinite extent... and so the whole language lacks that character that functional languages with GCs have, but it's still functional, just functional with a straight-jacket.

Earlier in TFA there's a mention of exterior iteration as in generators, and I want to point out that while generators are very nice, they are not a substitute for closures. Icon, for example, had iterators and first-class co-routines ("co-expressions"), but no closures, and so where one needed closures one had to use co-routines (costly!). It's true that with generators one needs closures less than without generators, but still, closures are very important.

> Traits. I generally don't like traits / typeclasses. To my eyes they're too type-directed, too global, too much like programming and debugging a distributed set of invisible inference rules, and produce too much coupling between libraries in terms of what is or isn't allowed to maintain coherence. I wanted (and got part way into building) a first class module system in the ML tradition. Many team members objected because these systems are more verbose, often painfully so, and I lost the argument. But I still don't like the result, and I would probably have backed the experiment out "if I'd been BDFL".

This loses me too.

It's great then that Rust didn't have a BDFL! :)

> Underpowered existentials. The dyn Trait mechanism in Rust allows runtime and heterogeneous polymorphism, a.k.a. Existentials. These types are useful for many reasons: both solving heterogeneous representation cases and also selectively backing-off from monomorphization or inlining (when you have those) in order to favour code size / compile time or allow dynamic linking or runtime extension. Early Rust tried to use these extensively (see also "first-class modules") and actually had an intermediate-rigidity type called an obj that was always a sort of Cecil-like runtime-extensible existential glued to a self-type record that allowed method-by-method overriding at runtime (almost like a prototype-OO system). Today's Rust strongly discourages the use of any such dynamic dispatch, a feedback loop arising from both technical limitations placed on them and a library ecosystem that's taken that as a sign never to use them.

This, on the other hand, is a brilliant observation and I agree with it as with much else in TFA.

> Tail calls. I actually wanted them! I think they're great. And I got argued into not having them because the project in general got argued into the position of "compete to win with C++ on performance" and so I wound up writing a sad post rejecting them which is one of the saddest things ever written on the subject. It remains true with Rust's priorities today, I doubt it'll ever be possible across crates (maybe maybe within), but as with stack iterators IMO they're a great primitive to have in a language, in this case for writing simple and composable state machines, and "if I were BDFL" I probably would have pointed the language in a direction that kept them. Early Rust had them, LLVM mostly made us drop them, and C++ performance obsession kept them consigned to WONTFIX bug status.

Oh dear. TCO is essential, IMO. I understand that it may not be possible in cross-crate cases, but still, TCO is very important.

Re: The Rust I wanted had no future

#390
post #353
post #304

Earlier quoted context omitted.

Return either value or an EMPTY placeholder. Look Java did it. It returns a nullable value or Optional.

Then I have to check the result anyways. Same thing

You should always check

The argument is that Rust forces you and in C++ you can forget/the compiler can do what it wants

Post reply on HN