Steven D'Aprano writes:

 > There are many things which are core to science and engineering but 
 > aren't part of the core Python language. What makes units of 
 > measurements more special than, say, numpy arrays or dataframes?

Arrays and dataframes are data structures, hidden behind the syntax.
They can be conveniently referenced and manipulated with functions
invoked via existing syntax.  This existing syntax is familiar to us
from many decades of programming language practice, and we have always
accepted it because of the constraint of 1-dimensional computer text.
Much of it is extensions of centuries of mathematical practice, from
operator symbols to function call notation, to these modern data
structures.  And that's one thing I love about Python, the ability to
use familiar syntax in analogous ways.

Applying this line of thought to units, the practice for centuries (at
least in English and Japanese) has been to append the unit after the
value.  But this is a syntax error in Python, and even the 'value[unit]'
dodge fails for literal numbers, while it probably isn't needed often
for variables (I would probably even consider it bad style).  We can
construct a Unit class, and use the multiplication operator to combine
a "bare" number with the unit, but this doesn't feel right to naive
users.  To me it feels like multiplying a number by a list.  What I
ideally want is two parts of a coherent whole, like real and imag.
(Note: This does not bother me in practice at all, I'm trying to
empathize with the folks whole say they can't stomach Python's
approach to units at all.)

Furthermore, there's another problem: units "should" have their own
namespace, almost like keywords.  But it's much more complicated than
keywords, because (1) there are many more potential collisions, both
between ordinary identifiers and units ('m' as an integer variable
vs. 'm' as a unit) and among units ('A' for ampere and 'A' for
Angstrom), and (2) the units namespace should be extensible.

Both of these issues (natural language practice and namespace) can be
most fully addressed with syntax that allows an optional identifier
expression to be placed directly after a literal or identifier, and
enforcing the semantics that this optional identifier expression must
be composed of registered units and only the allowed operations (* and
/, I guess).  Invalid operations would be SyntaxErrors, unregistered
identifiers would be RuntimeErrors.

I think that one way both issues can be addressed without syntax is to
take a package like units, add "repertoire attributes", so we can
write things like this

    import units
    u = units.si.modifiable_copy()    # the SI repertoire is read-only
    u.register_unit('frob', 'Fr', composed=u.foo/u.m,
                    doc='Frob is a devo unit invented by A. Panshin.')

    if 12*u.mm * 42*u.MFr == 502*u.foo:
        print('Well done!')

That would work fine for me.  But I can see why somebody who
frequently uses interactive Python as a scientific calculator would
prefer to write

    if 12 m/s * 42 s == 502 m:
        print('Well done!')

with the base SI repertoire (a dozen or so prefixes and 7 units) in
builtins.

As far as I can tell, that's the whole argument.

Steve

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

Reply via email to