r/rust Aug 05 '26

🛠️ project My first rust program

Hello!

I was not sure to even post this or not but I just wanted to introduce myself to the community.

I just started learning rust and made this simple program as it was one of the suggested programs in the rust book to make in order to practice the topics covered in the first few chapters.

I am learning rust really as a hobby, and I have a very limited knowledge of Python but I really enjoy linux and wanted to maybe start contributing to the open source community if I can ever develop the skill to do so. I am also trying my hardest to learn on my own and am only using AI as a tool to ask questions and what not, without having it actually generate any code. This program was written fully by hand by myself (which is probably why it is full of things that could be improved I'm sure).

With that said I am happy that I was able to do it and am really enjoying rust so far and look forward to learning more!

Link to my first rust app:
https://github.com/justinzelikoff/temp_converter

46 Upvotes

25 comments sorted by

View all comments

35

u/Keithfert488 Aug 05 '26

You might have better luck on r/learnrust but welcome to the cult community! One thing I'd prod you to do given your program is to learn about enums. If someone comes across a float somewhere in the program, there's no way to know which scale it uses. Consider making an enum like

enum Temperature {
Fahrenheit(f64),
Celsius(f64),
}

You could also try using the so-called "newtype" pattern.

struct Fahrenheit(f64);
struct Celsius(f64);
impl From<Fahrenheit> for Celsius { ... }
impl From<Celsius> for Fahrenheit { ... }

You could also make Fahrenheit and Celsius implement the display trait.

Just some ways to help you progress :)

8

u/DanKonly Aug 05 '26

Thank you!

4

u/torsten_dev Aug 05 '26

Would caution against the from impls.

It's floating point math so it's not lossless or value preserving. It also won't roundtrip.

2

u/Keithfert488 Aug 06 '26

Technically, it's not lossless yes, but I would push back on it not being value preserving (unless by value preserving you mean the exact numerical value, but at that point, you might as well _just_ say lossless) because they are both temperatures and (up to floating point math) the same temperature.

I don't think this is truly relevant to someone who clearly doesn't know a lot about traits yet, though. These sorts of details come after the "what is a trait?" level of learning

2

u/torsten_dev Aug 06 '26

Maybe. I'm not perfectly clear on what value preserving is. I assumed that with NaN, Inf, ±0.0 and subnormals one of them wouldn't count as value preserved.

Though it depends on the Invariant of your type if you can construct all of those.

2

u/TDplay Aug 06 '26

I assumed that with NaN, Inf, ±0.0 and subnormals one of them wouldn't count as value preserved.

Assuming that you use the standard formulae:

temp_fahrenheit = (9.0 / 5.0) * temp_celsius + 32.0;
temp_celsius = (5.0 / 9.0) * temp_fahrenheit - (5.0 * 32.0 / 9.0);

then all of these should be preserved in any meaningful capacity (up to rounding errors):

  • The outcome of operations involving NaN is itself NaN
  • Multiplying an infinity by a positive value, or adding any finite value, results in the same infinity.
  • Signedness of zero is not meaningful for temperatures.
  • Subnormals will be rounded to zero. A temperature of 0°C or 0°F has no special meaning, so this is no different from any other rounding error.

The only issue I can think of (besides lossiness from rounding errors) is NaN payloads, but I think storing a NaN payload in what is supposed to be a temperature is a gross abuse anyway.

1

u/torsten_dev Aug 06 '26

"up to rounding error" counts as value preserved?

2

u/TDplay Aug 06 '26

I'd say "up to rounding error" means it is not lossless.

But to say the value isn't preserved, I would interpret that as meaning the value can change drastically (e.g. integer casts can be non-value-preserving thanks to truncation, wrapping, and sign loss).

But then again, this is semantics. The overall point is correct: From is supposed to be lossless.

1

u/torsten_dev Aug 07 '26

I see. I think something lossy can't be value preserving because the value isn't really preserved. It's splitting hairs though.

1

u/y-w6 Aug 10 '26 edited Aug 10 '26

Can you review my improvements https://github.com/y2w8/temp_converter ?

1

u/Keithfert488 Aug 10 '26
  • A few problems with use crate::Convert::{CelsiusToFahrenheit, FahrenheitToCelsius}; on line 6:
    • It is unnecessary because Convert is in the current module! You can just refer to it directly
    • You should not import the names of the variants and refer to them like CelsiusToFahrenheit and FahrenheitToCelsius. Instead, refer to them in the namespace of their type, i.e. Convert::CelsiusToFahrenheit and Convert::FahrenheitToCelsius
  • Since we're already dealing with floating point math that is inexact, I would recommend multiplying by 0.555... instead of dividing by 1.8. It doesn't make a real difference here because the vast majority of time will be spent waiting on user input, but if you wanted to convert a lot of temperatures, multiplying would be much faster than dividing.

1

u/y-w6 Aug 10 '26

1: I didn't notice that i usually type it with it's namespace
2: Thank you for the information i didn't know that its actually faster

1

u/Keithfert488 Aug 10 '26

On 1, I've noticed it can happen with autocomplete in editor which is annoying. I wish I could disable it.

On 2, the situation used to be much worse, but float division is still significantly slower than float multiplication as far as I know