On Mon, 4 Apr 2022 at 14:22, Brian McCall
<brian.patrick.mcc...@gmail.com> wrote:
>
> I think if you look into CGPM standards (they're the grand pooh bahs who 
> decide what SI units are) then you'd find that a lot of these potential 
> collisions have already been encountered and resolved. Under SI, there is no 
> ambiguity regarding K. K means Kelvin and only Kelvin, whereas k means 1000.
>

The trouble is that SI isn't the only set of units out there. And
particularly if you support SI derived units, there will be
innumerable collisions of abbreviations with other systems. Unless
you're going to mandate *in the language* that SI units are the only
ones permitted (and thus anger a fairly large slab of people), the
precise meanings of the abbreviations will have to be handled by
libraries.

> Regarding precision, this is not something that so many scientists and 
> engineers understand as well as computer scientists and engineers. I'd rather 
> see units available for integers as well as floats. I think that as long as a 
> unit is defined, it makes sense to allow integer quantities of them. If they 
> are to built-in types, as I would prefer, then I suppose unfortunately one 
> would not be able to define fractions of these units as new units. But again, 
> most of this work is done with floats anyway, so if units were only available 
> for floats, I would still see this as a big step forward.
>

Oh absolutely they should be available for integers. Unfortunately,
that doesn't always solve the problem. Exactly how far is it from the
sun to Saturn at aphelion? Do you write it as 1357554000000m, which
implies false precision? What about 1.357554e12m ? Well, that's a
float, not an int. (My apologies if the figure is straight-up wrong, I
just pulled that from a quick Google search.) It's pretty much
inevitable that floats are going to show up, and that means that
forcing everything into the same scale system is likely to cause
problems (just like when you're building a 3D graphical world and you
place a light source 1AU away to represent sunlight - you just create
unnecessary FP inaccuracies).

> Related to these questions, there is the question of what to do about mixed 
> systems? Should 2.54 in / 1 cm evaluate to 2.54 in/cm or should it evaluate 
> to 1? I'd much rather it evaluate to 1, but if anyone else has a stronger 
> opinion, I would not let a dispute over such a thing stand in the way of 
> getting units. Regarding 1m / 1mm, though, I have a much stronger opinion. It 
> should be 1000, without any units.
>

I would say that 2.54in/1cm should be equal to 1. Units should
completely cancel out. It's less clear when there's choice of
equivalent units, like "5ft+6in" potentially being "5.5ft" or "66in";
but I would also say that those two quantities should compare equal.
(Which may make their hashes tricky to calculate.)

> There is yet another question related to the interpretation of K as 1000 vs 
> Kelvin. As I said, SI is clear that K means Kelvin, but what about Python 
> users that are not familiar with SI? What about those in the financial 
> industry? To them, K means 1000, and might not even know what Kelvin is. Now, 
> unless adding a suffix K to a number is supported later on, a financial 
> person would have to go pretty far out of their way, or be looking at the 
> wrong code to be confused by something referring to Kelvin. But it would 
> indeed be a mistake to assume that everyone who uses Python wants and can 
> live with SI units, or even that they would be using the same set of units! 
> Which brings me to the next part of ChrisA's reply...
>
> > 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.
> >
>
> As I mentioned above, I am not a purist. I keep a set of Thorlabs thread 
> adapters handy in my lab so that I can screw imperial cage plates onto metric 
> posts.
>
> I think I diverge (or perhaps just don't understand) statement on "semantic 
> meaning". To me, semantic meaning of the units seems pretty essential. 
> Wherever possible, units should be simplified in a prescribed manner. 1W / 1s 
> = 1J, 10km/1cm = 1000000. The meaning of these suffixes should be explicit, 
> not implicit.
>

There are three levels of meaning happening here.

1) Syntax. This is set by the language, must be locked in at
compilation time, and if you get this wrong, you get SyntaxError.
2) Low-level semantics. In my proposal, this is a simple concept of
"look up a registration table, call the appropriate function, and use
what it gives back".
3) High-level semantics. This is where the true meaning of "meter" is
assigned, and in my proposal, that's the job of libraries, not the
language.

To illustrate the difference here, I'll use a different piece of code:

with slider.handler_block(sig):
    slider.set_value(value)

What is the meaning of the "with" statement?

1) "with" thing ":" suite

This is how you parse the line of code. You expect the word "with",
then something that is the context manager, you might capture it in a
name (not happening here), and then there's an indented block of code.
Doesn't tell you anything about what it means, but it tells you how to
spell it out. This is the syntax.

2) Call the __enter__ method of the object, then run the suite, then
call the __exit__ method, even if an exception is raised.

This is low-level semantics. The language doesn't define anything more
than this, but on its own, it doesn't tell you why this is useful.

3) Temporarily block this signal from being sent, long enough to set
the slider's value.

This is high-level semantics - the true meaning of the code, what
makes it actually useful. In this particular case, the meaning comes
from the GTK library, not the language itself. It's entirely possible
for some high-level semantics to come from core language or standard
library features (notably files, and synchronization primitives), but
it's also possible to have a feature with absolutely no useful meaning
in the core language (like matrix multiplication).

In my opinion, the language should be defining the first two levels,
but not the third. Rules like "1W / 1s == 1J" come from high level
semantics, and can be provided by libraries. The language just defines
the hooks by which those libraries can set themselves up.

> > Does this seem like a plausible way to go about it?
>
> As far as registering units, I think registering individual units is a bit 
> much. Of course, several of these statements could be put inside a module or 
> package to make things easier. But I also don't like that it means the syntax 
> of the "literals" needs to be allowed during parsing, and left to the 
> interpreter to figure out if the unit was registered. I do think it is 
> reasonable to require programmers to "opt in" to using SI or other units, and 
> possibly even specify which set or sets of units they intend to use. But if 
> their constants are ill-formed, then that should still be caught during 
> parsing and throw a SyntaxError.
>

This is where I currently disagree, but would be open to seeing an
actual implementation. The trouble is, very very little in a .py file
can change the way that that file is parsed; if something's a
SyntaxError, you generally can't make it legal with code in that file,
only with code somewhere else. (The one exception is __future__
directives, and they should be rare.) That has the unfortunate side
effect that, if you want "25mm" to be legal but "25zm" to be a
SyntaxError, there needs to be something executed before this file
gets imported, which registers those suffixes.

On the other hand, it is entirely reasonable to have "25zm" raise a
runtime exception when that point in the code is reached.

> ```
> measure SI
> length = 12m
> width = 10mm
> area = length * width
> print(area)
> ```
> ... with no SyntaxErrors and a result of "0.12 m2"
>
> After the "measure SI" statement, all literals that are formed with SI units 
> are considered valid syntax and are evaluated accordingly. Prior to "measure 
> SI", only the unitless primitives are allowed. Clearly this works differently 
> than does the `global` or `local` statement, which are modifying a namespace. 
> Also, the choice of keyword matters, because making "measure" a keyword would 
> probably break a lot of existing code (3to4.py!!!). But it is dead simple, 
> and it does behave in a way that is actually quite similar to modifying the 
> existing namespace.
>
> This ended up being a much longer reply than I anticipated, but I hope it 
> helps.
>

Where would "measure SI" be implemented? Does it have to be a core
feature of the language? The global statement (there's no "local"
statement - do you mean "nonlocal"?) is fully defined by the language,
so its impact on the surrounding code is also well defined. But if
"measure" statements can be provided by importable modules, there are
only two options: either it's a run-time action (like most imports),
or it has to be done before you import something else, which requires
a bootstrap script:

# SI_runner.py
import measurements.SI
measurements.SI.register()
import real_code.py

# real_code.py
length = 12m
width = 10mm
print(length * width)

That's annoying. Very annoying. The strictly run-time nature of
Python's import statement does have some consequences, but it's also
extremely easy to work with (trust me, JavaScript module imports are
far more annoying simply because they get executed before the rest of
the code does).

But I would be open to seeing an actual implementation before locking
in an opinion on this.

Well, actually, I'm open to just never locking in an opinion, but you
know what I mean :)

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/MTUR6MHKYAOLMTMG77PS2C5NXNBG75TP/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to