Recent submissions

Comment · 5 years ago
Comment · 5 years ago
An important one is missing from this overview: using a const. This is sometimes useful, because it does not require the type to be Copy; only that the value is a constant:

    const EMPTY: String = String::new();
    let a: [String; 1000] = [EMPTY; 1000];

    const NONE: Option<String> = None;
    let b: [Option<String>; 1000] = [NONE; 1000];

    const SEVEN: AtomicU32 = AtomicU32::new(7);
    let c: [AtomicU32; 200] = [SEVEN; 200];
Comment · 5 years ago
Comment · 5 years ago
`T: 'a` means that you may keep values of type T around for lifetime 'a, but not that they will. So `T: 'static` means that you may keep values of that type around forever, as they do not refer to anything that doesn't live forever.

So neither `&'a i32` nor `MutexGuard<'a, i32>` are 'static (unless 'a is), because you shouldn't keep references like that around longer than the stuff it points to. But i32 by itself satisfies i32: 'static, because it's perfectly fine to keep an i32 around forever. (But that doesn't mean that every i32 will stick around forever.)

Comment · 6 years ago
Good point! Updated.
Comment · 6 years ago
Thanks! Updated.
Comment · 6 years ago
Comment · 7 years ago
Comment · 7 years ago
It uses the same Python interpreter, but each macro invocation is considered its own module. A later version of the crate will have the possibility to keep the context around to be re-used by a later invocation such that, for example, you don't need to import things again.
Comment · 7 years ago
In Python, all data (even simple integers) are all allocated on the heap. ToPyObject makes a deep copy of everything, converting everything to `PyObject` on the heap, so all data is owned.

The numpy crate helps if you need to convert large arrays to Python, as numpy does not store every element separately on the heap.

Comment · 7 years ago
Comment · 7 years ago
At work, we make high performant drone control systems in Rust. But for testing and debugging, we simply use Matplotlib (a Python library) to make plots of simulations, etc. So we prefer Rust for the control systems themselves for the speed and reliability, but for plotting results of simulations, we don't care much about performance and rather just use something with all the features we need.
Comment · 7 years ago
Author here. Let me know if you have any questions. :)
Comment · 7 years ago
Yes, this was our main worry as well. At first we switched to Rust only for the lower level code, the parts that interfaces with sensors and the motors, that do the data logging, our inter process communication library, etc. The part with the control algorithms (where all the interesting linear algebra code is) was still in C++ until recently.

For all the small vectors and matrices, things like Vector3 and Matrix3x3 from nalgebra work fine. A few generic things we had to change from statically sized to dynamically sized arrays/matrices, but since these were rather big already, the difference in performance was neglegible. The type safety was maintained by directly wrapping those in a generic struct where the template parameter describes the contents of the matrix or vector. Such template parameter is basically a struct where the members describe the meaning of all the columns/rows of the related vector/matrix. A custom derive proc macro generated the conversions to and from this type (which are all optimized away by the compiler). It looks something like this:

    struct Foo<T: VectorLike> {
        matrix: DynanamicallyAllocatedMatrix<f64>,
    }

    impl<T: VectorLike> Foo<T> {
        fn new() {
            Foo { matrix: DynanamicallyAllocatedMatrix::zeros(T::N, T::N) }
        }
        fn get_diagonal(&self) -> T { ... }
        ...
    }
We were already doing something like this in C++, but with some hacky preprocessor macros instead of Rust's procedural macros.

In the end, keeping track of the meaning of the entire vector/matrix in the type system provides us with even a lot more safety than only keeping the size of them in the type system. And it has the advantage that you don't need const generics, since you're keeping track of whole types, and not just numbers. The downside is that we have to maintain a few procedural macro implementations.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton