[Python-ideas] Re: Custom literals, a la C++

2022-04-08 Thread Steven D'Aprano
On Mon, Apr 04, 2022 at 02:47:48PM -, Brian McCall wrote:
> Asked and answered!
> 
> > * There are an unlimited number of derived (non-SI) and compound units 
> >   that people will want to use.
> 
> Unlimited? You sure that problem can't be bounded? 

Every problem can be bounded by the amount of matter and energy in the 
universe :-)

More practically, the problem is bounded by the number of addressable 
memory locations (2^64) and more practically still, by the amount of 
memory you actually have.

Presumably there is only a finite number of named measurement units 
which have ever been used in history, maybe a few thousand or so. A few 
days ago I pointed out that the Unix "units" program listed 2000+ units. 
I upgraded to a more recent version, and it now has over 3000:

[steve ~]$ units
Currency exchange rates from FloatRates (USD base) on 2018-10-20 
3070 units, 109 prefixes, 109 nonlinear units

If the implementation had some reasonable hard limit like 20,000 named 
units, I wouldn't complain. But why? The obvious mapping from unit names 
to values is to use a dict, which is limited only by memory.


> In terms of the internal representation of units, the representation 
> that is use for machine calculations, there are only 7 units that need 
> to be supported. Everything else is a product of powers of these 7 
> units.

If you use the geometrized unit system, you need only one base unit, 
the metre. Everything can be written as a small power of length.

But for a more practical system, I count a minimum of 12 base 
dimensions:

* length
* mass
* time
* electric current
* thermodynamic temperature
* luminous intensity
* amount of substance
* amount of information
* currency
* plane angle
* solid angle
* other dimensionless (the name "uno" was proposed in 2003)

Some of these are strictly dimensionless in terms of the standard 
physics dimensional quantities, but we really don't want to be able to 
add 30 degrees to 1 yoctomol and get 1.1 radians.

(Reasonable people may disagree. So may unreasonable people.)

But as discussed in other parts of this lng thread, there are other 
dimensionless quantities which we may wish to treat as distinct. Ratios?

Then there are at least three types of non-linear units:

- temperatures
- log scales such as bels (decibels) and moment magnitude scale for earthquakes
- piecewise linear (wire gauges etc)

and lets not forget prefixes.



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


[Python-ideas] Re: Custom literals, a la C++

2022-04-08 Thread Chris Angelico
On Sat, 9 Apr 2022 at 02:31, Christopher Barker  wrote:
>
> On Fri, Apr 8, 2022 at 8:29 AM Chris Angelico  wrote:
>>
>> > > another that's using nautical miles, but *not both in the same
>> > > module*?
>
>
> Absolutely!
>
> There is talk about "the Application" as though that's one thing, but Python 
> applications these days can be quite large collections of third party 
> packages -- each of which do not know about the other,a nd each of which may 
> be using units in different ways.
>
> For example, I have an application that literally depends on four different 
> JSON libraries -- each used by a different third-party package. Imagine if 
> the configurable JSON encoding/decoding settings were global state -- that 
> would be a disaster.
>

You're misunderstanding the difference between "application" and
"library" here. Those are four separate libraries, and each one has a
single purpose: encoding/decoding stuff. It is not the application. It
is not the primary purpose of the process. If one of those JSON
libraries were to change your process's working directory, you would
be extremely surprised. We aren't bothered by the fact that os.chdir()
is global, we just accept that it belongs to the application, not a
library.

The Application *is* one thing. It calls on libraries, but there's
only one thing that has command of this sort of thing.

General rule: A library is allowed to change things that belong to the
application if, and only if, it is at the behest of the application.
That's a matter of etiquette rather than a hard-and-fast rule, but we
decry badly-behaved libraries for violating it, rather than blaming
the feature for being global.

> Granted
> * Python is dynamic and has a global module namespace, so packages CAN monkey 
> patch and make of mess of virtually anything.
> * "Well behaved" packages would not mess with the global configuration.
>
> But that doesn't mean that it wouldn't happen -- why encourage it? Why have a 
> global registry and then tell people not to use it?

For precisely the same reason that we have so many other global
registries. It is simplest and cleanest to maintain consistency rather
than try to have per-module boundaries.

When you have per-module features, refactoring becomes more of a
hassle. I've fielded multiple questions from people who do "import
sys" in one module, and then try to use "sys.argv" in another module,
not realising that the namespace into which the name 'sys' was
imported belonged only to that module. It's not too hard to explain,
but it's a thing that has to be learned. The more things that are
per-module, the more things you have to think about when you refactor.

It is a *good thing*, not a bad thing, that a large number of settings
are completely global. We do not need per-module settings for
everything, and it would be a nightmare to work with if we did.

> Having a global registry/context/whatever for something that is 
> designed/expected to be configured is dangerous and essentially useless.
>

Only if it's expected to be configured with some granularity. And, as
with decimal.localcontext(), it's perfectly possible to have scopes
much smaller than modules. So my question to you, just as to D'Aprano,
is: why should this be at the module scope, not global, and not
narrower?

