On 21Mar2020 12:15, Stephen J. Turnbull <turnbull.stephen...@u.tsukuba.ac.jp>
wrote:
Steven D'Aprano writes:
> So each loop will need its own context manager, meaning its own
> class. The *actual* invariant will be buried far away, in a CM
> class, rather than right there next to the loop.
I see no reason why that will be true for many invariants. The
context manager class would be simple, in principle: __entry__,
__exit__, and invariants. The expression in the with statement would
be a constructor.
> Worse: the condition will likely need to be written as a string, or a
> lambda, in order to delay evaluation.
Or a local def. This is correct, as far as I know. I would expect
the example from Wikipedia
(https://en.wikipedia.org/wiki/Loop_invariant#Informal_example)
translated to Python would be written in the "condition as string"
implementation as
def max(n, a):
m = a[0]
# m equals the maximum value in a[0...0]
i = 1
while (i != n) {
with Invariants('m == max(a[0:i])'):
[... and hacks with globals, locals ...]
Twio things:
1:
Might I point out to everyone the icontract PyPI module (maybe I've
missing this in the discussion?), which does all this kind of thing for
functions (programming by contract, thus the function level focus).
The important point here is that it uses lambda to express the
assertions:
@require(lambda foo: foo > 1)
def func(foo):
...
There's a post condition decorator, and invariants etc. It does funky
function signature inspection to match up the lambda parameter names to
the function paraemeter names. very cool.
2:
Anyway, a salient point here is that you can write _arbitrary_
invariants as context managers using closures to get the locals/globals
stuff (icontract isn't doing this, but it is heavy on the lambdas). For
example, maybe:
from ... import invariant_cm
def max(n, a):
m = a[0]
# m equals the maximum value in a[0...0]
i = 1
while (i != n) {
with invariant_cm(lambda: m == max(a[0:i])):
where invariant_cm came out of your library for checking before and
after the suite. The closure gets you the locals/globals directly
without cumbersomeness.
Cheers,
Cameron Simpson <c...@cskk.id.au>
_______________________________________________
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/K5A6SMIU6QCGQIAADTR2SQHKO5YX47LN/
Code of Conduct: http://python.org/psf/codeofconduct/