Hacker News new | ask | show | jobs
by dfranke 2079 days ago
I hope we eventually get Presburger arithmetic support so that one could write

    fn concat<T,M,N>([T; M], [T; N]) -> [T; M+N]
2 comments

The future is here now, for the last ~week or so, on nightly Rust:

    #![feature(const_generics, const_evaluatable_checked)]

    fn append<T: Copy + Default, const N: usize, const M: usize>(
      xs: &[T; N], ys: &[T; M]) -> [T; N + M] {
        let mut result = [T::default(); N + M];
        result[..N].copy_from_slice(&xs[..]);
        result[N..].copy_from_slice(&ys[..]);
        result
    }

    fn main() {
        let arr = append(&[1i32; 3], &[2i32; 4]);
        dbg!(arr);
    }
and also proper units of measurement support while we're at it...
I don't understand what you're asking for here.

I did an experiment with units of measure years ago in Rust: https://github.com/coder543/metric

To me, it felt ergonomic, and it was absolutely compile-time type safe to the extent you would expect. It worked just fine. I know of quite a few other libraries that do the same thing with their own unique approaches, so there are many flavors of this that all work on stable Rust.

If you're asking for something like this to be built into the standard library... that's very unlikely to happen in the foreseeable future.

When working with audio signals, is it possible to transmute a Vec<f32> (or slice/etc.) to a Vec<Amplitude<f32>>? It's a concern I haven't seen addressed the last time I tried working with Rust units.
I would just recommend constructing them as Amplitude values to begin with and avoid the need for a transmute. That Vec isn’t going to materialize out of thin air, and there’s no cost to using one of these zero size wrappers from the beginning.

But, yes, you probably could transmute it... if you really have to.

What if you're interfacing with an audio output library and synthesis library that works with &[f32] and not a dimensioned type?
These scenarios are so hypothetical that it’s pointless to give an answer. What if the library requires you to pass in values in a custom struct they defined? What if the library requires all sorts of arbitrary nonsense?

The reality is that the conversion cost to just `map` one Vec to another is extremely low on anything but maybe a microcontroller —- and even then, maybe not.

If you benchmark things and can’t find a safe way to do things, there are unsafe methods, but I am highly skeptical that they would be needed.

It’s also extremely possible to fork such a library, change a few lines to use the dimensionally correct type, and be done with the issue.

If all of your heavy lifting is being done by this external library anyways, and that library just uses raw floats... why bother with the ceremony of using a dimensionally safe float in your own code if the performance cost of mapping between types is too high?

The real benefit of dimensional safety is when you’re actually doing computations, not some external library you pulled in.

Rust allows for these zero cost wrapper types that will do exactly the correct computations as if they were done with hand written code... but you have to actually have computations that you want to do. The type system intentionally doesn’t want you to treat these typed floats as regular floats. That’s the point.

But there are ways to transmute certain types for no performance penalty, they’re just footguns you should avoid except as an option of last resort.

There are some RFCs that in combination would allow that: https://github.com/rust-lang/rfcs/pull/2756 https://github.com/rust-lang/rfcs/pull/2981
i'm actually asking for something like this to be implemented on a language level, but if the type system is ergonomic enough, then i'd be mostly fine.

most numbers i deal with in my code have units somewhere. mistakes happen. i don't want to choose from multiple unique approaches, i need the ecosystem to standardize on one solution. see also the async task executor problem in other languages.

So tell me if C/C++ or Kotlin do that.
i'd love them do that ergonomically and successfully. it'd certainly add a point for either in my book. that's besides the point, though.