[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Greg Ewing

On 30/04/20 3:32 am, Christopher Barker wrote:
I've wondered about Linked Lists for a while, but while there are many 
versions on PyPi, I can't find one that seems to be mature and 
maintained. Which seems to indicate that there isn't much demand for them.


I think this is probably because a linked list is more of
a design pattern than a concrete data structure. In situations
where you want a linked list in particular, rather than just
a container that supports certain operations, you really need
the references implementing the links to be embedded in the
objects being kept in the list. This makes it difficult to
abstract, especially if your objects need to be part of more
than one list at a time.

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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Greg Ewing

On 29/04/20 11:32 pm, Steven D'Aprano wrote:

My reasoning was that *eventually* for a big enough list, the cost of
making the copy would outweigh the cost of moving the items. I don't
know if my reasoning was valid or not,


I think it's not. They're both O(n) in the length of the list,
so at most they will differ by a constant factor for large n.

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


[Python-ideas] Re: Adding a "once" function to functools

2020-04-29 Thread Andrew Barnert via Python-ideas
On Apr 29, 2020, at 11:15, Tom Forbes  wrote:
> 
>> Thread 2 wakes up with the lock, calls the function, fills the cache, and 
>> releases the lock.
> 
> What exactly would the issue be with this:
> 
> ```
> import functools
> from threading import Lock
> 
> def once(func):
>sentinel = object()
>cache = sentinel
>lock = Lock()
> 
>@functools.wraps(func)
>def _wrapper():
>nonlocal cache, lock, sentinel
>if cache is sentinel:
>with lock:
>if cache is sentinel:
>cache = func()
>return cache
> 
>return _wrapper
> ```

You’ve written an exactly equIvalent to the double-checked locking for 
singletons examples that broke Java 1.4 and C++03 and led to us having once 
functions in the first place.

In both of those languages, and most others, there is no guarantee that the 
write to cache in thread 1 happens between the two reads from cache in thread 
2. Which gives you the fun kind of bug that every few thousand runs you have 
corrupted data an hour later, or it works fine on your computer but it crashes 
for one of your users because they have two CPUs that don’t share L2 cache 
while you have all your cores on the same die, or it works fine until you 
change some completely unrelated part of the code, etc.

Java solved this by adding volatile variables in Java 5 (existing code was 
still broken, but just mark cache volatile and it’s fixed); C++11 added a 
compiler-assisted call_once function (and added a memory model that allows them 
to specify exactly what happens and when so that the desired behavior was 
actually guaranteeable). Newer languages learned from their experience and got 
it right the first time, rather than repeating the same mistake.

Is there anything about Python’s memory model guarantee that means it can’t 
happen in Python? I don’t think there _is_ a memory model. In CPython, or any 
GIL-based implementation, I _think_ it’s safe (the other thread can’t be 
running at the same time on a different core, so there can’t be a cache 
coherency ordering issue between the cores, right?), but what about on Jython, 
or PyPy-STM, or a future GIL-less Python?

And in both of those languages, double-checked locking is still nowhere near as 
efficient as using a local static.

> Seems generally more correct, even in single threaded cases, to pay the 
> overhead only in the first call if you want `call_once` semantics. Which is 
> why you would be using `call_once` in the first place?

But you won’t be paying the overhead only on the first call, you’ll be paying 
it on all of the calls that before the first one completed. That’s the whole 
point of the lock, after all—they have to wait until it’s ready—and they can’t 
possibly do that without the lock overhead. And for the next few afterward, 
because they’ll have gotten far enough to check even if they haven’t gotten far 
enough to get the lock, and there’s no way they can know they don’t need the 
lock. And for the next few after that, because unless the system only runs one 
thread at a time and synchronizes all of memory every time you switch threads 
they may not see the write yet anyway.
___
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/G4ZDP6UYOL323VGX4IFRGGA5OVIEDD6P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding a "once" function to functools

2020-04-29 Thread Raymond Hettinger



> On Apr 29, 2020, at 11:15 AM, Tom Forbes  wrote:
> 
> What exactly would the issue be with this:
> 
> ```
> import functools
> from threading import Lock
> 
> def once(func):
>sentinel = object()
>cache = sentinel
>lock = Lock()
> 
>@functools.wraps(func)
>def _wrapper():
>nonlocal cache, lock, sentinel
>if cache is sentinel:
>with lock:
>if cache is sentinel:
>cache = func()
>return cache
> 
>return _wrapper
> ```

This recipe is the best variant so far and gives us something concrete to talk 
about :-)

Benefits: Guarantees the wrapped function is not called more than once.
Restrictions:  Only works with zero argument functions.
Risks: Any reentrancy or recursion will result in deadlock.
Limitations: No instrumentation. No ability to reset or clear. Won't work 
across multiple processes.