> I'm not sure if this is really a good analogy, but it reminds me of the 
> issues with system locale settings:
>
> Back in the day, it seemed like a great idea to have one central palceon a 
> computer to set these nifty things that apply to that particular computer. 
> But enter the internet, where the location the computer the code is running 
> on could be completely unrelated to where the user is and what the user wants 
> to see, and it's a complete mess. Add to that different operating systems, 
> etc.
>
>
> To this day, Python struggles with these issues -- if you use the default 
> settings to open a text file, it may get virtually any encoding depending on 
> what system the program is running on -- there is a PEP in progress to fix 
> that, but it's been a long time!
>

What we now have is an even broader setting: the entire *planet* is
being set into a default of UTF-8, one programming language at a time.
We don't need it to be per-process any more, and we definitely never
wanted it to be per-module or any other finer scope.

The reason for having it centralized on the computer has always been
that different applications could then agree on something. Let's say
you set your computer to use ISO-8859-7 (or, if you're a Microsoft
shop, you might use code page 1253 for the same purpose). You're
telling every single application that you're planning to use Greek
text, and that it should assume that eight-bit data is most likely to
be in Greek. Since text files don't have inherent metadata identifying
their encodings, it's not unreasonable to let the system decide it.

Of course, that never worked all that well, so I'm not sorry to see
more and more things go 

[Python-ideas] Re: Custom literals, a la C++

2022-04-08 Thread Christopher Barker
On Fri, Apr 8, 2022 at 8:29 AM Chris Angelico  wrote:

> > > another that's using nautical miles, but *not both in the same
> > > module*?


Absolutely!

There is talk about "the Application" as though that's one thing, but
Python applications these days can be quite large collections of third
party packages -- each of which do not know about the other,a nd each of
which may be using units in different ways.

For example, I have an application that literally depends on four different
JSON libraries -- each used by a different third-party package. Imagine if
the configurable JSON encoding/decoding settings were global state -- that
would be a disaster.

Granted
* Python is dynamic and has a global module namespace, so packages CAN
monkey patch and make of mess of virtually anything.
* "Well behaved" packages would not mess with the global configuration.

But that doesn't mean that it wouldn't happen -- why encourage it? Why have
a global registry and then tell people not to use it?

Having a global registry/context/whatever for something that is
designed/expected to be configured is dangerous and essentially useless.

I'm not sure if this is really a good analogy, but it reminds me of the
issues with system locale settings:

Back in the day, it seemed like a great idea to have one central palceon a
computer to set these nifty things that apply to that particular computer.
But enter the internet, where the location the computer the code is
running on could be completely unrelated to where the user is and what the
user wants to see, and it's a complete mess. Add to that different
operating systems, etc.

To this day, Python struggles with these issues -- if you use the default
settings to open a text file, it may get virtually any encoding depending
on what system the program is running on -- there is a PEP in progress to
fix that, but it's been a long time!

Dateitme handling has the same issues -- I think the C libs STILL use the
system timezone settings. And an early version of the numpy datetime
implementation did too -- realy bad idea.

In short: The context in which code is run should be in complete control of
the person writing the code, not the person writing the "application".

Again: practical use case with units:

I maintain a primitive unit conversion lib -- in that lib, I have a
"registry" of units and names and synonyms, etc. That registry is loaded at
module import, and at that time it checks for conflicts, etc. Being Python,
the registry could be altered at run time, but that is not exposed as part
of the public API, and it's not a recommended or standard practice. And
this lets me make all sorts of arbitrary decisions about what "mile" and
"oz" and all that means, and it's not going to get broken by someone else
that prefers different uses -- at least if they use the public API.

-CHB



-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/UDGHUPACN7ZP6YZYOBWOB4CEVQWTGMGM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Custom literals, a la C++

2022-04-08 Thread Chris Angelico
On Sat, 9 Apr 2022 at 00:34, Steven D'Aprano  wrote:
>
> On Tue, Apr 05, 2022 at 02:17:00PM +1000, Chris Angelico wrote:
>
> > Do you ever have one module that's using statute miles and
> > another that's using nautical miles, but *not both in the same
> > module*? The only reason to have them namespaced to modules is to
> > allow different modules to use them independently. If your application
> > needs to use both statute and nautical miles in the same module (most
> > likely the main module), then it's going to have an issue, and your
> > proposal adds a ton of complexity (that's a real unit, by the way, I
> > totally didn't make it up) for no benefit whatsoever.
>
> That's not the real problem.
>
> The real problem is that my program may:
>
> * import ham, which registers mile as 1609.3412 m
> * import spam, which registers mile as 1609.344 m
> * import cheese, which registers mile as 1609.3472 m
> * import aardvark, which registers mile as 1609.3426 m
> * import hovercraft, which registers mile as 1853.181 m
>
> and then do calculations in miles, before converting to metres, and the
> results I get will be subtly (or not so subtly) different depending on
> the order I import those modules.
>
> (By the way, none of the above are nautical miles; of which there are at
> least three.)

Would it be better if you wrote it like this?

import SI; si.register()

I would be hard pressed to imagine a situation as pathological as you
suggest. Aside from a (relatively small) number of common systems,
most measurement systems are going to be sufficiently special purpose
that they're going to be the entire application. If you have a library
that chooses to register a common name like "mile", it's no different
from that library doing something like "decimal.getcontext().prec =
2", which is a fully documented feature.

Some features belong to the application, not the library, and I don't
think that's spoiled other things before. We cope.

> > What's the difference? You're looking at a fundamentally identical
> > problem, and thinking that it's fundamentally solved by module-level
> > separation? Show me some evidence.
>
> You are correct that this is fundamentally identical to the problem that
> namespaces are designed to solve. This is why modern languages don't
> have one single system-wide namespace.

Right. Remind me why most command shells have a single system-wide
namespace, then? Or is it a really good idea in programming but not in
scripting?

> We have 30+ years of Python programming, and 40-odd years of programming
> prior to Python, showing that the solution to the name collusion problem
> is to have distinct namespaces rather than one single system-wide
> namespace that everything writes to. That's exactly my point.

Yes. I have never disputed the value of namespaces as a way of
stopping names from colluding. Or colliding. What I'm disputing is
that the *module* is the one and only namespace that is right here.
You haven't yet shown a single bit of evidence for that.

> (Is that even possible? At import time, can eggs tell which module is
> importing it?)

I'm sure anything's possible with sys._getframe.

> > Have you ever mutated sys.modules?
>
> Not directly, no, except by the approved method of calling `import`,
> which never over-writes an existing entry, only adds new entries.

It's an incredibly useful way to mock things. You provide a module
before something else calls on it.

(It's also a good way for a module to replace *itself*, although
that's less commonly needed now that you can do module-level getattr.)

> Nor have I ever mutated the central registry of codecs to *replace*
> an existing encoder (like UTF-8) with my own. Likewise for error
> handlers.

Right. And, again, these namespaces are not per-module, yet you aren't
bothered by someone registering a name that you want. Why is the
module the perfect scope for units?

> There's only a relatively small number of each, and the two registries
> change so rarely that there is next to zero chance that I might
> accidently trample over an existing codecs or error handler with my own.
> And I do not expect that arbitrary imports will make changes to those
> registries.

You don't expect it. But somehow you DO expect arbitrary imports to
mutate the unit namespace. Why?

> With units, there are thousands of named units, with many name
> collisions. The system would be unworkable with only a single
> interpreter-wide registry.

[citation needed]

Do libraries tend to work in this way, giving unitted values in a
system different from the one the application uses? Is that actually a
thing, or are you just guessing?

> > > This is exactly analogous to the situation Python would have if there
> > > were no per-module globals, just the system-wide builtins, and every
> > > library stored top-level variables and functions in that namespace.
> > > *shudders*
> >
> > Straw man. It's more like using decimal.getcontext() and making
> > changes.
>
> The 

[Python-ideas] Re: Custom literals, a la C++

2022-04-08 Thread Steven D'Aprano
On Tue, Apr 05, 2022 at 02:17:00PM +1000, Chris Angelico wrote:

> Do you ever have one module that's using statute miles and
> another that's using nautical miles, but *not both in the same
> module*? The only reason to have them namespaced to modules is to
> allow different modules to use them independently. If your application
> needs to use both statute and nautical miles in the same module (most
> likely the main module), then it's going to have an issue, and your
> proposal adds a ton of complexity (that's a real unit, by the way, I
> totally didn't make it up) for no benefit whatsoever.

That's not the real problem.

The real problem is that my program may:

* import ham, which registers mile as 1609.3412 m
* import spam, which registers mile as 1609.344 m
* import cheese, which registers mile as 1609.3472 m
* import aardvark, which registers mile as 1609.3426 m
* import hovercraft, which registers mile as 1853.181 m

and then do calculations in miles, before converting to metres, and the 
results I get will be subtly (or not so subtly) different depending on 
the order I import those modules.

(By the way, none of the above are nautical miles; of which there are at 
least three.)


> "If I import * from cheddar first, then camembert, then I have issues".

And that is why you shouldn't `import *`. This is an old, well-known 
issue with wildcard imports.


> What's the difference? You're looking at a fundamentally identical
> problem, and thinking that it's fundamentally solved by module-level
> separation? Show me some evidence.

You are correct that this is fundamentally identical to the problem that 
namespaces are designed to solve. This is why modern languages don't 
have one single system-wide namespace.

We have 30+ years of Python programming, and 40-odd years of programming 
prior to Python, showing that the solution to the name collusion problem 
is to have distinct namespaces rather than one single system-wide 
namespace that everything writes to. That's exactly my point.

Of course if I do this:

from spam import mile
from eggs import mile

then I have a namespace collision that results in last value winning. 
But that's kinda obvious doncha think? :-)

Importantly, just doing

from spam import mile
import eggs

will not collide, except under the very unusual case that eggs gets up 
to no good by writing to the importing module's namespace.

(Is that even possible? At import time, can eggs tell which module is 
importing it?)



> Have you ever mutated sys.modules?

Not directly, no, except by the approved method of calling `import`, 
which never over-writes an existing entry, only adds new entries.

Nor have I ever mutated the central registry of codecs to *replace* 
an existing encoder (like UTF-8) with my own. Likewise for error 
handlers.

There's only a relatively small number of each, and the two registries 
change so rarely that there is next to zero chance that I might 
accidently trample over an existing codecs or error handler with my own. 
And I do not expect that arbitrary imports will make changes to those 
registries.

Never have I worried that `import spam` might change the meaning of the 
'utf-8' codec, or replace some error handler with one with the same name 
but different behaviour.

But if there were thousands of codecs, and every second module I 
imported could potentially add or delete those codecs, then I would have 
to worry about these things. The system would be unworkable and we would 
have to find a better one.

With units, there are thousands of named units, with many name 
collisions. The system would be unworkable with only a single 
interpreter-wide registry.


> > This is exactly analogous to the situation Python would have if there
> > were no per-module globals, just the system-wide builtins, and every
> > library stored top-level variables and functions in that namespace.
> > *shudders*
> 
> Straw man. It's more like using decimal.getcontext() and making
> changes.

The situation is analogous, but not identical. The decimal context is 
not a interpreter-wide registry of long-lasting entities intended to be 
used by any and all modules. It is a per-thread part of the decimal API.

Its not even a very close analogy: aside from sharing the vague concept 
of "global state" with your units registry, there's nothing like 
registering a unit ("furlongs per fortnight") in the decimal context. 
There are only eight settings, and you cannot set arbitary attributes in 
decimal contexts.

The decimal context environment isn't even truly interpreter-wide. It is 
per thread storage, so every thread has its own independent environment.

Other modules (except possibly your application's main module) are not 
expected to modify the current context, although that's not enforced. 
(This is Python: you can shoot yourself in the foot if you really want 
to.) It would be considered *badly-behaved* for other modules or 
functions to directly modify the 

[Python-ideas] Re: mro and super don't feel so pythonic

2022-04-08 Thread Chris Angelico
On Fri, 8 Apr 2022 at 22:56, Joao S. O. Bueno  wrote:
>
> Hi. I've replied to the first e-mail on this thread, more than 10 days ago.
> I am back, though I've read most of what was written.
>
> I don't think things have improved, but you sure are consuming everyone's time
>
> You are still repeating this:
> "more in line with the expectation of the majority, "
>
> Though, as already asked, there is zero (nothing) to support that.
> I've seen exactly _one_ e-mail among those in the thread, that seemed
> to need something different from the current status quo - though not
> exactly what you offer. I replied in private as that user's needs could
> be fulfilled with a custom metaclass, offering personal help with that (and 
> did not get a reply).
>
> So, I'd suggest to you, if not for others, at least for myself, that you'd 
> get some
> backup on what this "majority" you claim could be. Could you set, I don't 
> know,
> some online form? With questions like:
>
> "on the following scenario, what do you [think|prefer] 'super' [does|could 
> do]?"
>
> Then we can check. No need for "majority" - get at least some 10 respondents, 
> with 2 or 3 of those
> thinking the same as you, and then maybe it would make sense insisting
> on this path, as there could be something in there.
>

While I admire the intent here, unfortunately, a survey like that is
almost completely useless. It's easy to trap people into thinking that
super does something different from what it does, but that still
doesn't show that super needs to be changed. It might be better to
word it like this:

In the given scenario, which of these lines of code would you expect
to have this behaviour?
* super().method()
* ParentClass.method()
* method()
* ::method()
* ^method()
* super[1].method()

and ask people to rank them in order of which ones make the most
sense. I still don't think the survey would be hugely useful, but this
sort of wording is a better way of judging people's expectations than
asking them to describe the behaviour of a short form like
"super().method()".

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


[Python-ideas] Re: mro and super don't feel so pythonic

2022-04-08 Thread Joao S. O. Bueno
Hi. I've replied to the first e-mail on this thread, more than 10 days ago.
I am back, though I've read most of what was written.

I don't think things have improved, but you sure are consuming everyone's
time

You are still repeating this:
"more in line with the expectation of the majority, "

Though, as already asked, there is zero (nothing) to support that.
I've seen exactly _one_ e-mail among those in the thread, that seemed
to need something different from the current status quo - though not
exactly what you offer. I replied in private as that user's needs could
be fulfilled with a custom metaclass, offering personal help with that (and
did not get a reply).

So, I'd suggest to you, if not for others, at least for myself, that you'd
get some
backup on what this "majority" you claim could be. Could you set, I don't
know,
some online form? With questions like:

"on the following scenario, what do you [think|prefer] 'super' [does|could
do]?"

Then we can check. No need for "majority" - get at least some 10
respondents, with 2 or 3 of those
thinking the same as you, and then maybe it would make sense insisting
on this path, as there could be something in there.

Otherwise, just admit these are some features you thought of yourself, and
not even you seem
to be quite sure  of which should be the specs or deterministic outcome (if
any) when
calling parent class methods with M.I. Get your ideas out into some
packages,
gists, blog posts - some of what you want can be got with custom metaclasses
(except when retrieving dunder methods for operators, like __add__), and I
can
even help you to come up with those if you want. But these are toys
nonetheless,
which might see the "light of the day" maybe once a year in a codebase.

best regards,

js
  -><-



On Thu, Apr 7, 2022 at 12:39 PM malmiteria  wrote:

> Antoine Rozo writes:
> > If the only feature you need from super is the proxy one, why don't you
> > code your own parent-proxy-type?
>
> I did :
> https://github.com/malmiteria/super-alternative-to-super/blob/master/parent.py
>
> This is irrelevant to the discussion we're having i think.
> Essentially, I'm arguing against today's state of some edge case of MRO +
> super, and against the UX associated with it.
> Those are issues with today's python, and the update that i propose would
> reduce the UX problems with super and MRO, would allow for use case of
> super more in line with the expectation of the majority, and would open the
> door to a few cases locked behind MRO errors today.
> Technically, with my proposal, you could even do circular inheritance,
> which is definitely unheard of today:
> ```
> class Day:
>   def tell_time(self):
> print("it's daytime")
> sleep(1)
> super().tell_time()
>
> class Night(Day):
>   def tell_time(self):
> print("it's night time")
> sleep(1)
> super().tell_time()
>
> Day.__bases__ = (Night, )
>
> Day().tell_time() # infinitely loops over "it's daytime" and "it's night
> time"
> ```
> That would be an incredibely easy way to articulate process that repeat in
> a cycle, with no end, cron style.
> No need to get multiple class too:
> ```
> class CronTask:
>   def task(self):
> # do something
> time.sleep(1)
> super().task()
>
> CronTask.__bases__ = (CronTask, )
>
> CronTask().task() # runs the task forever with a time sleep in between
> ```
>
> I'm convinced there's some smart designs that are banned from python
> because of MRO and super's limitations.
> ___
> 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/BKFSLLICTCAYBPIZBTVW4Y4OPT3UKBZ2/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/BVZ7UIEHFGX3V66P2COWOY7UK3WCCSDA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Native support for units [was: custom literals]

2022-04-08 Thread Paul Moore
On Fri, 8 Apr 2022 at 13:09, Matt del Valle  wrote:
>
> My personal preference for adding units to python would be to make instances 
> of all numeric classes subscriptable, with the implementation being roughly 
> equivalent to:
>
> def __getitem__(self, unit_cls: type[T]) -> T:
> return unit_cls(self)
>
>
> We could then discuss the possibility of adding some implementation of units 
> to the stdlib. For example:
>
> from units.si import km, m, N, Pa
>
> 3[km] + 4[m] == 3004[m]  # True
> 5[N]/1[m**2] == 5[Pa]  # True

Thanks. That's extremely useful, and I can see it as a reasonable
language feature request. BUT (and it's a big "but"!) someone would
have to write, support and maintain that units library. Obviously in
the first instance, it couldn't use the dedicated syntax, but
unit_cls(number) doesn't seem like a horribly bad compromise for a 3rd
party library right now.

So here's my proposal.

1. Somebody (or a group of people) who wants to see this happen, write
(or adopt) a library and publish it on PyPI. It should provide *all*
of the functionality that the proposed stdlib support would offer,
with the sole exception that units get attached to values using
unit_cls(number) rather than special syntax. It's possible that the
"units" library that's already on PyPI is (nearly) that library - but
from what I've heard in this thread, the community hasn't reached
consensus on what "best of breed" looks like yet.
2. Once that library has demonstrated its popularity, someone writes a
PEP suggesting that the language adds support for the syntax
`number[annotation]` that can be customised by user code. This would
be very similar in principle to the PEP for the matrix multiplication
@ operator - a popular 3rd party library demonstrates that a
well-focused language change, designed to be generally useful, can
significantly improve the UI of  the library in a way which would be
natural for that library's users (while still being general enough to
allow others to experiment with the feature as well).
3. Once the new language feature is accepted, and the library authors
are willing, propose that the library gets added to the stdlib.

We're currently at step 1 - we need someone to come up with a library
that demonstrates how to provide this functionality in a way that
matches users' requirements, and which has unified community support.
That step doesn't need anything much from the Python core devs or even
this list, beyond maybe a general feeling that the overall plan "isn't
a totally dumb idea"...

Step 2 is where a PEP and proper core dev support would be needed. But
the library would be useful even if this doesn't happen (and
conversely, if the library proves *not* to be useful, it demonstrates
that the language change wouldn't actually be as valuable as people
had hoped).

Step 3 is optional. With language support that can be used by external
libraries, "being part of the stdlib" isn't needed. This is true of
pretty much everything in the stdlib, though - stdlib modules don't
have any special benefits that external libraries don't. As a
supporter of a large stdlib, I'd be OK with moving the units library
into the stdlib (on the assumption that the library maintainers commit
to supporting it in the stdlib, and don't run away and dump the
problem on the core devs). Others who prefer a smaller stdlib would
argue it's fine on PyPI. But that's an argument about principles which
frankly end users and 3rd party library authors can't influence much
(and can probably ignore in practice).

So honestly, I'd encourage interested users to get on with
implementing the library of their dreams. By all means look ahead to
how language syntax improvements might help you, but don't let that
stop you getting something useful working right now.

Paul
___
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/5NYDJZSQK7ZEE5UDCWHAAU5ZK5FKCLVE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Native support for units [was: custom literals]

2022-04-08 Thread Matt del Valle
My personal preference for adding units to python would be to make
instances of all numeric classes subscriptable, with the implementation
being roughly equivalent to:

def __getitem__(self, unit_cls: type[T]) -> T:
return unit_cls(self)


We could then discuss the possibility of adding some implementation of
units to the stdlib. For example:

from units.si import km, m, N, Pa

3[km] + 4[m] == 3004[m]  # True
5[N]/1[m**2] == 5[Pa]  # True


'Casual' users could also use a star import (despite its pitfalls) and not
have to worry about going back and updating the import statement, so I
don't think requiring that import would be much of a barrier to beginners.
They'd just learn they need that star import at the top of the file as a
sort of 'magic spell'.

Third-party libraries could provide their own unit classes with additional
features and characteristics that you could substitute in by simply
changing the import statement and nothing else. To write a custom unit
class you would just have to implement an __init__ that accepts a single
numeric argument. To enable units like  m², the __pow__ magic method would
have to be implemented in the unit class' metaclass.

The advantages of this seem to me like:
1) no new syntax, just an extra magic method for numeric types
2) batteries included,
3) Won't clutter up the builtins, you have to opt in by using imports
3) simple for third-party libraries to support and extend

