sharkdp / numbat

A statically typed programming language for scientific computations with first class support for physical dimensions and units
https://numbat.dev
Apache License 2.0
1.11k stars 44 forks source link

1000 - 20% #494

Open andylima opened 1 month ago

andylima commented 1 month ago

Can percentage expressions that work in calculators like Raycast and Numi, such as 1000 - 20% work in Numbat?

...That would be great. 😃 This is a really common use case.

triallax commented 1 month ago

that evaluates just fine in numbat, but not in the way you're probably expecting

% in numbat is basically just 1/100, so 1000 - 20% is equivalent to 1000 - 20/100 which comes out to 999.8

i presume what you're thinking of would be more like this:

>>> 1000 * (1 - 20%)

  1000 × (1 - 20 percent)

    = 800
andylima commented 1 month ago

I see. Thank you for explaining how such a calculation can be done with numbat.

sharkdp commented 1 month ago

Related discussions (in the predecessor project of Numbat):

It might be worth re-evaluating this. For one, in Numbat, we do not use % for modulo anymore. We currently use it as an alias for the percent unit that is simply defined as 0.01, as @triallax mentioned. I'm still not sold on having special syntax support for % though, but if someone can come up with a good proposal on how this could work, we can certainly discuss it. What I really don't want is a configuration option for this. That's something that Qalculate does:

image

Of course you can argue that this makes everyone happy. But I don't like the user experience. And adding configuration options always increases complexity of a software product and makes it harder to test.

One thing we can definitely support is custom functions (and maybe even special syntax?) for those percentage computations. Something like:

fn add_percentage<D: Dim>(value: D, percentage: Scalar) = value * (1 + percentage)
fn sub_percentage<D: Dim>(value: D, percentage: Scalar) = add_percentage(value, -percentage)

which you can use like this: image

In fact, you could add those two functions to your init.nbt file and use them today.

But of course, this approach suffers from a discoverability problem. How are users going to know about this feature?

Edit: Well, thinking about this a bit more. We could partially solve that discoverability problem by emitting a useful error message if someone attempts to do something like a + 20% where a is not a dimensionless quantity. Because we would show a type error anyway. We could as well add something like: "if you attempted to add 20% of …, use 'add_percentage(…, 20%)".

andylima commented 1 month ago

@sharkdp Those two functions would be a good addition. I agree with almost everything on your post... Except that I think special syntax for those functions makes sense. What about the syntax below? 1000 -% 20 1000 +% 20

These kind of calculations are common enough that, again, calculators such as Raycast, Numi and Soulver have special support for them in the form that I described in the first post.