It would be nice to look at some compelling use cases.  Off hand, I can't think 
of time when I would have used this decorator.  Also, I have a nagging worry 
that holding a non-reentrant lock across an arbitrary user defined function 
call is recipe for deadlocks.  That's why during code reviews we typically 
check every single use of Lock() to see if it should have been an RLock(), 
especially in big systems where GC, __del__, or weakref callbacks can trigger 
running any code at just about any time.


Raymond










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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Raymond Hettinger

> On Apr 29, 2020, at 12:02 PM, Christopher Barker  wrote:
> 
> On Apr 29, 2020, at 08:33, Christopher Barker  wrote:
> > I've wondered about Linked Lists for a while, but while there are many 
> > versions on PyPi, I can't find one that seems to be mature and maintained. 
> > Which seems to indicate that there isn't much demand for them.
> 
> Isn't much demand for a *generic* linked list. It would probably be a good 
> recipe though -- so users could have a starting point for their custom 
> version.

In case you're interested, the pure python OrderedDict code uses a doubly 
linked list augmented by a dictionary to quickly find individual links. It may 
be worth taking at look.¹ 

The implementation was mostly obvious.  The only trick was to use weakrefs for 
the backlink to avoid creating a reference cycle — the original version just 
lets GC do the clean-up, but users wanted to avoid cycles entirely.


Raymond


¹ https://github.com/python/cpython/blob/3.8/Lib/collections/__init__.py#L78
___
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/5ZSDX4FBSZEG3W6CGY6DNDOTLDOK7AQJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Rhodri James

On 29/04/2020 20:54, Andrew Barnert via Python-ideas wrote:

On Apr 29, 2020, at 12:03, Christopher Barker
wrote:


Isn't much demand for a*generic*  linked list. It would probably be
a good recipe though -- so users could have a starting point for
their custom version.

I think what would be really handy would be a HOWTO on linked lists
that showed the different options and tradeoffs and how to implement
and use at least a few different ones, and showed why they’re useful
with examples. (And also showed why the Sequence/Iterable API can be
helpful but also why it’s not sufficient.)


Isn't the point that you should be approaching a datastructure in Python 
thinking about what you want it to do, not how it's implemented 
underneath?  That sort of micromanagement smacks of premature optimisation.


--
Rhodri James *-* Kynesim Ltd
___
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/X4FQMNUQLVVHPCCA7VGACO4NA4YZLLXJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Chris Angelico
On Thu, Apr 30, 2020 at 5:56 AM Andrew Barnert via Python-ideas
 wrote:
>
> On Apr 29, 2020, at 12:03, Christopher Barker  wrote:
> >
> >
> > Isn't much demand for a *generic* linked list. It would probably be a good 
> > recipe though -- so users could have a starting point for their custom 
> > version.
>
> I think what would be really handy would be a HOWTO on linked lists that 
> showed the different options and tradeoffs and how to implement and use at 
> least a few different ones, and showed why they’re useful with examples. (And 
> also showed why the Sequence/Iterable API can be helpful but also why it’s 
> not sufficient.)
>
> Then the collections module (and the tutorial?) could both just have a 
> sentence saying “Python doesn’t have a linked list type because there are so 
> many useful kinds of linked lists and they’re all easy to build but very 
> different—see the Linked Lists HOWTO for details.”
>
> But if I wrote it, it would probably be 4x as long as any novice would want 
> to read.
>

Summary, for novices: "Just use a built-in list and don't worry about
it. Performance of built-in types is usually 'good enough' even if it
isn't perfect."

It's only the experts who need this sort of thing, so I'm not too
bothered if novices can't implement LLs efficiently in Python.

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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Andrew Barnert via Python-ideas
On Apr 29, 2020, at 12:03, Christopher Barker  wrote:
> 
> 
> Isn't much demand for a *generic* linked list. It would probably be a good 
> recipe though -- so users could have a starting point for their custom 
> version.

I think what would be really handy would be a HOWTO on linked lists that showed 
the different options and tradeoffs and how to implement and use at least a few 
different ones, and showed why they’re useful with examples. (And also showed 
why the Sequence/Iterable API can be helpful but also why it’s not sufficient.)

Then the collections module (and the tutorial?) could both just have a sentence 
saying “Python doesn’t have a linked list type because there are so many useful 
kinds of linked lists and they’re all easy to build but very different—see the 
Linked Lists HOWTO for details.”

But if I wrote it, it would probably be 4x as long as any novice would want to 
read. (I think I wrote some blog posts on linked lists in Python years ago, and 
ended up building a Haskell-style lazy list out of a trigger function and then 
showing how to do Fibonacci numbers by recursively zipping it, or something 
crazy like that.)