I can't really see much in the way of disadvantages aside from:
1) aesthetic objections to the use of subscription for this purpose. I
personally quite like it because in a way a unit at the end of a number *is*
a subscript anyway, so it seems quite fitting to use python's subscription
syntax for it.
2) the opposite of advantage 3) above: people actually *wanting* the units
to be part of the builtins so that you don't have to use any imports.
Depending on your opinion this can be a good or bad thing

And if no reasonable implementation of the batteries can be agreed upon,
that's fine, that part can be delayed or rejected.

On Fri, Apr 8, 2022 at 12:21 PM Ricky Teachey  wrote:

> On Fri, Apr 8, 2022, 2:40 AM Stephen J. Turnbull <
> stephenjturnb...@gmail.com> wrote:
>
>> Brian McCall writes:
>>  Steven d'Aprano writes:
>>
>>  > > you have shown nothing to justify why unit support must be built
>>  > > into the language itself.
>>  >
>>  > I did what I could, but I'm not going to try and justify any more.
>>
>> That makes me sad, because everybody in the thread acknowledges that
>> improving the Python distribution's support for units is a good idea,
>> but nobody is as enthusiastic about getting it done as you.
>>
>> Chris Barker's comments about multiple attractive library
>> implementations are well-taken, I think, but I also think that with
>> more focus on getting a satisfactory module into the stdlib, it would
>> be quite possible to pick one that doesn't rely on non-stdlib types
>> (so I guess astropy.units would be out).
>>
>> That doesn't directly get you the literal syntax for units you focus
>> on, but if units are easier to use, more applications will use them,
>> and perhaps build up momentum for a syntax change.  And the syntax
>> change is useless without the library.
>>
>
> I'll try to provide examples of my struggles with units in python but I'm
> not an accomplished coder at all and don't have much to look at in the way
> of examples. I sometimes go weeks without writing any code at all, followed
> by days of nothing but writing code.
>
> Python is so painful to use for units I've actually avoided it, so there
> won't be many examples I can give anyway. Hence my silence in this thread
> the past few days.
>
> I just get really excited at the idea of it being native to the language
> and am dreaming of being able to use it more often for my every day
> calculations. Right now I just don't feel confident I can.
> ___
> 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/LSQQKL72J5AWCCZFHVY2M4RJFU7Y6OGH/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/E6TWNUNIABVADBLRHY6LQXFRCH4UE74Z/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Giving Decimal a global context was a mistake?

