Live data from Hacker News

Rust means never having to close a socket

blog.skylight.io

151–160 of 165 posts

Re: Rust means never having to close a socket

#151
In Rust, unlike in garbage collected languages, you never1 explicitly close or release resources like files, sockets and locks

GC languages is trying to emulate machine with infinite memory so you don't need to bother yourself with _memory_ management. It's not compatible with rust's resource management system that manages resources and treats memory as another type of resource. The same is true for C++ BTW, in good C++ code you never release resources by hand and use ownership for this (RAII).

Re: Rust means never having to close a socket

#152

Earlier quoted context omitted.

Unfortunately Swift is not open source or cross platform

Right, I meant solely on paradigm.

Ok, let's assume that they open it.

First there will be need of a standard library. For the moment to do anything sensible you are importing Apple's Foundation Library (probably in one year time it will be better).

Then I see no problem to have it server-side (both as a scripting or compiled language).

Re: Rust means never having to close a socket

#153

"Rust achieves both of these features without runtime costs (garbage collection or reference counting), and without sacrificing safety." If it is freeing everything at the scope boundary it is incurring a huge runtime cost relative to garbage collected languages. GC scales with the number of live objects during GC while this scheme scales with the number of allocated objects. It is far more predictable than GC but I…

> It is far more predictable than GC but I don't believe that it isn't more expensive. A GC has to determine liveness of objects, so it has to traverse the object graph (or at least the most recent generation if the GC is generational) to know which objects are still alive and which aren't. That's what "GC scaling" refers to. Then it still has to deallocate dead objects, and pay the same deallocation cost as scope-bo…

Good generational GC doesn't need to deallocate objects one by one, instead of that it can deallocate objects in bulk (if there is no finalizers). It can allocate memory faster because it doesn't need to use memory allocator to create every object, it just increment pointer that points to the beginning of the free space. It's true that modern GC has greater throughput than simple allocation/deallocation schemes. Problem is predictability (as been mentioned).

Re: Rust means never having to close a socket

#154

Earlier quoted context omitted.

> It is far more predictable than GC but I don't believe that it isn't more expensive. A GC has to determine liveness of objects, so it has to traverse the object graph (or at least the most recent generation if the GC is generational) to know which objects are still alive and which aren't. That's what "GC scaling" refers to. Then it still has to deallocate dead objects, and pay the same deallocation cost as scope-bo…

It doesn't have to deallocate dead objects. That is sort of the point of most collectors.

But it has to scan/mark all the objects, not just the the unused ones. This has large overhead in big-mem apps. Not to mention that usually this forces the whole app into RAM (makes swap useless) and also potentialy drains cpu caches. And to amortize this it often has more memory overhead (up to 2x) than typical fragmentation in a manually managed app.

Re: Rust means never having to close a socket

#155

As someone who's been using (and really liking) rust for about 6 months, there are two things in this article which are, I'd say, 'common misconceptions' about rust: One of the coolest features of Rust is how it automatically manages resources for you, while still guaranteeing both safety (no segfaults) and high performance. In rust there are two types of code. 'safe' and 'unsafe'. The above is only true if your enti…

> That is, if you write entirely 100% safe code, and use some library that uses 'unsafe' code at a low level (this is very common; for example, an C binding or memory optimization), then rust does NOT guarantee safety. What do you consider a "guarantee"? Do you consider pure JavaScript to "guarantee" safety, even though there have been exploitable bugs in the JIT and interpreter? Do you consider pure-computation, non…

"We've talked about adding a lint so the compiler can optionally warn and allow you to fix it if this performance cost is a concern to you. (It's a very minor cost—one test and branch on a stack byte, and again only if the object is conditionally moved.)"

Might I just make a meta comment that while that may not be a huge use case, the ability to assert that some particular optimization is firing and get warnings if I've done something to break it is something I've wanted out of a language for a long time. I know it's easier said than done, but I'd love it.

Re: Rust means never having to close a socket

#156
post #138
post #37

Earlier quoted context omitted.

Freeing resources as soon as humanly (computerly?) possible will optimize your memory usage, but can actually be worse for execution speed. If you're willing to use slightly more memory, it's generally faster to free memory in coarse chunks than one-thing-at-a-time. So even though Rust can conceivably free memory sooner, it might as well defer freeing until the end of the scope, since it can prove that that's safe. T…