In the old days we could probably just post three different simple recipes on 
ActiveState and link to them from the docs and let people build on the examples 
there, rather than try to write it all up-front and fit it into the Python docs 
style, but that doesn’t work so well anymore.

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


[Python-ideas] Re: zip(x, y, z, strict=True)

2020-04-29 Thread Andrew Barnert via Python-ideas
On Apr 29, 2020, at 07:08, Barry Scott  wrote:
> 
> 
>> On 28 Apr 2020, at 16:12, Rhodri James  wrote:
>> 
>>> On 28/04/2020 15:46, Brandt Bucher wrote:
>>> Thanks for weighing in, everybody.
>>> Over the course of the last week, it has become surprisingly clear that 
>>> this change is controversial enough to require a PEP.
>>> With that in mind, I've started drafting one summarizing the discussion 
>>> that took place here, and arguing for the addition of a boolean flag to the 
>>> `zip` constructor. Antoine Pitrou has agreed to sponsor, and I've chatted 
>>> with another core developer who shares my view that such a flag wouldn't 
>>> violate Python's existing design philosophies.
>>> I'll be watching this thread, and should have a draft posted to the list 
>>> for feedback this week.
>> 
>> -1 on the flag.  I'd be happy to have a separate zip_strict() (however you 
>> spell it), but behaviour switches just smell wrong.
> 
> Also -1 on the flag.
> 
> 1. A new name can be searched for.
> 2. You do not force a if on the flag for every single call to zip.

Agreed on both Rhodri’s and Barry’s reasons, and more below.

I also prefer the name zip_equal to zip_strict, because what we’re being strict 
about isn’t nearly as obvious as what’s different between shortest vs. equal 
vs. longest, but that’s just a mild preference, not a -1 like the flag.

In addition to the three points above:

Having one common zip variant spelled as a different function and the other as 
a flag seems really bad for learning and remembering the language. And 
zip_longest has a solidly established precedent. And I don’t think you want to 
add multiple bool flags to zip?

Also, just look at these:

zip_strict(xs, ys)
zip(xs, ys, strict=True)

The first one is easier to read because it doesn’t have the extra 5 characters 
to skim over that don’t really add anything to the meaning, and it puts the 
important distinction up front.

It’s also shorter, and a lot easier to type with auto-complete—which isn’t 
nearly as big of a deal, but if this is really meant to be used often it does 
add up.

And it’s obviously more extensible, if it really is at all possible that we 
might want to eventually deprecate shortest or add new end behaviors like 
yielding partial tuples or Soni’s thing of stashing the leftovers somehow (none 
of which I find very convincing, but others apparently do, and picking a design 
that rules them out means explicitly rejecting them).

A string or enum flag instead of a book solves half of those problems (as long 
as “longest” is one of the options), but it makes others even worse. The 
available strings aren’t even discoverable as part of the signature, 
auto-complete won’t help at all, and the result is even longer and even more 
deemphasizes the important thing.

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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Christopher Barker
Thanks for all the details -- it really makes the point I was trying to
make.

On Apr 29, 2020, at 08:33, Christopher Barker  wrote:

> > I've wondered about Linked Lists for a while, but while there are many
> versions on PyPi, I can't find one that seems to be mature and maintained.
> Which seems to indicate that there isn't much demand for them.
>

Isn't much demand for a *generic* linked list. It would probably be a good
recipe though -- so users could have a starting point for their custom
version.

Also -- as you point out, while it may be useful for a linked list to be a
Sequence, the API shouldn't be only that -- it'd almost defeat the purpose
of a linked list at all.

-CHB





> I think there’s lots of demand for them, but there are so many different
> variants that can’t substitute for each other (try taking any nontrivial
> sample code using Haskell’s single-linked, no-handle, immutable
> tail-sharing list and rewriting it with C++’s doubly-linked handled mutable
> list, or vice-versa), and most of the key operations fit so poorly with
> Python’s sequence/iterable API, and they’re all so easy to build, that
> people just build the one they need whenever they need it.
>
> I do have a few different linked lists in my toolbox that have come up
> often enough that I stashed them (an immutable cons, a handled
> double-linked list, a cffi wrapper for a common style of C
> internally-linked lists, probably others), but half the time I reach for
> one I have to modify it anyway, so I haven’t bothered to turn them into a
> package I just import and use.
>
> And, while I did add the whole (Mutable)Sequence API to each one (because
> it’s convenient for debugging and REPL exploration to be able to list(xs),
> or to get a repr that’s written in terms of a from_iter classmethod so I
> can eval it back, etc.), I usually don’t use that API for anything but
> debugging. When you’re dealing with linked lists, you usually need to deal
> with the nodes directly. For example, one big reason to use linked lists is
> constant-time splicing, but you can’t splice in constant time if all you
> have is the head/handle and/or an opaque iterator that only knows how to go
> forward; you need the node before the splice point (or, for doubly-linked,
> after is fine too). Another reason to use (Lisp/Haskell-style) linked lists
> is that they automatically release nodes as you iterate unless you keep a
> reference to the head, but that’s clumsy to do with Python-style APIs. And
> so on.
>
>
>