2022-04-08 Thread Greg Ewing

On 8/04/22 7:03 pm, Christopher Barker wrote:

Are you SURE your accounting software is doing the right thing?  ;-)


Well, I've only ever seen precision problems manifest themselves
once, and that was when I wrote a script that used repeated
multiplications by 10 as part of a process to convert a number
into words. I had to put some rounding steps into that to make
it work properly.

Other than that, if you were adding up about a billion monetary
amounts in one go without any rounding, you might get a problem.
I've never seen anyone do that, though. :-)

Also -- if it uses 64 bit floats, it'll have problems with trillions of 
dollars :-)


If your business is that big, you would not be using this particular
accounting package!

--
Greg

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


[Python-ideas] Re: Native support for units [was: custom literals]

2022-04-08 Thread Paul Moore
On Fri, 8 Apr 2022 at 12:22, Ricky Teachey  wrote:

> I just get really excited at the idea of it being native to the language and 
> am dreaming of being able to use it more often for my every day calculations. 
> Right now I just don't feel confident I can.

If you can describe what the Python of your dreams would look like,
that would be really useful. Most of the problem here is with people
who *don't* need units for every day calculations struggling to
understand what is wrong with a library-based solution, and what
"language support" would look like in practice.

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


[Python-ideas] Re: Native support for units [was: custom literals]

