On Mon, 4 Apr 2022 at 04:53, Brian McCall <brian.patrick.mcc...@gmail.com> wrote: > If you had asked me twenty years ago if I thought units should be a native > part of any programming language, I would have said absolutely - because in > my youthful ignorance I had no idea what it would take to make such a thing > work. Five years later, I would have said "not worth it". Now I'm back where > I started. The lack of native language support for SI units is a problem for > an entire segment of programmers. Programming languages took a big step > forward in deciding that EVERYTHING is a pointer/reference, and EVERYTHING is > an object. They need to take another step forward to say that EVERY number > has a unit, including "unitless". Not having this language feature is > becoming (or already is) a problem. The question is, is it Python's problem? >
Part of the problem here is that Python has to be many many things. Which set of units is appropriate? For instance, in a lot of contexts, it's fine to simply attach K to the end of something to mean "a thousand", while still keeping it unitless; but in other contexts, 273K clearly is a unit of temperature. (Although I think the solution there is to hard-disallow prefixes without units, as otherwise there'd be all manner of collisions.) Is it valid to refer to fifteen Angstroms as 15A, or do you have to say 15Å, or 15e-10m and accept that it's now a float not an int? Similarly, what if you want to write a Python script that works in natural units - the Planck length, mass, time, and temperature? Purity and practicality are at odds here. Practicality says that you should be able to have "miles" as a unit, purity says that the only valid units are pure SI fundamentals and everything else is transformed into those. Leaving it to libraries would allow different Python programs to make different choices. But I would very much like to see a measure of language support for "number with alphabetic tag", without giving it any semantic meaning whatsoever. Python currently has precisely one such tag, and one conflicting piece of syntax: "10j" means "complex(imag=10)", and "10e1" means "100.0". (They can of course be combined, 10e1j does indeed mean 100*sqrt(-1).) This is what could be expanded. C++ does things differently, since it can actually compile things in, and declarations earlier in the file can redefine how later parts of the file get parsed. In Python, I think it'd make sense to syntactically accept *any* suffix, and then have a run-time translation table that can have anything registered; if you use a suffix that isn't registered, it's a run-time error. Something like this: import sys # sys.register_numeric_suffix("j", lambda n: complex(imag=n)) sys.register_numeric_suffix("m", lambda n: unit(n, "meter")) sys.register_numeric_suffix("mol", lambda n: unit(n, "mole")) (For backward compatibility, the "j" suffix probably still has to be handled at compilation time, which would mean you can't actually do that first one.) Using it would look something like this: def spread(): """Calculate the thickness of avocado when spread on a single slice of bread""" qty = 1.5mol area = 200mm * 200mm return qty / area Unfortunately, these would no longer be "literals" in the same way that imaginary numbers are, but let's call them "unit displays". To evaluate a unit display, you take the literal (1.5) and the unit (stored as a string, "mol"), and do a lookup into the core table (CPython would probably have an opcode for this, rather than doing it with a method that could be overridden, but it would basically be "sys.lookup_unit(1.5, 'mol')" or something). Whatever it gives back is the object you use. Does this seem like a plausible way to go about it? ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/XAAHFOWRED2TK4XZCXHEKCQIE4KMI7SJ/ Code of Conduct: http://python.org/psf/codeofconduct/