-- 
Christopher Barker, PhD

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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Andrew Barnert via Python-ideas
On Apr 29, 2020, at 08:33, Christopher Barker  wrote:
> 
> I've wondered about Linked Lists for a while, but while there are many 
> versions on PyPi, I can't find one that seems to be mature and maintained. 
> Which seems to indicate that there isn't much demand for them.

I think there’s lots of demand for them, but there are so many different 
variants that can’t substitute for each other (try taking any nontrivial sample 
code using Haskell’s single-linked, no-handle, immutable tail-sharing list and 
rewriting it with C++’s doubly-linked handled mutable list, or vice-versa), and 
most of the key operations fit so poorly with Python’s sequence/iterable API, 
and they’re all so easy to build, that people just build the one they need 
whenever they need it.

I do have a few different linked lists in my toolbox that have come up often 
enough that I stashed them (an immutable cons, a handled double-linked list, a 
cffi wrapper for a common style of C internally-linked lists, probably others), 
but half the time I reach for one I have to modify it anyway, so I haven’t 
bothered to turn them into a package I just import and use.

And, while I did add the whole (Mutable)Sequence API to each one (because it’s 
convenient for debugging and REPL exploration to be able to list(xs), or to get 
a repr that’s written in terms of a from_iter classmethod so I can eval it 
back, etc.), I usually don’t use that API for anything but debugging. When 
you’re dealing with linked lists, you usually need to deal with the nodes 
directly. For example, one big reason to use linked lists is constant-time 
splicing, but you can’t splice in constant time if all you have is the 
head/handle and/or an opaque iterator that only knows how to go forward; you 
need the node before the splice point (or, for doubly-linked, after is fine 
too). Another reason to use (Lisp/Haskell-style) linked lists is that they 
automatically release nodes as you iterate unless you keep a reference to the 
head, but that’s clumsy to do with Python-style APIs. And so on.

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


[Python-ideas] Re: Adding a "once" function to functools

2020-04-29 Thread Tom Forbes
> Thread 2 wakes up with the lock, calls the function, fills the cache, and 
> releases the lock.


What exactly would the issue be with this:

```
import functools
from threading import Lock

def once(func):
sentinel = object()
cache = sentinel
lock = Lock()

@functools.wraps(func)
def _wrapper():
nonlocal cache, lock, sentinel
if cache is sentinel:
with lock:
if cache is sentinel:
cache = func()
return cache

return _wrapper
```

It ensures it’s invoked once, it’s fast and it doesn’t require acquiring a lock 
needlessly. Always wrapping a lock around a static value to account for a small 
edge case seems redundant, more than “it’s usually not optimal”. It’s never 
optimal: in multi-threaded cases you’re causing needless contention, and in 
single threaded cases all your calls are now slower.

Seems generally more correct, even in single threaded cases, to pay the 
overhead only in the first call if you want `call_once` semantics. Which is why 
you would be using `call_once` in the first place?


> On 29 Apr 2020, at 18:51, Andrew Barnert  wrote:
> 
> On Apr 29, 2020, at 00:34, Tom Forbes  wrote:
>> 
>> It’s not quite that easy, either you needlessly lock all calls or you end 
>> up invoking it twice.
>> 
>> What you want is to acquire a lock if the cache is empty, check if another 
>> thread has filled the cache while you where waiting on the lock, call the 
>> function, fill the cache and return.
> 
> Thread 1 sees the cache is empty, so it acquires the lock, runs the function. 
> 
> Thread 2 sees the cache is empty, so it tries to acquire the cache and blocks.
> 
> Thread 1 finishes the function, fills the cache, and releases the lock.
> 
> Thread 2 wakes up with the lock, calls the function, fills the cache, and 
> releases the lock.
> 
> You’ve now run the function twice instead of once, and the first caller got a 
> different value than the one every subsequent caller can get.
> 
> There are actually plenty of cases where this is acceptable (the function is 
> safe, and idempotent, and while it’s slow it’s not so slow that occasionally 
> running it twice is worse than locking a zillion times)—but in those cases, 
> just not using a lock is even better. In fact, if you can compare-and-swap at 
> the end (which requires a lock to simulate in Python, but it’s a much more 
> granular one than locking over the whole expensive function call), you can 
> even use it in more cases (in particular, where the function isn’t idempotent 
> but you need to value to be).
> 
> This is exactly why users should be encouraged to just lock the whole thing. 
> It’s always correct. It’s usually not optimal, but often good enough. The one 
> really common and simple case where it’s not good enough is single-threaded 
> code. Anything else where you need to optimize, you really do need to 
> understand the pattern you’re trying to optimize for (and the environment(s) 
> you’re running under) and write your own function.
> 
> 
___
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/MHTUCWAKNA72ACADM6N6VNCYRM3IBY7T/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Serhiy Storchaka