2022-04-08 Thread Ricky Teachey
On Fri, Apr 8, 2022, 2:40 AM Stephen J. Turnbull 
wrote:

> Brian McCall writes:
>  Steven d'Aprano writes:
>
>  > > you have shown nothing to justify why unit support must be built
>  > > into the language itself.
>  >
>  > I did what I could, but I'm not going to try and justify any more.
>
> That makes me sad, because everybody in the thread acknowledges that
> improving the Python distribution's support for units is a good idea,
> but nobody is as enthusiastic about getting it done as you.
>
> Chris Barker's comments about multiple attractive library
> implementations are well-taken, I think, but I also think that with
> more focus on getting a satisfactory module into the stdlib, it would
> be quite possible to pick one that doesn't rely on non-stdlib types
> (so I guess astropy.units would be out).
>
> That doesn't directly get you the literal syntax for units you focus
> on, but if units are easier to use, more applications will use them,
> and perhaps build up momentum for a syntax change.  And the syntax
> change is useless without the library.
>

I'll try to provide examples of my struggles with units in python but I'm
not an accomplished coder at all and don't have much to look at in the way
of examples. I sometimes go weeks without writing any code at all, followed
by days of nothing but writing code.

Python is so painful to use for units I've actually avoided it, so there
won't be many examples I can give anyway. Hence my silence in this thread
the past few days.

