Live data from Hacker News

The Rust I wanted had no future

graydon2.dreamwidth.org

441–450 of 523 posts

Re: The Rust I wanted had no future

#442
post #403
post #398

Earlier quoted context omitted.

No. In Rust check is there by default, with optional unchecked access. In C++ the safety is off by default and you have to remember to check. It's like Yaml parsers, they had "load_yaml" which is unsafe and "safe_load_yaml" which is the secure option. Imagine no surprise when Rubyists went for shorter safe looking method and got their servers pwned.

I think you are wrong. I looked and in Rust doc it says that: "Removes the last element from a vector and returns it, or None if it is empty". You better be doing check for "None".

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 to check BEFORE you pop_back().

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.

Re: The Rust I wanted had no future

#443
post #323

Earlier quoted context omitted.

> Dependency management is best in class Do crates have namespaces that ownership is verified for?

Crate namespaces is best-in-class++ feature and currently not available.

Yeah, I ask because the JVM world has had that since... whenever Maven's central repository came about [0][1][2], I guess, and it ensures that there's no debate about namesquatting [3], nor typosquatting attack vectors [4].

I am constantly baffled that NPM, PyPi, crates.io etc. didn't copy this idea for those last two reasons. In my mind, it's not quite best in class without it.

[0]: https://central.sonatype.org/publish/requirements/coordinate...

[1]: https://central.sonatype.org/faq/how-to-set-txt-record/

[2]: https://central.sonatype.org/publish/requirements/coordinate...

[3]: https://internals.rust-lang.org/t/pre-rfc-formal-squatting-p...

[4]: https://blog.sonatype.com/this-week-in-malware-may-13th-edit...

Re: The Rust I wanted had no future

#444
post #321

Earlier quoted context omitted.

I think you're manifesting what I'm talking about. The reason you cannot replace async with threads has nothing to do with the ecosystem, but the simple fact that threading is a model of parallelism and async/await is a model of concurrency. These are two subtly different concepts in software architecture, but they are not the same thing. More concretely, threaded code has nothing to say about whether or not its sync…

> I think you're manifesting what I'm talking about. The reason you cannot replace async with threads has nothing to do with the ecosystem, but the simple fact that threading is a model of parallelism and async/await is a model of concurrency. That is an artificial distinction you made up. I have written many apps and desktop applications, all of which where using 3-10 threads, some of them doing "parallel" work mean…

It's not an artificial distinction at all, but it is subtle.

2, 4, even 256 sockets exchanging data can be worked with concurrently on a single thread and gain performance vs blocking and waiting for the first socket to finish. There's no parallelism, since they're never actively reading/writing at the same time, but they're concurrent because they exist and operate in overlapping timeframes.

Running two independent algorithms could mimic this - run part of algo A, then part of B, then A, etc. It's not useful for performance, though. To be useful you require parallelism - you have to have the algorithms executing at the same time, using multiple threads.

On async itself - it's not perfect, but honestly, there are contexts where it makes a lot of sense. I work on a lot of non-blocking C code - the entire programs are basically epoll and timer driven. As a result, the high level coordination is just callback hell. Async is very nice in comparison.

Yes, you can spin up threads to do everything with blocking, but non-blocking I/O came around specifically because the threads add overhead and kind of suck. It's worth noting that having threads can also infect the codebase. You either have to carefully manage mutexes, or you only communicate with channels and have to worry about keeping things updated and in sync. Sometimes this works great with minimal communication between threads. However, if you have one socket per thread and the sockets are all triggering actions that mess with the same data... it's not so great.

Re: The Rust I wanted had no future

#445
post #211
post #145

Earlier quoted context omitted.

> Compiled vs interpreted makes it easier to catch (syntax) errors beforehand. ... Mapping JSON (or whatever) to strongly typed objects is great cough C#. You also get LINQ. And a fairly heavy amount of web frameworks in ASP.NET / Razor.

Or Java, F#, Scala, Kotlin, Haskell. If we were to randomly pick a language, chances are it could be a good fit for these — Rust became as well-known as is because it was made for a different niche, where there were no competition.

Hell, even Python can map JSON to a strongly typed object. I am a firm fan of Pydantic and its competitors when dealing with JSON blobs. No-one deserves a KeyError in prod code.

Re: The Rust I wanted had no future

#446

Earlier quoted context omitted.

My understanding is that for the Elm BDFL, the B was dropped.

The language creator has preferred to work on the development of the language largely in private, for the last couple of years. He’s explained why he’s chosen to do this and why he thinks it is beneficial. But, understandably, some people haven’t take too well to the lack of updates. I think whether you view that as benevolent or not (I would, because I agree with lots of de facto development standards being detrimen…

I was more thinking of a) the ring-fencing of native code and b) his conduct in discussions about such things. Guido was never that abrasive.

Re: The Rust I wanted had no future

#447
post #321

Earlier quoted context omitted.

I think you're manifesting what I'm talking about. The reason you cannot replace async with threads has nothing to do with the ecosystem, but the simple fact that threading is a model of parallelism and async/await is a model of concurrency. These are two subtly different concepts in software architecture, but they are not the same thing. More concretely, threaded code has nothing to say about whether or not its sync…

> I think you're manifesting what I'm talking about. The reason you cannot replace async with threads has nothing to do with the ecosystem, but the simple fact that threading is a model of parallelism and async/await is a model of concurrency. That is an artificial distinction you made up. I have written many apps and desktop applications, all of which where using 3-10 threads, some of them doing "parallel" work mean…

https://towardsdatascience.com/concurrency-and-parallelism-w...

Besides IO Completion Ports for async IO has been the fastest way to do heavy IO on Windows, and it was introduced years before JavaScript even was a thing.

And that's just one example. So hardly think JavaScript was the main driver there.

Re: The Rust I wanted had no future

#448
post #439
post #422

Earlier quoted context omitted.

Are you saying that Rust will refuse to compile code that does not explicitly check option return result for empty?

>Are you saying that Rust will refuse to compile code that does not explicitly Depends what you mean by explicit. Look at it like this: pub fn main() { let mut vec : Vec = vec![]; let x = vec.pop(); println!("{:?}",x); // prints: None } In this case you see the value is missing. vec.pop().expect("I want a value") will panic with "I want a value" because value is empty. And most rigorous way to deal with it is: if let…

for some reason I can not answer your subsequent reply so I do it here:

I looked at your example and played a bit with it and yes I agree with you - compiler does help in this case.

My old text:

So instead of checking if vector is not empty you check that the return result is not empty. I do not see much difference. If Rust compiler would choke when "else" clause in your example is not present I would understand your point about compiler preventing improper access.

Re: The Rust I wanted had no future

#449
post #442
post #403

Earlier quoted context omitted.

I think you are wrong. I looked and in Rust doc it says that: "Removes the last element from a vector and returns it, or None if it is empty". You better be doing check for "None".

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 bomb if pop() returns "none" and you try for example add said "none" to some number.

Re: The Rust I wanted had no future

#450
post #372
post #361

Earlier quoted context omitted.

How about waiting until all or part of donut pack is eaten by multiple eaters? Jokes aside, async/await comes from easier handling of a callback code and automatic function splitting. Writing asynchronous donut eating in loops or with yielding of partial results is very easy to swallow with such syntactic sugar. The whole model is very easy to grasp and to work with. I'm not saying that's the best solution but it def…

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.
Post reply on HN