Thanks. I can see the pro in that choice. But the con would be memory starvation (assuming that heap is bounded as in the JVM). I think one middle-path could be to mark the resource as released as soon as compiler detects it, and then release it 1. when the allocator is starved or 2. when the resource goes out of scope 3. when drop() is explicitly called

Heaps aren't bounded in systems contexts; a process is free to gobble up the entire address space if left unchecked, which would (hopefully) result in your process being killed by the OS.

I believe we have discussed your first bullet point there, with regard to attempting to free waiting-for-the-scope-to-end-but-not-being-used memory in the event that allocation fails. But this is a hairy subject, and is beyond my expertise.

Note that your third bullet point does cause memory to be freed immediately, because the `drop` function is a scope all its own.

Re: Rust means never having to close a socket

#157
post #14

For files python[0] does not need an explicit with to close the file. It gets closed when references reach zero. [0] For the pedants repeating each other in the replies... Where by python, I mean the implementation that 98% of people use, called python, which the competition calls CPython. Yes it is a great feature of the implementation, like the deterministic memory management through reference counting.

That's an implementation detail of CPython. You rely on that behaviour, your code is broken: * on pypy * on jython * on ironpython That is, it's broken on Python, and it's not correct Python code. It's only correct CPython code.

Why? Wouldn't any garbage collector collect the file object when it goes out of scope?

    def foolish():
        f = open('filename.txt')
Once `foolish` returns, `f` goes out of scope, refcounting or not. Once `f` goes out of scope, its destructor closes the file. In CPython, the destructor is called when the refcount reaches zero. In Pypy, the destructor is called when there are no more references to `f`. Both happen when `foolish` returns, in both Pypy and CPython.

This is an implementation detail of file, not CPython.

Or did I fundamentally misunderstand something here?

Re: Rust means never having to close a socket

#158
post #141

Earlier quoted context omitted.

> It is nonsense to say that "libraries can have bugs so you might as well use C++". My argument is that if you assert 'rust is 100% safe' then you must assert, all your dependencies are bug free. If you can somehow magically assert 'all my code is bug free', that would be great... but if so, you wouldn't need the borrow checker at all would you? (I'm certainly not endorsing using C++ :P I'm specifically talking to t…

> 'rust is magical and can never crash' turns up in blog > posts a lot The next time that you see someone doing this, please correct them. Misinformation does none of us any favors.

I believe that's what started this entire thread.

...there are two things in this article which are, I'd say, 'common misconceptions' about rust.

Re: Rust means never having to close a socket

#159
post #125

Earlier quoted context omitted.

'Unsafe' is a bad term, effect is much better and it is most definitely a rust issue. If the language doesn't have a way of dealing with effects it won't be able to handle them. Rust is honestly a more safe c++ and in my opinion not an alternative for c.

I don't know what this means. I stand by my upstream comment.

Algebraic effects system.

Re: Rust means never having to close a socket

#160

Earlier quoted context omitted.

That's an implementation detail of CPython. You rely on that behaviour, your code is broken: * on pypy * on jython * on ironpython That is, it's broken on Python, and it's not correct Python code. It's only correct CPython code.

Why? Wouldn't any garbage collector collect the file object when it goes out of scope? def foolish(): f = open('filename.txt') Once `foolish` returns, `f` goes out of scope, refcounting or not. Once `f` goes out of scope, its destructor closes the file. In CPython, the destructor is called when the refcount reaches zero. In Pypy, the destructor is called when there are no more references to `f`. Both happen when `foo…

Yes, you misunderstood how tracing garbage collection works. Cleanup of data allocated on the heap occurs during tracing phases, not when a reference goes out of scope. Otherwise, imagine if before it returned f copied the object into some global structure g--how would the garbage collector know it was safe to close?

(Some garbage collected languages can do automated "escape analysis" to figure out whether an object "escapes" the scope, and if it doesn't place it on the stack instead of the heap and deterministically free it when it goes out of scope. But that's surprisingly limited in real world programs and is generally speaking an implementation / optimization detail, not a core guarantee of the language).

Post reply on HN