29.04.20 17:56, Ram Rachum пише:
Thanks everybody for your answers, and especially Ricky for finding this 
note.


Please not that the optimization mentioned in the comment still keeps 
the linear complexity for these operations. It just reduces the constant 
multiplier.

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


[Python-ideas] Re: zip(x, y, z, strict=True)

2020-04-29 Thread Christopher Barker
On Tue, Apr 28, 2020 at 7:49 AM Brandt Bucher 
wrote:

> With that in mind, I've started drafting one summarizing the discussion
> that took place here, and arguing for the addition of a boolean flag to the
> `zip` constructor.


Since you've gotten a few -1s, I'll add a +1 -- for reasons posted here
before, a flag is far more likely to actually get used :-) -- but that's
why we need a PEP.

However, I urge you to consider a trinary switch instead:

"shortest" (default) |  "longest" | "equal"

Yes, we already have zip_longest, but if we're adding switching behavior to
zip(), it might as well handle all cases -- that seems a cleaner API to me.

-CHB


-- 
Christopher Barker, PhD

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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Christopher Barker
On Wed, Apr 29, 2020 at 8:02 AM Ram Rachum  wrote:

> Thanks everybody for your answers, and especially Ricky for finding this
> note.
>

which seems to indicate that if one were to implement this code more
efficiently, it would be considered for inclusion.

I will note that for the most part, the Python specs are for the API, and
do not guarantee particular performance characteristics. Dicts are
efficient because they need to be for reasonable performance of the entire
interpreter, but it isn't part of the Mapping ABC. Is there a single
instance of the SAME ABC being implemented in two ways, with different
performance characteristics?

I've wondered about Linked Lists for a while, but while there are many
versions on PyPi, I can't find one that seems to be mature and maintained.
Which seems to indicate that there isn't much demand for them.

-CHB





> On Wed, Apr 29, 2020 at 2:20 PM Ricky Teachey  wrote:
>
>> I was playing around with deque today, and there were a couple of
>>> operations I wanted to do, that can't really be done efficiently with deque
>>> because of its implementation.
>>>
>>> ...
>>>
>>> What do you think about adding [O(1) insert and remove] this to `deque`?
>>>
>>
>> _collectionsmodule.c has this note, so it sounds like this is intended to
>> be a possibility if there is enough interest:
>>
>> /* insert(), remove(), and delitem() are implemented in terms of rotate()
>>> for simplicity and reasonable performance near the end points.  If for some
>>> reason these methods become popular, it is not hard to re-implement this
>>> using direct data movement (similar to the code used in list slice
>>> assignments) and achieve a performance boost (by moving each pointer only
>>> once instead of twice). */
>>
>>
>>
>> https://github.com/python/cpython/blob/d16a1520c2b22c3cbde7547937ba283db3e88ff5/Modules/_collectionsmodule.c#L952-L958
>>
>>
>>
>> ---
>> Ricky.
>>
>> "I've never met a Kentucky man who wasn't either thinking about going
>> home or actually going home." - Happy Chandler
>>
> ___
> 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/JUOQ6DASMKMV52FKIQYAQQ4MJLYBK4LA/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Christopher Barker, PhD

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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Ram Rachum
Thanks everybody for your answers, and especially Ricky for finding this
note.

On Wed, Apr 29, 2020 at 2:20 PM Ricky Teachey  wrote:

> I was playing around with deque today, and there were a couple of
>> operations I wanted to do, that can't really be done efficiently with deque
>> because of its implementation.
>>
>> ...
>>
>> What do you think about adding [O(1) insert and remove] this to `deque`?
>>
>
> _collectionsmodule.c has this note, so it sounds like this is intended to
> be a possibility if there is enough interest:
>
> /* insert(), remove(), and delitem() are implemented in terms of rotate()
>> for simplicity and reasonable performance near the end points.  If for some
>> reason these methods become popular, it is not hard to re-implement this
>> using direct data movement (similar to the code used in list slice
>> assignments) and achieve a performance boost (by moving each pointer only
>> once instead of twice). */
>
>
>
> https://github.com/python/cpython/blob/d16a1520c2b22c3cbde7547937ba283db3e88ff5/Modules/_collectionsmodule.c#L952-L958
>
>
>
> ---
> Ricky.
>
> "I've never met a Kentucky man who wasn't either thinking about going home
> or actually going home." - Happy Chandler
>
___
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/JUOQ6DASMKMV52FKIQYAQQ4MJLYBK4LA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Barry Scott


