Live data from Hacker News

The Rust I wanted had no future

graydon2.dreamwidth.org

481–490 of 523 posts

Re: The Rust I wanted had no future

#481
post #372

Earlier quoted context omitted.

Doesn't matter. You either wait until donut is eaten by others or you don't. Caller is deciding if it's "synchronous" (blocking) action or not. The question is how you translate mental models from real world to the code, and async/await fails here spectacularly. It's just weirdly unnatural thinking about sequencial processes. It requires tremendous amount of cognitive gymnastics just to reason about simple things.

I’m sorry but isn’t this exactly how async/await works from the perspective of the caller? If you want to wait until the donut is eaten you `.await`. If you don’t, you do other stuff and then join the future later. The fact that the executor can get other stuff done while you’re awaiting the donut consumption is largely invisible from the caller’s perspective.

That's only if you marked function with "async". Developer who writes code for "eating a donut" supposedly has better knowledge of how I'm supposed to eat it - synchonously or asynchronously. So if they didn't mark function as "async" I can't decide how I should eat it, it's decided for me.

Re: The Rust I wanted had no future

#482
post #471
post #435

Earlier quoted context omitted.

It's not just that defaults matter, the problem here is why have footgun as the default? In a runtime example I can run it with tests and it would behave fine if both values are same or first arg is bigger, in Rust's case it would behave valid for ANY combination of arguments.

Likewise with C++ if the safety belt is buckled.