I just get really excited at the idea of it being native to the language
and am dreaming of being able to use it more often for my every day
calculations. Right now I just don't feel confident I can.
___
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/LSQQKL72J5AWCCZFHVY2M4RJFU7Y6OGH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: mro and super don't feel so pythonic

2022-04-08 Thread Steven D'Aprano
On Thu, Apr 07, 2022 at 11:52:31AM -, malmiteria  wrote:

> I believe my gobelin exemple is a fair case of MI since we can 
> definitely say halfbreed *is a* corruptedgobelin *and a* proudgobelin.

That is the most common relationship modelled by inheritance.


> In such a case with multiple *is a* there's multiple strategies to 
> blend in the multiple *is a*.

And super does that correctly.

Except that you prefer to use a different design that is not well- 
modelled by inheritance, but is well-modelled by delegation. And then 
for some reason, you insist on using super.


> Another strat is to say that some attributes / behaviors of one parent 
> override the over, like dominant genes.

Don't be fooled by the name, inheritance in programming languages does 
not model DNA. It is a simple model useful for programming.


> Today's MRO implicitely overrides all method from the second parent 
> with method from the first parent.

Right, because it models **cooperative inheritance**, not DNA. A method 
in one class overrides that in classes later in the MRO unless it 
cooperatively passes the call on to the next class in the MRO.


> Essentially, the first parent (in declaration order) is dominant on 
> all attributes. This isn't very subtle, as we could want some 
> attribute of each parent to be dominant, while others to be recessive.

This is all very hypothetical. You could want Intercal's COMEFROM 
statement too, but why would you?

MI is complicated enough without intentionally trying to make it 
arbitrarily more complicated, when instead you can just use composition 
or delegation instead.

You want to write this:

super(ProudGobelin, self).method()

But you can already do that, using less typing, and get exactly the same 
effect:

ProudGobelin.method(self)

That does everything you want, and saves you seven characters. Less 
typing, more efficient, works today in standard Python, no special 
imports needed or changes to the interpreter or language. All you need 
to do is **don't use super** for things that don't need super.

The only reason you won't use it is that you insist on using the 
screwdriver of super() to hammer in the nails of delegation.



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


[Python-ideas] Re: mro and super don't feel so pythonic

2022-04-08 Thread Greg Ewing

On 7/04/22 11:11 pm, malmiteria wrote:

But if there was a way to tell super what class it should be a proxy of, that 
would be very easy to explain : when there's two parent, just give the parent 
you want to target as an argument to super.


That sounds like exactly what Class.method(self) does today. Why
do we need another way to do it?

 It requires knowing a *lot* about the classes you're inheriting from, 
*today*, and that's a problem I'm trying to adress.

And you being able to tell those 2 classes have some sort of common ancestry 
wouldn't be of much help if you don't already know about MRO and the effect it 
might have on inherited classes in case of multiple inheritance.


That's not the kind of knowledge I'm talking about. You need to know
a lot about how those particular classes behave -- what their methods
do, whether they would conflict with each other in any way, what the
consequences would be of calling them in various orders, etc.

You seem to think that removing the MRO and making super work the
way you imagine it should would make it easy to grab any bunch of
arbitrary classes and inherit from them and everything would be fine
and dandy. It would not!


The Mixin use case, where we explicitely use the super ability to side jump so 
that our mixin 'specialise' the last class in MI order would really benefit 
from a feature allowing a class to select a parent after being defined.


I still don't understand how you expect a particular super call
in a particular method to somehow be able to jump sideways when
you want it to and not other times. You'll have to provide a
detailed example, not just vague waffling about mixins and
proxying.

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


[Python-ideas] Re: mro and super don't feel so pythonic

2022-04-08 Thread Greg Ewing

On 7/04/22 11:52 pm, malmiteria wrote:

I believe my gobelin exemple is a fair case of MI since we can definitely say 
halfbreed *is a* corruptedgobelin *and a* proudgobelin.


I'm not so sure about that. I would agree that it's a gobelin, just as
you are (presumably) a human.

But a child is *not* its parents -- it's a human in its own right that
happens to have some characteristics of one parent and some of the
other. I'm not sure MI is such a good way to model that kind of
relationship.

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


[Python-ideas] Re: mro and super don't feel so pythonic