> On 29 Apr 2020, at 12:36, remi.lape...@henki.fr wrote:
> 
> Also, removing an element from a doubly-linked list is not a O(1) operation, 
> it's O(n). It's O(1) once you have a pointer to the element but you have to 
> iterate over the list to get it and that would take O(n) operations, so 
> making deque a doubly-linked list would not be faster anyway.

In the cases where a DLL is the reasonable design choice remove is O(1) in my 
experience.
The reason is that you have the element in your hand by other means then 
scanning the DLL.

This was a heavily used pattern when I worked on DEC VMS device drivers.
Async I/O requests could be cancelled and removed from the list of outstanding
I/O for a device in O(1). Indeed the VAX had instructions to implement this 
pattern
in hardware.

Barry



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


[Python-ideas] Re: zip(x, y, z, strict=True)

2020-04-29 Thread Barry Scott



> On 28 Apr 2020, at 16:12, Rhodri James  wrote:
> 
> On 28/04/2020 15:46, Brandt Bucher wrote:
>> Thanks for weighing in, everybody.
>> Over the course of the last week, it has become surprisingly clear that this 
>> change is controversial enough to require a PEP.
>> With that in mind, I've started drafting one summarizing the discussion that 
>> took place here, and arguing for the addition of a boolean flag to the `zip` 
>> constructor. Antoine Pitrou has agreed to sponsor, and I've chatted with 
>> another core developer who shares my view that such a flag wouldn't violate 
>> Python's existing design philosophies.
>> I'll be watching this thread, and should have a draft posted to the list for 
>> feedback this week.
> 
> -1 on the flag.  I'd be happy to have a separate zip_strict() (however you 
> spell it), but behaviour switches just smell wrong.


Also -1 on the flag.

1. A new name can be searched for.
2. You do not force a if on the flag for every single call to zip.

Barry


> 
> -- 
> Rhodri James *-* Kynesim Ltd
> ___
> 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/BZUJUTAVOHJEUZ6QEIRZWZHKCRXE6AAS/
> 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/XEQIZHKWNKFDWQCBK4FAEGP2TEMDTMMP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Steven D'Aprano
On Wed, Apr 29, 2020 at 01:42:05PM +0300, Ram Rachum wrote:

> I was iterating through items of a deque, and in some cases I wanted to
> delete an item that I've found.

Deleting items from a container while iterating through it is an 
anti-pattern, easy to get wrong, prone to bugs, and in a high-level 
language like Python, very likely to be slower than creating a new 
container and copying it across.

I haven't tried it with dequeues, but some versions ago I tried to find 
the cross-over point where it was more efficient to delete items from a 
list in place, instead of copying:

mylist[:] = [x from x in mylist if not condition]

versus:

for i in range(len(mylist)-1, -1, -1):
if condition:
del mylist[i]

My reasoning was that *eventually* for a big enough list, the cost of 
making the copy would outweigh the cost of moving the items. I don't 
know if my reasoning was valid or not, but I was unable to find any such 
cutoff on my computer, up to hundreds of millions of items. Deletion was 
always slower.

But, if you insist on doing it, dequeues support deletion.


> As far as I understand, this is an
> operation that should be O(1) in a linked list, but Python only provides an
> O(N) way to do that, which is `del d[i]`.

Dequeues are not linked lists. I don't believe that they are implemented 
as linked lists, and I know that they certainly do not offer a linked 
list API.

You could try rotating the dequeue, popping it, then rotating it back.
That might be faster, if rotation is fast.

But if you are only deleting one or two items, is that deletion a 
bottle-neck in your code?


> The same can be said for inserting items in the middle.

If you want to insert and delete items in the middle, you are probably 
better off using a list. Dequeues are explicitly optimised for insertion 
and deletion at the ends, not the middle. It's a tradeoff.

> What do you think about adding this to `deque`?

Not much.

If you have a clever implementation in mind that will make deletion more 
efficient, that's an implementation detail that will depend on (1) 
whether you have someone willing and able to do the work and (2) whether 
or not that implementation will rule out other possible future 
improvements.


> The API will be tricky,
> admittedly, because you'll have to save some kind of reference to a cell in
> the deque.

I think you mean the implementation will be tricky. The API will surely 
be trivial: either `del mydeque[i]`, as now, or `mydequeue.delete(i)`.

If you have some other API in mind, please describe it.


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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread remi . lapeyre
A deque is a data structure that exists outside of Python and the only 
guarantee is that adding an element at the top or the front is O(1). Giving 
more guarantee would force trade-offs and impose them to other implementations. 
If you want fast deletion, you should use another data structure.

Also, removing an element from a doubly-linked list is not a O(1) operation, 
it's O(n). It's O(1) once you have a pointer to the element but you have to 
iterate over the list to get it and that would take O(n) operations, so making 
deque a doubly-linked list would not be faster anyway.

