lcn2 / calc

C-style arbitrary precision calculator
http://www.isthe.com/chongo/tech/comp/calc/index.html
Other
338 stars 52 forks source link

Add F# style units of measure #152

Open pmetzger opened 2 months ago

pmetzger commented 2 months ago

This is an idea that has batted about here a bit; I'm writing this down to memorialize some thinking on its own. I don't expect this could actually be done in time for Calc 3.0 (but who knows.)

As we all know, it's all to easy to make mistakes while programming or doing calculations. One way we avoid this during programming is with type systems which catch certain sorts of common errors. Unfortunately, ordinary type systems don't always capture as many of the mistakes we might make as we might want. For example, normal type systems don't always capture dimensions or units of measure, which has had devastating consequences in the real world sometimes.

As it happens the F# language introduced units of measure into its type system some time ago. This means that it is literally impossible to accidentally add inches to seconds in F# if you've used the type system right. It might be interesting to incorporate parts of the F# units system into Calc.

We could imagine a hypothetical future version of Calc in which we can tag values with units. I suspect the syntax below won't work for parsing reasons — the use of <> etc. would probably drive the parser crazy — but let's go with it for the moment for imaginative purposes and we could contemplate syntax (who knows, maybe braces?) that didn't break everything later. For purposes of thinking we might say:

; c=3e8<m/s>
; t=500<s>
; c*t
         150000000000<m>

We might allow ourselves the ability to tag the type we expect a calculation to have so that we'll get an error if it's the wrong type, define derived types (informing the system that <J> = <kg*m^2/s^2>) and even tagging the types of a function's parameters and returns with units so that if (say) we pass 5<1/mol> to something expecting <mol> it gets upset.

A small library could contain the normal Si units and their derived units, as well as conversion functions and the like.

lcn2 commented 1 month ago

Hello @pmetzger,

Interesting idea for calc v3.

Ignoring the "<>" parser issues, and as you say, "but let's go with it for the moment for imaginative purposes":

How would you propose doing the algebraic operations on the units as your example above shows?

We know that is one time DBell contemplated adding basic algebra to calc but that never really was ever completed.

Would you care to write code, @pmetzger, that could perform such algebraic operations on the units?

We might wish to consider adding "UNIT" as a type and adding:

        UNIT *vv_unit;        /* 18: algebraic unit set */

..

#define v_unit vv_unit

..

#define V_UNIT 18      /* algebraic unit set */

Perhaps calc numeric values could have a "UNIT" property that would default to "just a number / no units" property?

Then the fundamental operators would need to separately operate on the "UNIT" property and carry that along, or raise and exception as you suggested in the "UNIT" property did not match.

One would need to work how to scan and print calc values that had a "UNIT" property that wasn't "just a number / no units",etc.

A reasonable syntax for entering "UNIT"'s would need to fit into the parser: something that was backwards compatible with existing calc syntax. Any ideas?

Comments welcome.

pmetzger commented 1 month ago

I'd have to re-read the papers about F# units of measure work first I think. Before planning code, one needs to have a clear idea of what it will achieve. I don't think targeting it for 3.0 is a good idea; larding too many objectives onto one release means it puts off that release forever. (See Perl 6.)

lcn2 commented 1 month ago

I'd have to re-read the papers about F# units of measure work first I think. Before planning code, one needs to have a clear idea of what it will achieve. I don't think targeting it for 3.0 is a good idea; larding too many objectives onto one release means it puts off that release forever. (See Perl 6.)

Your point is very well taken (Perl 6), @pmetzger

At some point in the calc v3 project we will have to call a halt to new concepts and push things off into a calc v4 environment 🤓

UPDATE 0a

Now is the time for calc v3 dreams to be vocalized. As coding becomes a reality and enhancement projects start up, what will be done in calc v3, what will be pushed off to calc v4, and what will be dropped will become more apparent.

P.s., There are no plans for a Perl 6 calc plugin. Although Perl 6 might be ready for calc v4 development: maybe, if they hurry 🤓