Heavy disagree. This is less giving a safety belt and more like saying we got airbags (that are deadly without seatbelts) and a DIY seat belt is somewhere in there too (it's in a box under the seat).

Coming from Java the C++ stuff is jarringly unsafe.

Re: The Rust I wanted had no future

#483
post #449
post #442

Earlier quoted context omitted.

Problem is, you call pop on empty vector in C++, you get nasal demons. Not a case in Rust. I'm not a C++ expert but here is my understanding. Vector is essentially a tuple of (dynamic_array_address: ptr, size: size_t, capacity: size_t). To pop a value from vector you just decrements size. So what happens when you have empty vec? Your size is 0, and you're substracing 1, which causes undefined behavior. Correct way is…

>"Correct way is to check BEFORE you pop_back()" Absolutely and this is exactly what I do. I always check the containers before removing elements. >"In Rust, any number of invocation of pop() will not result in undefined behavior. You can ignore the value, or you can check it, but it doesn't expose you to UB just for slightly misusing a vector." I do not understand "slightly misusing" part. I assume in Rust it would…

> I assume in Rust it would bomb if pop()

That's the thing. It wouldn't. Worse you can do is make whole program panic, with well defined stack trace and message.

It will never return non-sense and pretend all is ok.

Re: The Rust I wanted had no future

#484
post #470

Earlier quoted context omitted.

You turned on a feature which helps diagnose this type of mistake at runtime, and it helped you by diagnosing the mistake at runtime. What does that prove? What I'm talking about is that Rust's Option is very cheap in all the cases where it can be very cheap, which makes this whole design feature more affordable. C++ eventually grew std::optional which is not powerful enough for this work and yet is also bigger and s…

It proves that there is a way to diagnose this type of mistake, that is what matters. Unlike C, which the only way to be safe is not to touch it at all. As for performance, ISO doesn't implement compilers, there are many ways to improve performance while keeping the semantics in line with the standard. If the compiler vendors decide to focus elsewhere is another matter, a bit like there are languages as complex as Ru…

Still, catching errors at runtime is subpar compared to catching them at compile time.

Even your dynamic example won't tell me calling pop/push x/y times respectively will fail if x > y.

I have to trigger it somehow.

Re: The Rust I wanted had no future

#485
post #237
post #226

Earlier quoted context omitted.

In C++ it is an error, if one bothers to enable bounds checking. https://godbolt.org/z/vYcMhE9h7 > Error: attempt to access an element in an empty container.

Someone much more insightful than me pointed out that most of the safety advantages of Rust are really a cultural phenomenon, rather than a strictly technical one. You could write unsafe unsafe Rust that derefs invalid pointers all day but when building systems and libraries with Rust, people value safety and Rust enables that as a priority.

> Someone much more insightful than me pointed out that most of the safety advantages of Rust are really a cultural phenomenon, rather than a strictly technical one

It's not. It's a safety phenomenon. See Java, C# etc.

Java doesn't have huge focus on it, but managed to get it right.

Re: The Rust I wanted had no future

#486
post #261
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…

It's crazy that the programming community even accepted the concept of async/await as a sane one. Being sync or async is essentially a property of the attention of the caller, not of the action itself. Is "eating a donut" a sync or async action? If I'm focusing all my attention on it, essentially putting all tasks aside (after) - then it's a synchronous action. If I'm reading a book/watching a video/walking/etc, whil…

Async/await, at least in JS, is here to make asynchronous code look like synchronous code, as in you can say "let toto = await asynchronousFunction(); doSomething(toto)".

Without it when you want to do asynchronous stuff you either block on it (not good since JS is single-threaded), eg "let toto = asynchronousFunction(); doSomething(toto)" and nothing can be done during the time asynchronousFunction is waiting on IO or something (in a browser environment that means part of your website stops responding to user input); or pass as an argument to the asynchronous function a function that will be executed by the asynchronous function once it "wakes up" (usually called a "callback"), and while it's waiting, the JS runtime can execute other stuff, eg "asynchronousFunction((toto => doSomething(toto)))".

Callbacks were I think from the start in JS. After a while promises were introduced, which compared to callbacks avoids nesting, and probably have some other advantages that I don't know about. Still, they are method chaining and not "regular code". For example regular try/catch won't work as usual, you have to use .catch(). Even later async/await got introduced, which allow you to write asynchronous code as if it was regular code, with a few exceptions (for example you can only use await in an async function, top-level await took a while to land on Node, stuff like that).

I don't think using real world human actions helps with understanding any of that. Async functions make sense in JS because again, JS is single threaded and if you do a blocking call (like asking the kernel to read a file, or making an HTTP request and waiting for the response), the event loop is blocked. From Node.js documentation's on the synchronous function in the fs module:

> The synchronous APIs perform all operations synchronously, blocking the event loop until the operation completes or fails.

Re: The Rust I wanted had no future

#487

Earlier quoted context omitted.

Python reached where it is because university CS programs which had previously been teaching Java reached for a new language.

Most universities I knew were still teaching Java well into python's rise to popularity a decade ago. Python got where it is by focusing on being simple, easy, and nice to use . Seriously take a look at PEP-20 sometime: https://peps.python.org/pep-0020/ Things like "There should be one-- and preferably only one --obvious way to do it." just was such a breath of fresh air in language design.

I take it they didn't extend that to the package managers :)

Re: The Rust I wanted had no future

#488

I don't understand why in Rust integers wrap around. It doesn't make sense and there are vulnerabilities caused by wrapping integers in C.

What's the alternative? What would you expect happens?

Panic so that the invalid value doesn't get stored into the database or somewhere else. The developer then would notice the problem and fix it.

Silently using invalid value is the worst choice.

Re: The Rust I wanted had no future

#489

Earlier quoted context omitted.

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.

Nobody complains about the Java compiler. Everyone complains about the class loading performance.

My only experience with very bad class loading performance was debugging the Eclipse Collections. Single handling, it was the worst I ever saw. Everything else is manageable. Does anyone know why that particular JAR is so bad?

Re: The Rust I wanted had no future

#490

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…

>A good example of this trade-off in Java is Lombok. A very handy library that legitimately avoids a ton of boilerplate, but it also absolutely tanks your build time.

I don't think this is actually true right now and for a while.

>In a real system, a large one, your team is better off just getting good enough with their editor that they can generate the hateful boilerplate

Which you can get by delomboking if you really need to.

Post reply on HN