I think the data structure that you are looking for would be a skipped-list, or 
alternatively (but the implementation is more involved) a red-black tree.
___
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/JXI3KKZZBD4ORTBKMZVMC7XNUNIK7DYB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Paul Sokolovsky
Hello,

On Wed, 29 Apr 2020 13:58:15 +0300
Ram Rachum  wrote:

> On Wed, Apr 29, 2020 at 1:54 PM Paul Sokolovsky 
> wrote:
> 
> > If you want a different data structure, [...] implement such a
> > data structure
> >  
> 
> And if I wanted an answer like "it's the way that it is because it's
> the way that it is" I wouldn't be posting on python-ideas.
> 
> Is there a strategic decision to limit deque to certain operations of
> doubly-linked lists and not others? 

Deque is not doubly-linked list, they are completely different data
structures. Even if a particular Python implementation uses
doubly-linked list as an internal implementation strategy. There're
other Python implementations which realize deque in other ways, which
guarantee performance only for operations defined for deque and not
for any other data structure. (E.g., an obvious implementation is an
array with head/tail pointers).

> That would make sense. Is that
> decision written somewhere with the rationale behind it? That would
> be interesting to read.


-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/ZBZ7TPNRCIQKBDDJ4AJQ7PPBTQ5FT4G2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Ricky Teachey
>
> I was playing around with deque today, and there were a couple of
> operations I wanted to do, that can't really be done efficiently with deque
> because of its implementation.
>
> ...
>
> What do you think about adding [O(1) insert and remove] this to `deque`?
>

_collectionsmodule.c has this note, so it sounds like this is intended to
be a possibility if there is enough interest:

/* insert(), remove(), and delitem() are implemented in terms of rotate()
> for simplicity and reasonable performance near the end points.  If for some
> reason these methods become popular, it is not hard to re-implement this
> using direct data movement (similar to the code used in list slice
> assignments) and achieve a performance boost (by moving each pointer only
> once instead of twice). */


https://github.com/python/cpython/blob/d16a1520c2b22c3cbde7547937ba283db3e88ff5/Modules/_collectionsmodule.c#L952-L958



---
Ricky.

"I've never met a Kentucky man who wasn't either thinking about going home
or actually going home." - Happy Chandler
___
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/M645KVEY6RUQG6SXQ3KTMY6GUPWVHYQN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Chris Angelico
On Wed, Apr 29, 2020 at 9:15 PM Chris Angelico  wrote:
> I'm not seeing any evidence that this is a doubly-linked list. It
> might happen to be implemented using one in current versions of
> CPython, but that's not mandated anywhere.

(And it's not a pure DLL - it's a DLL of blocks of 64 elements apiece.
I'm not sure if that's significant or not.)

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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Chris Angelico
On Wed, Apr 29, 2020 at 9:01 PM Ram Rachum  wrote:
> Is there a strategic decision to limit deque to certain operations of 
> doubly-linked lists and not others? That would make sense. Is that decision 
> written somewhere with the rationale behind it? That would be interesting to 
> read.
>

"""Deques are a generalization of stacks and queues (the name is
pronounced “deck” and is short for “double-ended queue”). Deques
support thread-safe, memory efficient appends and pops from either
side of the deque with approximately the same O(1) performance in
either direction."""

I'm not seeing any evidence that this is a doubly-linked list. It
might happen to be implemented using one in current versions of
CPython, but that's not mandated anywhere.

Is there a particular reason to mandate this for all Pythons for all
time? As Paul says, you can always implement your own doubly linked
list.

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


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Ram Rachum
On Wed, Apr 29, 2020 at 1:54 PM Paul Sokolovsky  wrote:

> If you want a different data structure, [...] implement such a
> data structure
>

And if I wanted an answer like "it's the way that it is because it's the
way that it is" I wouldn't be posting on python-ideas.

Is there a strategic decision to limit deque to certain operations of
doubly-linked lists and not others? That would make sense. Is that decision
written somewhere with the rationale behind it? That would be interesting
to read.
___
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/X2LDG4JMVFACX3KJBX5BLFVFNTIQ3TUT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: deque: Allow efficient operations

2020-04-29 Thread Paul Sokolovsky
Hello,

On Wed, 29 Apr 2020 13:42:05 +0300
Ram Rachum  wrote:

> I was playing around with deque today, and there were a couple of
> operations I wanted to do, that can't really be done efficiently with
> deque because of its implementation.
> 
> I was iterating through items of a deque, and in some cases I wanted
> to delete an item that I've found. As far as I understand, this is an
> operation that should be O(1) in a linked list, but Python only
> provides an O(N) way to do that, which is `del d[i]`.
> 
> The same can be said for inserting items in the middle.
> 
> What do you think about adding this to `deque`? The API will be
> tricky, admittedly, because you'll have to save some kind of
> reference to a cell in the deque.

