Git Product home page Git Product logo

Comments (11)

paholg avatar paholg commented on May 24, 2024

The easiest way to do this is to accept something that can convert into Kelvin.

You will also need to call value() (part of trait Dimensionless) to get the underlying f64 value once you have a unitless quantity:

Example:

use dimensioned::{si, Dimensionless};

impl TemperatureDependence for MyStruct {
  fn apply<T>(&self, n: Vector3<f64>, temperature: T) -> Vector<f64> 
  where T: Into<si::Kelvin<f64>> {
    // --snip--
    let f: f64 = *((temperature.into() - 20.0 * si::K) / si::K).value();
    // --snip--
    // returns a vector based on this
  }
}

If you really want to accept anything that is a Temperature without conversion, to which you'll add a constant, you'll probably end up having to do some hacks with the One trait in num or something like it, and it is likely to be a lot more work than it's worth.

from dimensioned.

wellcaffeinated avatar wellcaffeinated commented on May 24, 2024

That's fantastic! Thanks. Everything makes sense to me except for dereferencing that computation.

Presumably those brackets return a reference... but i'm not sure why. And doesn't calling a method on a reference automatically dereference it?

from dimensioned.

paho-outreach avatar paho-outreach commented on May 24, 2024

value() returns a reference. It should probably return a value, but it's too late to change without breaking changes.

from dimensioned.

wellcaffeinated avatar wellcaffeinated commented on May 24, 2024

Ohhh I see. I got the order of operations mixed up.

But now that I think about it, if I implement the function with this trait requirement and try to write another function that uses this one, won't that requirement ascend up the chain? Do I have to constantly worry about T: Into<si::Kelvin<f64>>?

eg:

fn otherFn<Q, T>( &tempDep: Q, n: Vector3<f64>, temp: T) -> Vector3<f64>
where 
  Q: TemperatureDependence,
  T: Into<si::Kelvin<f64>> // do I need to worry about this every time I use a temperature now?
{
   tempPep.apply(n, temp)
}

from dimensioned.

adeschamps avatar adeschamps commented on May 24, 2024

value() returns a reference. It should probably return a value, but it's too late to change without breaking changes.

For what it's worth, I would be happy to see see this change, and update my own code to deal with it. Overall, it would simplify things.

from dimensioned.

paholg avatar paholg commented on May 24, 2024

But now that I think about it, if I implement the function with this trait requirement and try to write another function that uses this one, won't that requirement ascend up the chain? Do I have to constantly worry about T: Into<si::Kelvin<f64>>?

Yeah, that's how generics in Rust work. Alternatively, those functions "up the chain" could accept any concrete type that implements that trait, such as taking si::Kelvin<f64> directly.

For what it's worth, I would be happy to see see this change, and update my own code to deal with it. Overall, it would simplify things.

I have a few breaking changes in mind that I'd like to save until I can replace typenum with const generics. This is one of them.

from dimensioned.

wellcaffeinated avatar wellcaffeinated commented on May 24, 2024

Oh that's too bad. I was hoping this library would implement something more along the lines of this:
https://ferrisellis.com/content/rust-implementing-units-for-types/

This strategy allows for accepting a Length in any units without declaring the input units.

fn circumference<T>(r: Length<T>) -> Length<T> where T: LengthUnit {
    2 * r * std::f64::consts::PI
}
fn main() {
    let l1 = millimeters!(10);
    let l2 = meters!(5);
    let l3 = (5 * l1) + l2;
    let l3_meters = f64::from(meters!(l3));
    let c1 = circumference(l1);

    println!("l1 = {}", l1);
    println!("l2 = {}", l2);
    println!("l3 = (5 * l1) + l2 = {}", l3);
    println!("l3_meters = {}", l3_meters);
    println!("circumference(radius = {}) = {}", l1, c1);
    println!("l3 > l2 : {}", l3 > l2);
    println!("l3 / l2 = {}", l3 / l2);
}

from dimensioned.

paholg avatar paholg commented on May 24, 2024

This strategy allows for accepting a Length in any units without declaring the input units.

It allows the appearance of accepting a Length in any units. In reality, lengths are only represented as nanometers. If you need to operate with greater than nanometer precision, or at astronomical distances, that type is useless.

Dimenionsed takes an alternate approach, letting you represent values in any units you wish, with the precision you wish, with the trade-off of additional boilerplate for generic functions.

You could achieve something similar in Dimensioned by, for example, just using si, and converting on output.

from dimensioned.

wellcaffeinated avatar wellcaffeinated commented on May 24, 2024

Ok i guess I'm trying to write my code to generally and I should just be using Kelvin

from dimensioned.

paholg avatar paholg commented on May 24, 2024

Here's what that example might look like in dimensioned:

use dimensioned::{si, f64prefixes::*};

fn circumference(r: si::Meter<f64>) -> si::Meter<f64> {
    2.0 * r * std::f64::consts::PI
}

fn main() {
    let l1 = 10.0 * MILLI * si::M;
    let l2 = 5.0 * si::M;
    let l3 = (5.0 * l1) + l2;
    let l3_meters = l3.value_unsafe;
    let c1 = circumference(l1);

    println!("l1 = {}", l1);
    println!("l2 = {}", l2);
    println!("l3 = (5 * l1) + l2 = {}", l3);
    println!("l3_meters = {}", l3_meters);
    println!("circumference(radius = {}) = {}", l1, c1);
    println!("l3 > l2 : {}", l3 > l2);
    println!("l3 / l2 = {}", l3 / l2);
}

The difference here is that all prints will be in meters, it would be up to you to output in a different unit if desired.

from dimensioned.

wellcaffeinated avatar wellcaffeinated commented on May 24, 2024

ok thanks!

from dimensioned.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.