2022-04-08 Thread Antoine Rozo
If these examples were possible (I wouldn't say they are smart designs)
they would lead to recursion errors.
Limitations on MRO are good, they force to keep a quite simple structure.

Le jeu. 7 avr. 2022 à 17:41, malmiteria  a écrit :

> Antoine Rozo writes:
> > If the only feature you need from super is the proxy one, why don't you
> > code your own parent-proxy-type?
>
> I did :
> https://github.com/malmiteria/super-alternative-to-super/blob/master/parent.py
>
> This is irrelevant to the discussion we're having i think.
> Essentially, I'm arguing against today's state of some edge case of MRO +
> super, and against the UX associated with it.
> Those are issues with today's python, and the update that i propose would
> reduce the UX problems with super and MRO, would allow for use case of
> super more in line with the expectation of the majority, and would open the
> door to a few cases locked behind MRO errors today.
> Technically, with my proposal, you could even do circular inheritance,
> which is definitely unheard of today:
> ```
> class Day:
>   def tell_time(self):
> print("it's daytime")
> sleep(1)
> super().tell_time()
>
> class Night(Day):
>   def tell_time(self):
> print("it's night time")
> sleep(1)
> super().tell_time()
>
> Day.__bases__ = (Night, )
>
> Day().tell_time() # infinitely loops over "it's daytime" and "it's night
> time"
> ```
> That would be an incredibely easy way to articulate process that repeat in
> a cycle, with no end, cron style.
> No need to get multiple class too:
> ```
> class CronTask:
>   def task(self):
> # do something
> time.sleep(1)
> super().task()
>
> CronTask.__bases__ = (CronTask, )
>
> CronTask().task() # runs the task forever with a time sleep in between
> ```
>
> I'm convinced there's some smart designs that are banned from python
> because of MRO and super's limitations.
> ___
> 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/BKFSLLICTCAYBPIZBTVW4Y4OPT3UKBZ2/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Antoine Rozo
___
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/NFHV3F2ELGZ6EW6QHDNOQGLZHNHJ54HH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Giving Decimal a global context was a mistake?

2022-04-08 Thread Christopher Barker
On Thu, Apr 7, 2022 at 2:51 PM Greg Ewing 
wrote:

> I don't think it's entirely about the display. It's also about
> things like sum([1/10] * 10) == 1 being False.


sure, but:

In [18]: sum([Decimal(1) / Decimal(3)] * 3) == Decimal(1)
Out[18]: False

Which is just as bad -- not as "confusing" to folks that are used to
decimal, but I get a bad feeling when the docs talk about "exact" -- I'm
not sure that the distinction that's it's only *decimal* fractions that are
exact comes through for more casual readers.

This is where
> "human-friendly" display actually makes things worse, because
> repr() makes it *look* like 1/10 equals decimal 1.0, but it really

doesn't.
>

well, yes, that is a good point.


> > Calculating interest, inflation, who knows what could easily
> > introduce non-exactly-representable-in-decimal numbers.
>
> Yes, but when it comes to the point of e.g. adding some interest
> to an account, the amount of interest needs to be an exact
> multiple of 0.01 dollars. And if you add up all the interest
> transferred during your nightly run, it had better exactly
> equal the amount taken out of the account the interest is being
> paid from.
>

Sure -- but that requires careful rounding and all that -- I don't think
Decimal makes that any easier, frankly, particularly if you use cents as
your units, rather than dollars.

(though my earlier point that Decimal does allow you to control the
rounding is an important feature for these types of applications)


> BTW, there's an accounting package I work with that uses binary
> floating point for money, and seems to get away with it. Probably
> because everything that goes into the database gets rounded to
> a defined number of decimal places, so errors don't get a chance
> to accumulate to the point where they would cause a problem.
> It does make me a bit nervous, though. :-)
>

Well -- the authors of that package seem to have demonstrated my point --
you need to take care with rounding and limited precision regardless -- and
once you do that, binary is just as good :-)

Are you sure you can trust it though? There's the old urban legend about
the programmer for a bank writing the code so that the rounded pennies
would go into his account -- it added up to a lot of money that nobody
noticed was missing. The legend goes that he was only caught because the
bank had a promotional event in which they drew a randomly selected
account -- and found his.

Are you SURE your accounting software is doing the right thing?  ;-)

-CHB

Also -- if it uses 64 bit floats, it'll have problems with trillions of
dollars :-) -- might lose track of some cents there 



-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/NKUUTXURMJXBWATMRIZULJR27U4MYDMZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Native support for units [was: custom literals]

2022-04-08 Thread Stephen J. Turnbull
Brian McCall writes:
 Steven d'Aprano writes:

 > > you have shown nothing to justify why unit support must be built
 > > into the language itself.
 > 
 > I did what I could, but I'm not going to try and justify any more.

That makes me sad, because everybody in the thread acknowledges that
improving the Python distribution's support for units is a good idea,
but nobody is as enthusiastic about getting it done as you.

Chris Barker's comments about multiple attractive library
implementations are well-taken, I think, but I also think that with
more focus on getting a satisfactory module into the stdlib, it would
be quite possible to pick one that doesn't rely on non-stdlib types
(so I guess astropy.units would be out).

That doesn't directly get you the literal syntax for units you focus
on, but if units are easier to use, more applications will use them,
and perhaps build up momentum for a syntax change.  And the syntax
change is useless without the library.

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