Deque is a data structure which allows efficient insertion/deletion from
2 ends of the structure, period.

If you want a different data structure, like linked list, or
doubly-linked list, with different set of operations, implement such a
data structure (it's trivial, and being done by other people all the
time).

> Thanks,
> Ram.



-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
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/MPWX45VK5SAG4JMGQ5F73MRLDWDMKNJC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] deque: Allow efficient operations

2020-04-29 Thread Ram Rachum
I was playing around with deque today, and there were a couple of
operations I wanted to do, that can't really be done efficiently with deque
because of its implementation.

I was iterating through items of a deque, and in some cases I wanted to
delete an item that I've found. As far as I understand, this is an
operation that should be O(1) in a linked list, but Python only provides an
O(N) way to do that, which is `del d[i]`.

The same can be said for inserting items in the middle.

What do you think about adding this to `deque`? The API will be tricky,
admittedly, because you'll have to save some kind of reference to a cell in
the deque.


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


[Python-ideas] Re: Adding a "once" function to functools

2020-04-29 Thread Rhodri James

On 28/04/2020 23:58, Andrew Barnert via Python-ideas wrote:

Really, we either need descriptors that can somehow work for globals
and class attributes (which is probably not solveable), or some brand
new language semantics that aren’t built on what’s already there. The
latter sounds like probably way more work than this feature deserves,
but maybe the experience of Swift argues otherwise.


Or you can do it up front, once you have the information to do it with. 
 There aren't that many occasions when lazy evaluation actually wins 
you anything much; basically when you have moderately expensive 
information that you may not need at all but will use a lot if you do 
need it.


--
Rhodri James *-* Kynesim Ltd
___
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/3ATLHCE557B4UA2OUXBAZZSZ5SCJFCY5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding a "once" function to functools

2020-04-29 Thread Tom Forbes
What you want is to acquire a lock if the cache is empty, check if another 
thread has filled the cache while you where waiting on the lock, call the 
function, fill the cache and return.

I don’t see how you could implement that with two independent decorators 
without locking all accesses (before `once`) or having the chance that it’s 
called more than once (after `once`).

Tom

> On 29 Apr 2020, at 08:15, Andrew Barnert via Python-ideas 
>  wrote:
> 
> On Apr 28, 2020, at 16:25, Steven D'Aprano  wrote:
>> 
>> On Tue, Apr 28, 2020 at 11:45:49AM -0700, Raymond Hettinger wrote:
>> 
>>> It seems like you would get just about everything you want with one line:
>>> 
>>>once = lru_cache(maxsize=None)
>> 
>> But is it thread-safe?
> 
> You can add thread safety the same way as any other function:
> 
>@synchronized
>@once
>def spam():
>return 42 in a slow and non-thread-safe and non-idempotent way and 
> also launch the missiles the second time we’re called
> 
> Or wrap a with lock: around the code that calls it, or whatever.
> 
> Not all uses of once require thread safety. For the really obvious example, 
> imagine you’re sharing a singleton between coroutines instead of threads. And 
> if people are really concerned with the overhead of lru_cache(maxsize=None), 
> the overhead of locking every time you access the value is probably even less 
> acceptable when unnecessary.
> 
> So, I think it makes sense to leave it up to the user (but to explain the 
> issue in the docs). Or maybe we could add a threading.once (and 
> asyncio.once?) as well as functools.once?
> 
> 
> ___
> 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/RSJLUF4R6TM3HSILZYWGB366WUHQT755/
> 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/LZPL7SIIEDUZW7P6CTRYJCXZVQOJJL24/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding a "once" function to functools

2020-04-29 Thread Andrew Barnert via Python-ideas
On Apr 28, 2020, at 16:25, Steven D'Aprano  wrote:
> 
> On Tue, Apr 28, 2020 at 11:45:49AM -0700, Raymond Hettinger wrote:
> 
>> It seems like you would get just about everything you want with one line:
>> 
>> once = lru_cache(maxsize=None)
> 
> But is it thread-safe?

You can add thread safety the same way as any other function:

@synchronized
@once
def spam():
return 42 in a slow and non-thread-safe and non-idempotent way and also 
launch the missiles the second time we’re called

Or wrap a with lock: around the code that calls it, or whatever.

Not all uses of once require thread safety. For the really obvious example, 
imagine you’re sharing a singleton between coroutines instead of threads. And 
if people are really concerned with the overhead of lru_cache(maxsize=None), 
the overhead of locking every time you access the value is probably even less 
acceptable when unnecessary.

So, I think it makes sense to leave it up to the user (but to explain the issue 
in the docs). Or maybe we could add a threading.once (and asyncio.once?) as 
well as functools.once?


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