Live data from Hacker News

Show HN: Numbat – A programming language with physical dimensions as types

numbat.dev

81–90 of 122 posts

Re: Show HN: Numbat – A programming language with physical dimensions as types

#81

Earlier quoted context omitted.

> I feel like that’s unit confusion. Converting from year to day should require you to specify what calendar year you’re in to resolve the ambiguity. A year has two meanings - a calendar year, with all the leap days and seconds and timezones, or a duration of time. The latter is still useful, e.g. when someone states that Proxima Centauri is 4.2 light-years away, they don't want to deal with leap-days. Decent time li…

Except there is also https://en.m.wikipedia.org/wiki/Sidereal_year So I would say they need explicit different years.

So 'year' refers to the Gregorian year and is equal to 365.243 days [1]. We also have 'julian_year' which is equal to '365.25 days'.

We also have 'sidereal_day' equal to '23.9345 hours', and if you believe it is useful, we can also add 'sidereal_years'.

[1] https://numbat.dev/doc/list-units.html

Re: Show HN: Numbat – A programming language with physical dimensions as types

#82
post #77
post #25

Or you could just use Nim [0], where this sort of thing can be implemented in Nim's macro system. Then you have a regular programming language combined with CT safe units. :) It even pretty much looks identical to those Numbat snippets! import unchained let earth_mass = 5.972168e24.kg let solar_mass = 1.9885e30.kg let lunar_mass = 7.342e22.kg let distance_sun = 1.AU # astronomical unit let distance_moon = 384_400.km…

Thank you for the reference. I hadn't seen Unchained. You missed the point about this example though. I wanted to show how Numbat can help prevent the exact error that you made in your program. 'G_Newton * earth_mass * solar_mass / distance_sun' is not a force. It's an energy. How would you write type annotations in this Nim example to help you find that same mistake?

Whoops, guilty as charged. I did indeed glance over that (both the text and the equation not actually being 1/r²).

In this case to get compiler help it's pretty much identical to Numbat. Annotating the "force" variables with a `Force` type. There's a few technicalities involved though. Normally the user is supposed to use explicit type annotations for variables. Quantities like `Force`, `Energy` etc. are mainly supported for function arguments (they are "concepts" in Nim lingo, a specific version of generics).

Technically you can abuse these concepts for type checking, by annotating with `Force`, e.g. `let force_sun: Force = ...`. That will correctly raise a CT error about mismatching units in this case. However, the code will /also/ not compile if you type `Energy` due to the underspecified type.

So what you're supposed to do is:

    import unchained
    
    let earth_mass = 5.972168e24.kg
    let solar_mass = 1.9885e30.kg
    let lunar_mass = 7.342e22.kg
    
    let distance_sun = 1.AU  # astronomical unit
    let distance_moon = 384_400.km
    
    let force_sun: N = G_Newton * earth_mass * solar_mass / distance_sun
    let force_moon: N = G_Newton * earth_mass * lunar_mass / distance_moon
    
    echo force_sun / force_moon
which will correctly raise a

    Error: type mismatch: got 'Joule' for '...' but expected 'Newton = Alias'

(or any other unit of force; note that if it was a non SI unit, e.g. `eV` for an energy, you'd need to explicitly convert the RHS expression into `eV` using `.to(eV)`. That will perform the CT check of whether the conversion is valid, and if so, hands you the value in `eV`. Implicit conversions to explicitly given types is not supported)

So I think we more or less do the same things. :)

And just to clarify, I'm always happy to see more libraries / programs etc. that do units as types. But for the same reason you hadn't even heard about Unchained, is the reason I can't stop myself from mentioning it in such a context. :D (niche programming language + niche topic clearly doesn't help).

Re: Show HN: Numbat – A programming language with physical dimensions as types

#83
post #50
post #25

Or you could just use Nim [0], where this sort of thing can be implemented in Nim's macro system. Then you have a regular programming language combined with CT safe units. :) It even pretty much looks identical to those Numbat snippets! import unchained let earth_mass = 5.972168e24.kg let solar_mass = 1.9885e30.kg let lunar_mass = 7.342e22.kg let distance_sun = 1.AU # astronomical unit let distance_moon = 384_400.km…

'can be implemented' is different from 'has been implemented' how does unchained handle gaussian elimination

Gaussian elimination in what context even? If your LA library supports generic types, it might work. But generally generic math operations are tricky to get right, because math often does things that from a pure physical perspective don't make a whole lot of sense / you run into trouble with too many competing types due to temporary multiplication / divisions etc (which is a big issue in any statically typed language, because your container (vector, matrix, tensor whatever) type is typically a single unit type!

Re: Show HN: Numbat – A programming language with physical dimensions as types

#84
post #83
post #50

Earlier quoted context omitted.

'can be implemented' is different from 'has been implemented' how does unchained handle gaussian elimination

