News for hackers. Stuff that matters.

stjepang

Re:Implementing a Type-safe printf in Rust on Saturday August 15, 2020 @05:36AM (#24167480)
Right, there is a way - to escape braces and print "text {value}" rather than the actual value, you'd use "text {{value}}"
Re:Implementing a Type-safe printf in Rust on Friday August 14, 2020 @04:38AM (#24155406)
Hi there, thought I might chime in as someone who used to work on tokio and is now working on async-std and smol. :)

A month ago I wrote a blog post about the evolution of async Rust and its async runtimes. Hopefully this answers your questions!

https://stjepang.github.io/2020/04/03/why-im-building-a-new-...

Re:Why writing a linked list in safe Rust is so damned hard on Friday February 23, 2018 @06:49AM (#16445736)
Why does option #3 look non-ideal, what are your concerns with it?
Re:Why is Rust difficult? on Monday January 22, 2018 @10:25AM (#16205005)
I'd like to read more about those soundness issues - do you have a link?
Re:Announcing Rust 1.23 on Friday January 05, 2018 @06:09AM (#16077907)
Yes, it is. But why 'the worst' aspects of each, though? I see it as the opposite: linked lists built on top of vectors combine good cache efficiency of vectors with algorithmic benefits of linked lists (many operations become O(1), or at least in the amortized sense).

Of course, arenas do have tradeoffs - I'll try to summarize.

Pros:

- Completely safe.

- More ergonomic than dealing with `Rc<RefCell<T>>`.

- Improved cache efficiency of linked data structures.

- Fast node allocation and deallocation.

Cons:

- Any two simultaneous node accesses must be immutable.

- Accessing a node incurs the cost of a bound and liveness check.

- Vector growth can be costly and cause a spike in latency.

- Vector growth moves all nodes in memory.

- Removing a node creates a hole in the vector, possibly wasting memory.

Generally speaking, I think anyone learning Rust and trying to implement a graph data structure should first do it on top of a vector. It's easier than other commonly suggested approaches and it's not a bad one either. In fact, that's how rustc builds some of its data structures, how conrod (a GUI toolkit) represents its widget graph, and how Way Cooler (a window manager) manages window tilings.

Re:Announcing Rust 1.23 on Thursday January 04, 2018 @07:27PM (#16075436)
But... doubly-linked lists and graphs are easy in Rust! :) Here are a few examples.

Doubly-linked list: https://github.com/stjepang/vec-arena/blob/master/examples/l...

Splay tree: https://github.com/stjepang/vec-arena/blob/master/examples/s...

Re:Announcing Rust 1.20 on Thursday August 31, 2017 @06:20PM (#15144458)
It's fairly easy to do this kind of thing using an arena and indices instead of pointers. Here's a simple splay tree with uplinks implemented this way:

https://github.com/stjepang/vec-arena/blob/master/examples/s...

Re:Pattern-defeating quicksort on Thursday June 29, 2017 @06:40PM (#14667433)
Absolutely - there are cases when branch misprediction is not the bottleneck. It depends on a lot of factors.

Another such case is when sorting strings because every comparison causes a potential cache miss and introduces even more branching, and all that would dwarf that one misprediction.

Re:Pattern-defeating quicksort on Thursday June 29, 2017 @04:58PM (#14666821)
To summarize:

If comparison is cheap (e.g. when sorting integers), pdqsort wins because it copies less data around and the instructions are less data-dependency-heavy.

If comparison is expensive (e.g. when sorting strings), timsort is usually a tiny bit faster (around 5% or less) because it performs a slightly smaller total number of comparisons.

Re:Channels in Golang on Sunday December 25, 2016 @11:49AM (#13254635)
There is a chapter in Rustonomicon on subtyping and variance: https://doc.rust-lang.org/nomicon/subtyping.html
Re:Rust gets a faster sort implementation on Wednesday December 14, 2016 @12:26PM (#13177750)
Author here. Yes, this is an interesting problem TimSort used to have. A counterexample to incorrect TimSort is sequence "120, 80, 25, 20, 30". This simple sequence could have been easily discovered by generating sequences randomly and verifying that the TimSort invariants hold on it. The fact that it took 13 years to discover the bug (using formal verification!) is just silly :)

Fortunately, the problem is easy to fix and there's a brief mention of it in the comments: https://is.gd/txKd4I

Re:Rust: 128 bit integers preparing to be released on Sunday December 04, 2016 @06:50AM (#13099689)
To transfer ownership, you would wrap the object in Mutex<T>, send it via Sender<T>, use some other synchronization primitive, or simply pass it over at the moment the thread is spawned.

It's up to the synchronization primitives to ensure memory barriers are executed, not the language. So e.g. a Mutex<T> would execute a memory barrier when locking and unlocking. Rust then allows you to pass ownership in a trusted manner only, i.e. through those primitives.

Of course, you can also create an unsafe block and say: "Rust, trust me, I know what I'm doing, don't bother me, and these are the invariants I want you to enforce in safe code..." Mutexes are implemented this way.

Re:Announcing Rust 1.13 on Friday November 11, 2016 @05:15AM (#12929386)
Yes, there is a simpler approach.

If your function returns Result<T, Box<Error>>, then you can use try! or ? operator to return any kind of error. It will be automatically boxed and converted into the generic Box<Error>.

This works for two reasons:

1) try! and ? don't simply return Err(err) on error case as one might think. They actually return Err(From::from(err)).

2) The standard library has: impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> { ... }

Check out this article, starting from "The From trait": http://blog.burntsushi.net/rust-error-handling/

Re:Swift 3.0 Unsafe World on Tuesday September 27, 2016 @10:30AM (#12589819)
Chris Lattner on the advantages of reference counting over tracing garbage collection: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mo...