Gaussian elimination in what context even? If your LA library supports generic types, it might work. But generally generic math operations are tricky to get right, because math often does things that from a pure physical perspective don't make a whole lot of sense / you run into trouble with too many competing types due to temporary multiplication / divisions etc (which is a big issue in any statically typed language…

most linear algebra requires vectors of multiple unit types. think of runge-kutta for a second-order system, for example, or just about any multivariate system. see https://yosefk.com/blog/can-your-static-type-system-handle-l... for more information

if your static type system can't handle that, it can't handle unit types for basic linear algebra subroutines

Re: Show HN: Numbat – A programming language with physical dimensions as types

#85
post #64
post #49

the classic problem for such number systems is linear algebra https://yosefk.com/blog/can-your-static-type-system-handle-l... the issue is that each column and each row of a matrix can have different units. worse, gauss-jordan elimination chooses which rows to operate on dynamically. there is eventually a solution to this problem in c++ far down the comments thread i don't see anything in https://numbat.dev/doc/type-…

No, we do not have aggregate types in Numbat yet. But it is definitely something I would like to support. Note that it is possible to construct a type system solution to this problem (vectors/matrices with non-uniform units). A colleague of mine has an excellent talk on this: https://www.youtube.com/watch?v=SLSTS-EvOx4 By 'Scalar', in the document you referenced, we mean a dimensionless quantity. Not a scalar in the…

thanks, i'll take a look

i know it's possible (even in c++ apparently) but so far it seems difficult

Re: Show HN: Numbat – A programming language with physical dimensions as types

#86
post #72
post #49

the classic problem for such number systems is linear algebra https://yosefk.com/blog/can-your-static-type-system-handle-l... the issue is that each column and each row of a matrix can have different units. worse, gauss-jordan elimination chooses which rows to operate on dynamically. there is eventually a solution to this problem in c++ far down the comments thread i don't see anything in https://numbat.dev/doc/type-…

Interesting article... though to be honest, I'm not sure I buy the premise. In the article, he states: "Let's call the matrix of all (xi 1) `X` and let's call the vector of all yi `Y`", and then states that the units of `X` are (m 1). But if you instead say the units of `X` are just m, the "1" is in units "m", then the problem goes away, the whole matrix has the same units ("m"), and everything works fine. I'll be ho…

i hadn't thought of it either before auditing an introductory numerical methods class, but in retrospect the page i linked does explain this, repeatedly, in the comments; i just didn't understand it at the time

basically it's very very common

Re: Show HN: Numbat – A programming language with physical dimensions as types

#87
post #71

Earlier quoted context omitted.

It'll fetch current conversation rates from the internet

Yes. We use up-to-date currency exchange rates from the European Central Bank [1]. https://github.com/sharkdp/numbat/blob/786512175b99c195a7d5b...

That's one of these things where you can spend quite some effort to get that right but it's not going to be useful for anything deeper. That's like saying "here, we have implemented Newton's mechanics in fundamental types, now you can in theory simulate a body up from its atoms!" and while that would sound compelling if you don't know much about physics, it would quickly become useless once you know more about physics.

Re: Show HN: Numbat – A programming language with physical dimensions as types

#88
post #79

Frink ( https://frinklang.org/ ) is an older language with similar design goals. Frink runs on the JVM and is also available on Android. I use it as a general purpose calculator on my smartphone. It's really nice that Numbat is written in Rust :) Will have to try it out.

Frink is not open source, unfortunately.

>> Frink is not open source, unfortunately.

True: https://frinklang.org/faq.html#OpenSource

Thanks for sharing Numbat with us.

It looks great!

Re: Show HN: Numbat – A programming language with physical dimensions as types

#89

How does something like `let y: Time = 1 year` work? Does it take into consideration the idea of leap years and leap seconds, counting a single year as 365.2422 days[0]? Or does it count as 365 days? I got curious and installed the CLI tool[1] and found that it does indeed account for leap second / leap years: >>> let jahr: Time = 1 year >>> let tage: Time = jahr -> days >>> tage = 365.243 day [Time] References: 0: h…

365·243 ought to be 365·2425 exactly:

Per 400 years, there is one leap day every 4 years (100 leap days), except when the year is divisible by 100 (so we overcounted by 4 and there are 100 – 4 = 96 leap days), except when the year is divisible by 400 (so we need to add that day back and arrive at 100 – 4 + 1 = 97). This gives us 97/400 = 0·2425.

The tropical year is about 365·24219 days long, but that's not relevant to timekeeping.

Re: Show HN: Numbat – A programming language with physical dimensions as types

#90
post #81

Earlier quoted context omitted.

Except there is also https://en.m.wikipedia.org/wiki/Sidereal_year So I would say they need explicit different years.

So 'year' refers to the Gregorian year and is equal to 365.243 days [1]. We also have 'julian_year' which is equal to '365.25 days'. We also have 'sidereal_day' equal to '23.9345 hours', and if you believe it is useful, we can also add 'sidereal_years'. [1] https://numbat.dev/doc/list-units.html

Do you have a calendar_year and a calendar_leap_year?
Post reply on HN