Re: [Python-ideas] Upgrade to Mailman 3

2018-09-30 Thread Wes Turner
re: message URL in mm3 footers (after sig dashes: '\n--\n')

"This list will soon be migrating to Mailman 3"
https://mail.python.org/mm3/archives/list/distutils-...@python.org/thread/IHWUGVND3FU2UH3GEC2GYOSOJJMKLO5H/

On Sunday, September 30, 2018, James Lu  wrote:

> It has a nice GUI for people who spectate a discussion to read emails
> without having to subscribe to the list.
>
> http://docs.mailman3.org/en/latest/migration.html
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Renaming icontract to pcontract

2018-09-30 Thread Marko Ristin-Kaufmann
Hi,
I'd like to rename icontract into pcontract to avoid name conflict with
java's icontract library.

Do you have any better suggestion?

Thanks!
Marko
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Transpiling contracts

2018-09-30 Thread Marko Ristin-Kaufmann
Hi James,

Regarding the “transpile into Python” syntax with with statements: Can I
> see an example of this syntax when used in pathlib? I’m a bit worried this
> syntax is too long and “in the way”, unlike decorators which are before the
> function body. Or do you mean that both MockP and your syntax should be
> supported?
>
> Would
>
> with requiring: assert arg1 < arg2, “message”
>
> Be the code you type or the code that’s actually run?
>

That's the code you would type. Let me make a full example (I'm omitting
"with contracts" since we actually don't need it).

You would read/write this:
def some_func(arg1: List[int])->int:
  with requiring:
assert len(arg1) > 3, "some description"

  with oldie as O, resultie as result, ensuring:
if SLOW:
  O.var1 = sum(arg1)
  assert result > sum(arg1) > O.var1

assert len(result) > 5

This would run:
@requires(lambda P: len(P.arg1) > 3, "some description")
@snapshot(lambda P, var1: sum(P.arg1), enabled=SLOW)
@ensures(lambda O, P, result: result > sum(arg1) > O.var1, enabled=SLOW)
@ensures(lambda result: len(result) > 5)

I omitted in the example how to specify a custom exception to avoid
confusion.

If we decide that transpiler is the way to go, I'd say it's easier to just
stick with lambdas and allow no mock-based approach in transpilation.

Cheers,
Marko


>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] "old" values in postconditions

2018-09-30 Thread Marko Ristin-Kaufmann
Hi James,
I agree. Having a snapshot decorator per variable also has the advantage
that we can add parameters to the decorator (e.g., snapshots also need
"enabled" and "description" argument).

How should we distinguish the two approaches? (I suppose you would also
apply them to requests, ensures and invariant decorator, right?) Is there a
terminology? Lambda-based conditions might be the name for the conventional
approach with @requests(lambda P: ...). What should we term the approach
you proposed?

Re naming: @requests(lambda P: P.arg1 < P.arg2) and @requests_that(P.arg1 <
P.arg2)?

Le dim. 30 sept. 2018 à 22:07, James Lu  a écrit :

> Hi Marko,
>
> I just found the time to reply to these.
> > I reread the proposal with MockP. I still don't get the details, but if
> I think I understand the basic idea. You put a placeholder and whenever one
> of its methods is called (including dunders), you record it and finally
> assemble an AST and compile a lambda function to be executed at actual call
> later.
> Precisely.
>
>
> > But that would still fail if you want to have:
> > @snapshot(var1=some_func(MockP.arg1, MockP.arg2))
> > , right? Or there is a way to record that?
>
> This would still fail. You would record it like this:
> @snapshot(var1=thunk(some_func)(MockP.arg1, MockP.arg2))
>
> thunk stores the function for later and produces another MockP object that
> listens for __call__.
>
> By the way, MockP is the class while P is a virgin instance of MockP.
> MockP instances are immutable, so any operation on a MockP instance creates
> a new object or MockP instance.
>
> I’m also beginning to lean towards
> @snapshot(var1=...)
> @snapshot(var2=...)
>
> I suspect this would deal better with VCS.
>
> This syntax does have a a nice visual alignment. I’m not entirely sure
> what kind of indentation PEP 8 recommends and editors give, so the point
> may be moot if the natural indentation also gives the same visual alignment.
>
> Though both should be supported so the best syntax may win.
>
> James Lu
>
>
> > On Sep 29, 2018, at 3:22 PM, Marko Ristin-Kaufmann <
> marko.ris...@gmail.com> wrote:
> >
> > I reread the proposal with MockP. I still don't get the details, but if
> I think I understand the basic idea. You put a placeholder and whenever one
> of its methods is called (including dunders), you record it and finally
> assemble an AST and compile a lambda function to be executed at actual call
> later.
> >
> > But that would still fail if you want to have:
> > @snapshot(var1=some_func(MockP.arg1, MockP.arg2))
> > , right? Or there is a way to record that?
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] "old" values in postconditions

2018-09-30 Thread Marko Ristin-Kaufmann
Hi James,
Sure, let's do that! I'm fine with emails, too. I needed only a bit of
structure since we lumped so many issues together, but maybe it's just my
OCD :)

Le lun. 1 oct. 2018 à 04:05, James Lu  a écrit :

> Hi Marko,
>
> Regarding switching over to GitHub issues:
> * I copy-pasted the MockP original code to GitHub issues.
> * There's a clunky way to view the discussion at
> https://mail.python.org/pipermail/python-ideas/2018-September/subject.html#start
> .
> * The less clunky way to view the discussion is to subscribe to the
> mailing list and use Gmail to move all the messages from python-ideas to
> python ideas list and all the messages from the discussions we have to a
> "contracts" label and view the discussion with your email client.
> * A week earlier I didn't think I'd be saying this, but I like email for
> discussion better. It works on mobile and I can send messages offline, and
> I send 90% of my messages on my phone and when I'm offline. Unless you know
> an alternative (WhatsApp, maybe?) that fits my use cases off the top of
> your head, I think we should stick to email.
> * My proposal: We split the discussion into a new email thread, we keep
> the latest agreed upon proposal on GitHub issues.
>
> On Sun, Sep 30, 2018 at 4:32 PM Marko Ristin-Kaufmann <
> marko.ris...@gmail.com> wrote:
>
>> Hi James,
>> (I'm just about to go to sleep, so I'll answer the other messages
>> tomorrow.)
>>
>> Should we keep some kind of document to keep track of all the different
>>> proposals? I’m thinking an editable document like HackMD where we can label
>>> all the different ideas to keep them straight in our head.
>>>
>>
>> I thought github issues would be a suitable place for that:
>> https://github.com/Parquery/icontract/issues
>>
>> It reads a bit easier as a discussion rather than a single document -- if
>> anybody else needs to follow. What do you think?
>>
>> On Sun, 30 Sep 2018 at 22:07, James Lu  wrote:
>>
>>> Hi Marko,
>>>
>>> Going back to your proposal on repeating lambda P as a convention.
>>>
>>> I do find
>>>
>>> @snapshot(some_identifier=P -> P.self(P.arg1),
>>> some_identifier2=P -> P.arg1 + P.arg2)
>>>
>>> acceptable.
>>>
>>> Should we keep some kind of document to keep track of all the different
>>> proposals? I’m thinking an editable document like HackMD where we can label
>>> all the different ideas to keep them straight in our head.
>>>
>>> James Lu
>>
>>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] "old" values in postconditions

2018-09-30 Thread James Lu
Hi Marko,

Regarding switching over to GitHub issues:
* I copy-pasted the MockP original code to GitHub issues.
* There's a clunky way to view the discussion at
https://mail.python.org/pipermail/python-ideas/2018-September/subject.html#start
.
* The less clunky way to view the discussion is to subscribe to the mailing
list and use Gmail to move all the messages from python-ideas to python
ideas list and all the messages from the discussions we have to a
"contracts" label and view the discussion with your email client.
* A week earlier I didn't think I'd be saying this, but I like email for
discussion better. It works on mobile and I can send messages offline, and
I send 90% of my messages on my phone and when I'm offline. Unless you know
an alternative (WhatsApp, maybe?) that fits my use cases off the top of
your head, I think we should stick to email.
* My proposal: We split the discussion into a new email thread, we keep the
latest agreed upon proposal on GitHub issues.

On Sun, Sep 30, 2018 at 4:32 PM Marko Ristin-Kaufmann <
marko.ris...@gmail.com> wrote:

> Hi James,
> (I'm just about to go to sleep, so I'll answer the other messages
> tomorrow.)
>
> Should we keep some kind of document to keep track of all the different
>> proposals? I’m thinking an editable document like HackMD where we can label
>> all the different ideas to keep them straight in our head.
>>
>
> I thought github issues would be a suitable place for that:
> https://github.com/Parquery/icontract/issues
>
> It reads a bit easier as a discussion rather than a single document -- if
> anybody else needs to follow. What do you think?
>
> On Sun, 30 Sep 2018 at 22:07, James Lu  wrote:
>
>> Hi Marko,
>>
>> Going back to your proposal on repeating lambda P as a convention.
>>
>> I do find
>>
>> @snapshot(some_identifier=P -> P.self(P.arg1),
>> some_identifier2=P -> P.arg1 + P.arg2)
>>
>> acceptable.
>>
>> Should we keep some kind of document to keep track of all the different
>> proposals? I’m thinking an editable document like HackMD where we can label
>> all the different ideas to keep them straight in our head.
>>
>> James Lu
>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Upgrade to Mailman 3

2018-09-30 Thread James Lu
It has a nice GUI for people who spectate a discussion to read emails
without having to subscribe to the list.

http://docs.mailman3.org/en/latest/migration.html
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Chris Angelico
On Mon, Oct 1, 2018 at 8:53 AM Oscar Benjamin
 wrote:
>
> On Sun, 30 Sep 2018 at 02:01, Steven D'Aprano  wrote:
> >
> > On Sat, Sep 29, 2018 at 09:43:42PM +0100, Oscar Benjamin wrote:
> > > On Sat, 29 Sep 2018 at 19:38, Steve Barnes  wrote:
> >
> > > > > I converted to int because I needed a whole number, this was intended 
> > > > > to
> > > > represent some more complex process where a value is converted to a
> > > > whole number down in the depths of the processing.
> > >
> > > Your requirement to have a whole number cannot meaningfully be
> > > satisfied if your input is nan so an exception is the most useful
> > > result.
> >
> > Not to Steve it isn't.
> >
> > Be careful about making value judgements like that: Steve is asking for
> > an integer NAN because for *him* an integer NAN is more useful than an
> > exception. You shouldn't tell him that he is wrong, unless you know his
> > use-case and his code, which you don't.
>
> Then he can catch the exception and do something else. If I called
> int(x) because my subsequent code "needed a whole number" then I would
> definitely not want to end up with a nan. The proposal requested is
> that int(x) could return something other than a well defined integer.
> That would break a lot of code!

At no point was the behaviour of int(x) ever proposed to be changed.
Don't overreact here. The recommended use-case was for a library to
return iNaN instead of None when it is unable to return an actual
value.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Oscar Benjamin
On Sun, 30 Sep 2018 at 02:01, Steven D'Aprano  wrote:
>
> On Sat, Sep 29, 2018 at 09:43:42PM +0100, Oscar Benjamin wrote:
> > On Sat, 29 Sep 2018 at 19:38, Steve Barnes  wrote:
>
> > > > I converted to int because I needed a whole number, this was intended to
> > > represent some more complex process where a value is converted to a
> > > whole number down in the depths of the processing.
> >
> > Your requirement to have a whole number cannot meaningfully be
> > satisfied if your input is nan so an exception is the most useful
> > result.
>
> Not to Steve it isn't.
>
> Be careful about making value judgements like that: Steve is asking for
> an integer NAN because for *him* an integer NAN is more useful than an
> exception. You shouldn't tell him that he is wrong, unless you know his
> use-case and his code, which you don't.

Then he can catch the exception and do something else. If I called
int(x) because my subsequent code "needed a whole number" then I would
definitely not want to end up with a nan. The proposal requested is
that int(x) could return something other than a well defined integer.
That would break a lot of code!

In what way is iNaN superior to a plain nan? In C this sort of thing
makes sense but in Python there's no reason you can't just use
float('nan'). (This was raised by Serhiy earlier in the thread,
resulting in Steve saying that he wants int(float('nan')) to return
iNaN which then results in the quoted context above).

I don't mean to make a judgment about Steve's use-cases: I have read
the messages in this thread and I haven't yet seen a use-case for this
proposal.

--
Oscar
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)

2018-09-30 Thread Eric V. Smith

On 9/30/2018 8:11 AM, Stephen J. Turnbull wrote:

Steven D'Aprano writes:
  > (7) You can't unit test loop invariants

I don't see how a loop invariant can be elegantly specified without
mixing it in to the implementation.  Can you show an example of code
written in a language with support for loop invariants *not* mixed
into the implementation?


I'd be very interested in this, too. Any pointers?

Eric

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Mital Ashok via Python-ideas
As others have said, I do not think directly changing int is a good idea.
It would break so much existing code if an unexpected iNaN appeared.

I also think having a nan-aware subclass should be the other way around. If
you are expecting a nan-aware int, a regular int would work fine. If you
are expecting an int, a nan-aware int might not work. It seems more like
int is a subclass of nan-aware int.

Another idea is having it as a completely different class. int can be made
a virtual subclass of it. This can be implemented in pure Python too.

However, I do not think there is a strong enough use case for this. The
example given for an integer infinity could have it replaced with a float
infinity. And how iNaN would define operations on it can be completely
unexpected. Throwing an error would be more useful in those places, but if
not possible, float('nan'), None or a custom object could be used (which
one used would be documented). Because there would be too much for Python
to "decide" for how iNaNs would work, it should be left up to user code.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] "old" values in postconditions

2018-09-30 Thread Marko Ristin-Kaufmann
Hi James,
(I'm just about to go to sleep, so I'll answer the other messages tomorrow.)

Should we keep some kind of document to keep track of all the different
> proposals? I’m thinking an editable document like HackMD where we can label
> all the different ideas to keep them straight in our head.
>

I thought github issues would be a suitable place for that:
https://github.com/Parquery/icontract/issues

It reads a bit easier as a discussion rather than a single document -- if
anybody else needs to follow. What do you think?

On Sun, 30 Sep 2018 at 22:07, James Lu  wrote:

> Hi Marko,
>
> Going back to your proposal on repeating lambda P as a convention.
>
> I do find
>
> @snapshot(some_identifier=P -> P.self(P.arg1),
> some_identifier2=P -> P.arg1 + P.arg2)
>
> acceptable.
>
> Should we keep some kind of document to keep track of all the different
> proposals? I’m thinking an editable document like HackMD where we can label
> all the different ideas to keep them straight in our head.
>
> James Lu
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] "old" values in postconditions

2018-09-30 Thread James Lu
Hi Marko,

I just found the time to reply to these.
> I reread the proposal with MockP. I still don't get the details, but if I 
> think I understand the basic idea. You put a placeholder and whenever one of 
> its methods is called (including dunders), you record it and finally assemble 
> an AST and compile a lambda function to be executed at actual call later.
Precisely.


> But that would still fail if you want to have:
> @snapshot(var1=some_func(MockP.arg1, MockP.arg2))
> , right? Or there is a way to record that?

This would still fail. You would record it like this:
@snapshot(var1=thunk(some_func)(MockP.arg1, MockP.arg2))

thunk stores the function for later and produces another MockP object that 
listens for __call__.

By the way, MockP is the class while P is a virgin instance of MockP. MockP 
instances are immutable, so any operation on a MockP instance creates a new 
object or MockP instance. 

I’m also beginning to lean towards
@snapshot(var1=...)
@snapshot(var2=...)

I suspect this would deal better with VCS.

This syntax does have a a nice visual alignment. I’m not entirely sure what 
kind of indentation PEP 8 recommends and editors give, so the point may be moot 
if the natural indentation also gives the same visual alignment.

Though both should be supported so the best syntax may win.

James Lu


> On Sep 29, 2018, at 3:22 PM, Marko Ristin-Kaufmann  
> wrote:
> 
> I reread the proposal with MockP. I still don't get the details, but if I 
> think I understand the basic idea. You put a placeholder and whenever one of 
> its methods is called (including dunders), you record it and finally assemble 
> an AST and compile a lambda function to be executed at actual call later.
> 
> But that would still fail if you want to have:
> @snapshot(var1=some_func(MockP.arg1, MockP.arg2))
> , right? Or there is a way to record that?
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] "old" values in postconditions

2018-09-30 Thread James Lu
Hi Marko,

Regarding the “transpile into Python” syntax with with statements: Can I see an 
example of this syntax when used in pathlib? I’m a bit worried this syntax is 
too long and “in the way”, unlike decorators which are before the function 
body. Or do you mean that both MockP and your syntax should be supported?

Would

with requiring: assert arg1 < arg2, “message”

Be the code you type or the code that’s actually run?

James Lu

> On Sep 29, 2018, at 2:56 PM, Marko Ristin-Kaufmann  
> wrote:
> 
> Just
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] "old" values in postconditions

2018-09-30 Thread James Lu
Hi Marko,

> If the documentation is clear, I'd expect the user to be able to distinguish 
> the two. The first approach is shorter, and uses magic, but fails in some 
> rare situations. The other method is more verbose, but always works.
I like this idea. 

James Lu
> On Sep 29, 2018, at 1:36 AM, Marko Ristin-Kaufmann  
> wrote:
> 
> If the documentation is clear, I'd expect the user to be able to distinguish 
> the two. The first approach is shorter, and uses magic, but fails in some 
> rare situations. The other method is more verbose, but always works.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] "old" values in postconditions

2018-09-30 Thread James Lu
Hi Marko,

Going back to your proposal on repeating lambda P as a convention.

I do find 

@snapshot(some_identifier=P -> P.self(P.arg1),
some_identifier2=P -> P.arg1 + P.arg2)

acceptable. 

Should we keep some kind of document to keep track of all the different 
proposals? I’m thinking an editable document like HackMD where we can label all 
the different ideas to keep them straight in our head.

James Lu
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Steve Barnes


On 30/09/2018 16:36, David Mertz wrote:
> On Sun, Sep 30, 2018 at 11:31 AM Steve Barnes  > wrote:
> 
> No complex can be converted to float without accessing either the real
> or imag component.
> 
> 
> Sure. Not in Python 3.7.  But mathematically, it seems really 
> straightforward to say that Complex numbers that lie on the Real line 
> (i.e. imaginary part is zero) map in an obvious way to Real numbers.
> 
> I haven't done an inventory, but I'd guess most—but not all—other PLs do 
> the same thing Python does.
> 
Personally I agree that float(2.0+0j) should possibly be a valid value 
(2.0) but there is the complication, as always, of how near zero is 
zero. But that is a battle for another time.

-- 
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect 
those of my employer.

---
This email has been checked for viruses by AVG.
https://www.avg.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
On Sun, Sep 30, 2018 at 11:35 AM Chris Angelico  wrote:

> On Mon, Oct 1, 2018 at 1:32 AM Steve Barnes 
> wrote:
> > No complex can be converted to float without accessing either the real
> > or imag component.
> Or taking its absolute value, which will return nan if either part is nan.
>

Well, various other operations as well as abs().  Anything that reduces a
complex to a float already... I guess you could argue that behind the
scenest hese functions all access .real and/or .imag.

>>> float(abs(1+1j))
1.4142135623730951
>>> float(cmath.phase(1+1j))
0.7853981633974483
>>> float(cmath.isfinite(1+1j))
1.0



-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
On Sun, Sep 30, 2018 at 11:31 AM Steve Barnes 
wrote:

> No complex can be converted to float without accessing either the real
> or imag component.
>

Sure. Not in Python 3.7.  But mathematically, it seems really
straightforward to say that Complex numbers that lie on the Real line (i.e.
imaginary part is zero) map in an obvious way to Real numbers.

I haven't done an inventory, but I'd guess most—but not all—other PLs do
the same thing Python does.

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Chris Angelico
On Mon, Oct 1, 2018 at 1:32 AM Steve Barnes  wrote:
>
> No complex can be converted to float without accessing either the real
> or imag component.
>

Or taking its absolute value, which will return nan if either part is nan.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Why is design-by-contracts not widely adopted?

2018-09-30 Thread Steven D'Aprano
On Sun, Sep 30, 2018 at 10:29:50AM -0400, David Mertz wrote:

> I think Steven's is backwards in its own way.
> 
>- Contracts test the space of arguments *actually used during testing
>period* (or during initial production if the performance hit is
>acceptable).
>- Unit tests test the space of arguments *thought of by the developers*.
> 
> *A priori,* either one of those can cover cases not addressed by the
> other.

Fair point.

But given that in general unit tests tend to only exercise a handful of 
values (have a look at the tests in the Python stdlib) I think it is 
fair to say that in practice unit tests typically do not have anywhere 
near the coverage of live data used during alpha and beta testing.


> If unit tests use the hypothesis library or similar approaches,
> unit tests might very well examine arguments unlikely to be encountered in
> real-world (or test phase) use... 

Indeed.

We can consider all of these things as complementary:

- doctests give us confidence that the documentation hasn't rotted;

- unit tests give us confidence that corner cases are tested;

- contracts give us confidence that regular and common cases are tested;

- regression tests give us confidence that bugs aren't re-introduced;

- smoke tests give us confidence that the software at least will run;

- static type checking allows us to drop type checks from our unit 
  tests and contracts;

but of course there can be overlap. And that's perfectly fine.


[...]
> - Half of the checks are very far away, in a separate file, assuming
> >   I even remembered or bothered to write the test.
> >
> 
> To me, this is the GREATEST VIRTUE of unit tests over DbC.  It puts the
> tests far away where they don't distract from reading and understanding the
> function itself.  I rarely want my checks proximate since I wear a very
> different hat when thinking about checks than when writing functionality
> (ideally, a lot of the time, I wear the unit test hat *before* I write the
> implementation; TDD is usually good practice).

I'm curious. When you write a function or method, do you include input 
checks? Here's an example from the Python stdlib (docstring removed for 
brevity):

# bisect.py
def insort_right(a, x, lo=0, hi=None):
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if x < a[mid]: hi = mid
else: lo = mid+1
a.insert(lo, x)

Do you consider that check for lo < 0 to be disruptive? How would you 
put that in a unit test?

That check is effectively a pre-condition. Putting aside the question of 
which exception should be raised (AssertionError or ValueError), we 
could re-write that as a contract:

def insort_right(a, x, lo=0, hi=None):
require:
lo >= 0
# implementation follows, as above
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if x < a[mid]: hi = mid
else: lo = mid+1
a.insert(lo, x)

Do you consider that precondition check for lo >= to be disruptive? More 
or less disruptive than when it was in the body of the function 
implementation?



> > - The post-conditions aren't checked unless I run my test suite, and
> >   then they only check the canned input in the test suite.
> >
> 
> Yes, this is a great advantage of unit tests.  No cost until you explicitly
> run them.

If you're worried about the cost of verifying your program does the 
right thing during testing and development, I think you're doing 
something wrong :-)

If there are specific functions/classes where the tests are insanely 
expensive, that's one thing. I have some code that wants to verify that 
a number is prime as part of an informal post-condition check, but if it 
is a *big* prime that check is too costly so I skip it.

But in general, if I'm testing or under active development, what do I 
care if the program takes 3 seconds to run instead of 2.5 seconds? 
Either way, its finished by the time I come back from making my coffee
:-)

But more seriously, fine, if a particular contract is too expensive to 
run, disable it or remove it and add some unit tests. And then your 
devs will complain that the unit tests are too slow, and stop running 
them, and that's why we can't have nice things... *wink*


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Steve Barnes


On 30/09/2018 16:26, David Mertz wrote:
> On Sun, Sep 30, 2018 at 11:17 AM Steve Barnes  > wrote:
> 
> Note that my statements above had a single = i.e.
> float(NaNAwareInt('nan')) produces float('nan'), etc., as does:
> 
> In [42]: nan = decimal.Decimal('nan')
> In [43]: decimal.Decimal(nan)
> Out[43]: Decimal('NaN')
> In [44]: float(nan)
> Out[44]: nan
> 
> 
> I think this explanation is still a little confusing.  I take it what 
> you're getting at is that a "NaN" of any particular type (float, 
> Decimal, complex, NanAwareInt) should be a perfectly good initializer to 
> create a NaN of a different type using its constructor.
> 
> I think that is sensible (not sure about complex).  Currently we have:
> 
>  >>> complex(nan)
> (nan+0j)
>  >>> float(complex('nan'))
> Traceback (most recent call last):
>    File "", line 1, in 
>      float(complex('nan'))
> TypeError: can't convert complex to float
> 
>  >>> complex(float('nan'))
> (nan+0j)
>  >>> float(complex('nan'))
> Traceback (most recent call last):
>    File "", line 1, in 
>      float(complex('nan'))
> TypeError: can't convert complex to float
> 
>  >>> from decimal import Decimal
>  >>> Decimal('nan')
> Decimal('NaN')
>  >>> float(Decimal('nan'))
> nan
>  >>> Decimal(float('nan'))
> Decimal('NaN')
>  >>> complex(Decimal('nan'))
> (nan+0j)
>  >>> Decimal(complex('nan'))
> Traceback (most recent call last):
>    File "", line 1, in 
>      Decimal(complex('nan'))
> TypeError: conversion from complex to Decimal is not supported
> 
> 
> I don't think we can change the "cast-from-complex" behavior... even 
> though I think it maybe should have been different from the start.
> 
No complex can be converted to float without accessing either the real 
or imag component.

In [51]: cn=complex(4, float('nan'))

In [52]: cn
Out[52]: (4+nanj)

In [53]: cn.real
Out[53]: 4.0

In [54]: cn.imag
Out[54]: nan

In [55]: float(cn.imag)
Out[55]: nan

-- 
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect 
those of my employer.

---
This email has been checked for viruses by AVG.
https://www.avg.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
On Sun, Sep 30, 2018 at 11:17 AM Steve Barnes 
wrote:

> Note that my statements above had a single = i.e.
> float(NaNAwareInt('nan')) produces float('nan'), etc., as does:
>
> In [42]: nan = decimal.Decimal('nan')
> In [43]: decimal.Decimal(nan)
> Out[43]: Decimal('NaN')
> In [44]: float(nan)
> Out[44]: nan
>

I think this explanation is still a little confusing.  I take it what
you're getting at is that a "NaN" of any particular type (float, Decimal,
complex, NanAwareInt) should be a perfectly good initializer to create a
NaN of a different type using its constructor.

I think that is sensible (not sure about complex).  Currently we have:

>>> complex(nan)
(nan+0j)
>>> float(complex('nan'))
Traceback (most recent call last):
  File "", line 1, in 
float(complex('nan'))
TypeError: can't convert complex to float

>>> complex(float('nan'))
(nan+0j)
>>> float(complex('nan'))
Traceback (most recent call last):
  File "", line 1, in 
float(complex('nan'))
TypeError: can't convert complex to float

>>> from decimal import Decimal
>>> Decimal('nan')
Decimal('NaN')
>>> float(Decimal('nan'))
nan
>>> Decimal(float('nan'))
Decimal('NaN')
>>> complex(Decimal('nan'))
(nan+0j)
>>> Decimal(complex('nan'))
Traceback (most recent call last):
  File "", line 1, in 
Decimal(complex('nan'))
TypeError: conversion from complex to Decimal is not supported


I don't think we can change the "cast-from-complex" behavior... even though
I think it maybe should have been different from the start.

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Steve Barnes


On 30/09/2018 16:13, David Mertz wrote:
> On Sun, Sep 30, 2018 at 11:01 AM Steve Barnes  > wrote:
> 
> Adding inf & -inf would be nice but to do so we would need a better
> name
> than NaNAwareInt.
> 
> 
> My placeholder name is deliberately awkward.  I think it gestures at the 
> concept for discussion purposes though.
> 
> It would also be nice if Decimal(NaNAwareInt('nan')) = Decimal('NaN'),
> float(NaNAwareInt('nan')) = float('nan'), etc.
> 
> 
> This seems like bad behavior given (per IEEE-754 spec):
> 
>  >>> float('nan') == float('nan')
> False
>  >>> nan = float('nan')
>  >>> nan == nan
> False
> 
> -- 
> Keeping medicines from the bloodstreams of the sick; food
> from the bellies of the hungry; books from the hands of the
> uneducated; technology from the underdeveloped; and putting
> advocates of freedom in prisons.  Intellectual property is
> to the 21st century what the slave trade was to the 16th.
David,

Note that my statements above had a single = i.e. 
float(NaNAwareInt('nan')) produces float('nan'), etc., as does:

In [42]: nan = decimal.Decimal('nan')

In [43]: decimal.Decimal(nan)
Out[43]: Decimal('NaN')

In [44]: float(nan)
Out[44]: nan

and vice-versa.

-- 
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect 
those of my employer.

---
This email has been checked for viruses by AVG.
https://www.avg.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
On Sun, Sep 30, 2018 at 11:01 AM Steve Barnes 
wrote:

> Adding inf & -inf would be nice but to do so we would need a better name
> than NaNAwareInt.
>

My placeholder name is deliberately awkward.  I think it gestures at the
concept for discussion purposes though.


> It would also be nice if Decimal(NaNAwareInt('nan')) = Decimal('NaN'),
> float(NaNAwareInt('nan')) = float('nan'), etc.


This seems like bad behavior given (per IEEE-754 spec):

>>> float('nan') == float('nan')
False
>>> nan = float('nan')
>>> nan == nan
False


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
On Sun, Sep 30, 2018 at 11:04 AM Chris Angelico  wrote:

> On Mon, Oct 1, 2018 at 12:58 AM David Mertz  wrote:
> >> I'm not sure what's going on. I have a Py3 busily calculating
> >> 2**(2**65) and it's pegging a CPU core while progressively consuming
> >> memory, but it responds to Ctrl-C, which suggests that Python bytecode
> >> is still being executed.
> > I'm not quite sure, but my guess is that at SOME POINT you'll get an
> overflow exception when the current value gets too big to store as a native
> int.  Or maybe it'll be a segfault; I don't know.
> >>> "a" * (2**63 - 1)
> Traceback (most recent call last):
>   File "", line 1, in 
> MemoryError
>
> Bam, instant. (Interestingly, trying to use 2**63 says "OverflowError:
> cannot fit 'int' into an index-sized integer", suggesting that
> "index-sized integer" is signed, even though a size can and should be
> unsigned.) Were there some kind of hard limit, it would be entirely
> possible to exceed that and get an instant error, without actually
> calculating all the way up there. But it looks like that doesn't
> happen.
>

Sure, it wouldn't be THAT hard to do bounds checking in the Python
implementation  to make '2**(2**65))' an instance error rather than a
wait-to-exhaust-swap one.  But it's a corner case, and probably not worth
the overhead for all the non-crazy uses of integer arithmetic.


> In any case, the colloquial definition that I usually cite ("Python
> can store infinitely big integers" or "integers can be as big as you
> have RAM to store") is within epsilon of correct :D
>

I teach the same thing.  For beginners or intermediate students, I just say
"unbounded ints." Occasionally for advanced students I add the footnote.


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Chris Angelico
On Mon, Oct 1, 2018 at 12:58 AM David Mertz  wrote:
>> I'm not sure what's going on. I have a Py3 busily calculating
>> 2**(2**65) and it's pegging a CPU core while progressively consuming
>> memory, but it responds to Ctrl-C, which suggests that Python bytecode
>> is still being executed.
>
>
> I'm not quite sure, but my guess is that at SOME POINT you'll get an overflow 
> exception when the current value gets too big to store as a native int.  Or 
> maybe it'll be a segfault; I don't know.
>
> I'm also not sure if you'll see this error before or after the heat death of 
> the universe ;-).
>
> I *am* sure that your swap space on your puny few terabyte disk will fill up 
> before you complete the calculation, so that might be a system level crash 
> not a caught exception.

Hahahaha. I was trying to compare to this:

>>> "a" * (2**63 - 1)
Traceback (most recent call last):
  File "", line 1, in 
MemoryError

Bam, instant. (Interestingly, trying to use 2**63 says "OverflowError:
cannot fit 'int' into an index-sized integer", suggesting that
"index-sized integer" is signed, even though a size can and should be
unsigned.) Were there some kind of hard limit, it would be entirely
possible to exceed that and get an instant error, without actually
calculating all the way up there. But it looks like that doesn't
happen.

In any case, the colloquial definition that I usually cite ("Python
can store infinitely big integers" or "integers can be as big as you
have RAM to store") is within epsilon of correct :D

Thanks for the info. Cool to know!

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Steve Barnes


On 30/09/2018 15:15, David Mertz wrote:
> For similar reasons, I'd like an iInf too, FWIW.  It's good for an 
> overflow value, although it's hard to get there in Python ints (would 
> 'NaNAwareInt(1)/0' be an exception or iInf?).  Bonus points for anyone 
> who knows the actual maximum size of Python ints :-).
> 
> However, the main use I'd have for iInf is simply as a starting value in 
> a minimization loop.  E.g.
> 
> minimum = NaNAwareInt('inf')
> for i in the_data:
>      minimum = min(i, minimum)
> 
>      other_stuff(i, minimum, a, b, c)
> 
> 
> I've written that code a fair number of times; usually I just pick a 
> placeholder value that is "absurdly large relative to my domain", but a 
> clean infinity would be slightly better.  E.g. 'minimum = 10**100'.
> 
The official maximum for a Python integer is x where x.bit_length()/8 == 
total_available_memory, (notice the word available which includes 
addressing limitations, other memory constraints, etc.).

Adding inf & -inf would be nice but to do so we would need a better name 
than NaNAwareInt.

It would also be nice if Decimal(NaNAwareInt('nan')) = Decimal('NaN'), 
float(NaNAwareInt('nan')) = float('nan'), etc.

I have been doing some reading up on Signalling vs. Quiet NaN and think 
that this convention could be well worth following, (and possibly 
storing some information about where the NaN was raised on first 
encountering a Signalling NaN (and converting it to Quiet).

-- 
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect 
those of my employer.

---
This email has been checked for viruses by AVG.
https://www.avg.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
On Sun, Sep 30, 2018 at 10:49 AM Chris Angelico  wrote:

> > int.bit_length() is stored as a system-native integer, e.g. 64-bit,
> rather than recursively as a Python int.  So the largest Python int is
> '2**sys.maxsize` (e.g. '2**(2**63-1)').  I may possibly have an off-by-one
> or off-by-power-of-two in there :-).
>
> Hah. Is that a fundamental limit based on the underlying
> representation, or would it mean that bit_length would bomb with an
> exception if the number is larger than that?
>

It's implementation specific.  In concept, a version of Python other than
CPython 3.7 could store bit-length as either a Python int or a
system-native int, to whatever recursive depth was needed to prevent
overflows.  Or perhaps as a linked list of native ints. Or something else.

There's no sane reason to bother doing that, but there's never been a
*promise* in Python semantics not to represent numbers with more than 1e19
bits in them.


> I'm not sure what's going on. I have a Py3 busily calculating
> 2**(2**65) and it's pegging a CPU core while progressively consuming
> memory, but it responds to Ctrl-C, which suggests that Python bytecode
> is still being executed.
>

I'm not quite sure, but my guess is that at SOME POINT you'll get an
overflow exception when the current value gets too big to store as a native
int.  Or maybe it'll be a segfault; I don't know.

I'm also not sure if you'll see this error before or after the heat death
of the universe ;-).

I *am* sure that your swap space on your puny few terabyte disk will fill
up before you complete the calculation, so that might be a system level
crash not a caught exception.

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Steven D'Aprano
On Sun, Sep 30, 2018 at 09:55:58AM -0400, David Mertz wrote:
> Notwithstanding my observation of one case where 'nan  float' doesn't
> stay a nan, I definitely want something like iNaN. Btw are there other
> operations on NaN's do not produce NaN's?

Yes.

The (informal?) rule applied by IEEE-754 is that if a function takes 
multiple arguments, and the result is entirely determined by all the 
non-NAN inputs, then that value ought to be returned. For example:

py> math.hypot(INF, NAN)
inf

py> 1**NAN
1.0

But generally, any operation (apart from comparisons) on a NAN is 
usually going to return a NAN.


> I suspect a NaNAwareInt subclass is the easiest way to get there, but I'm
> agnostic on that detail.

I think that adding a NAN to int itself will be too controversial to be 
accepted :-)



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Chris Angelico
On Mon, Oct 1, 2018 at 12:45 AM Anders Hovmöller  wrote:
> But making any change to the basic types truth table is a big -1 from me. 
> This seems like a Python 2-3 transition to me.
>

Far FAR worse than anything that changed in Py2->Py3.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Chris Angelico
On Mon, Oct 1, 2018 at 12:44 AM David Mertz  wrote:
>
> On Sun, Sep 30, 2018 at 10:23 AM Chris Angelico  wrote:
>>
>> On Mon, Oct 1, 2018 at 12:18 AM David Mertz  wrote:
>> > Bonus points for anyone who knows the actual maximum size of Python ints 
>> > :-).
>>
>> Whatever the maximum is, it's insanely huge.
>> Want to share what the maximum actually is? I'm very curious!
>
>
> Indeed.  It's a lot bigger than any machine that will exist in my lifetime 
> can hold.
>
> int.bit_length() is stored as a system-native integer, e.g. 64-bit, rather 
> than recursively as a Python int.  So the largest Python int is 
> '2**sys.maxsize` (e.g. '2**(2**63-1)').  I may possibly have an off-by-one or 
> off-by-power-of-two in there :-).
>

Hah. Is that a fundamental limit based on the underlying
representation, or would it mean that bit_length would bomb with an
exception if the number is larger than that?

I'm not sure what's going on. I have a Py3 busily calculating
2**(2**65) and it's pegging a CPU core while progressively consuming
memory, but it responds to Ctrl-C, which suggests that Python bytecode
is still being executed.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Anders Hovmöller


>> I am roughing out such a class and some test cases which will hopefully 
>> include some cases where the hoped for advantages can be realised.
>> 
>> My thinking on bitwise operations is to do the same as arithmetic 
>> operations, i.e. (anything op iNaN) = iNaN and likewise for shift 
>> operations.
> 
> Steve,
> 
> While you are extending a number system, can every int be truthy, while
> only iNan be falsey?  I found that behaviour more useful because
> checking if there is a value is more common than checking if it is a
> zero value.

I’m not saying you’re wrong in principle but such a change to Python seems 
extremely disruptive. And if we’re talking about robustness of code then 
truthiness would be better like in Java (!) imo, where only true is true and 
false is false and everything else is an error. If we’re actually talking about 
changing the truth table of Python for basic types then this is the logical 
next step.

But making any change to the basic types truth table is a big -1 from me. This 
seems like a Python 2-3 transition to me. 

/ Anders
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
On Sun, Sep 30, 2018 at 10:23 AM Chris Angelico  wrote:

> On Mon, Oct 1, 2018 at 12:18 AM David Mertz  wrote:
> > Bonus points for anyone who knows the actual maximum size of Python ints
> :-).
>
> Whatever the maximum is, it's insanely huge.
> Want to share what the maximum actually is? I'm very curious!
>

Indeed.  It's a lot bigger than any machine that will exist in my lifetime
can hold.

int.bit_length() is stored as a system-native integer, e.g. 64-bit, rather
than recursively as a Python int.  So the largest Python int is
'2**sys.maxsize` (e.g. '2**(2**63-1)').  I may possibly have an off-by-one
or off-by-power-of-two in there :-).


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Kyle Lahnakoski



On 2018-09-30 10:15, David Mertz wrote:
> For similar reasons, I'd like an iInf too, FWIW.  It's good for an
> overflow value, although it's hard to get there in Python ints (would
> 'NaNAwareInt(1)/0' be an exception or iInf?).  Bonus points for anyone
> who knows the actual maximum size of Python ints :-).
>
> However, the main use I'd have for iInf is simply as a starting value
> in a minimization loop.  E.g.
>
> minimum = NaNAwareInt('inf')
> for i in the_data:
>     minimum = min(i, minimum)
>
>     other_stuff(i, minimum, a, b, c)
>
>
> I've written that code a fair number of times; usually I just pick a
> placeholder value that is "absurdly large relative to my domain", but
> a clean infinity would be slightly better.  E.g. 'minimum = 10**100'.

If we conceptualize iNan as "not an integer", then we can define
operators in two manners:

Let |●| be any operator:

1) "conservative" - operators that define a|● |b==iNaN if either a or b
is iNan
2) "decisive" - operators that never return iNan

With a decisive min(a, b), you can write the code you want without
needing iINF

 

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Why is design-by-contracts not widely adopted?

2018-09-30 Thread David Mertz
On Sat, Sep 29, 2018 at 7:20 AM Steven D'Aprano  wrote:

> On Wed, Sep 26, 2018 at 04:03:16PM +0100, Rhodri James wrote:
> > Assuming that you
> > aren't doing some kind of wide-ranging static analysis (which doesn't
> > seem to be what we're talking about), all that the contracts have bought
> > you is the assurance that *this* invocation of the function with *these*
> > parameters giving *this* result is what you expected.  It does not say
> > anything about the reliability of the function in general.
>
> This is virtually the complete opposite of what contracts give us. What
> you are describing is the problem with *unit testing*, not contracts.
>

I think Steven's is backwards in its own way.

   - Contracts test the space of arguments *actually used during testing
   period* (or during initial production if the performance hit is
   acceptable).
   - Unit tests test the space of arguments *thought of by the developers*.

*A priori,* either one of those can cover cases not addressed by the
other.  If unit tests use the hypothesis library or similar approaches,
unit tests might very well examine arguments unlikely to be encountered in
real-world (or test phase) use... these are nonetheless edge cases that are
important to assure correct behavior on ("correct" can mean various things,
of course: exceptions, recovery, default values whatever).

In contrast, contracts might well find arguments that the developers of
unit tests had not thought of.  I tend to think someone sitting down trying
to think of edge cases is going to be able to write more thorough tests
than the accident of "what did we see during this run" ... but it could go
either way.

Of course... my own approach to this concern would more likely be to use a
logging decorator rather than a DbC one.  Then collect those logs that show
all the arguments that were passed to a given function during a testing
period, and roll those back into the unit tests.  My approach is a bit more
manual work, but also more flexible and more powerful.

- Half of the checks are very far away, in a separate file, assuming
>   I even remembered or bothered to write the test.
>

To me, this is the GREATEST VIRTUE of unit tests over DbC.  It puts the
tests far away where they don't distract from reading and understanding the
function itself.  I rarely want my checks proximate since I wear a very
different hat when thinking about checks than when writing functionality
(ideally, a lot of the time, I wear the unit test hat *before* I write the
implementation; TDD is usually good practice).


> - The post-conditions aren't checked unless I run my test suite, and
>   then they only check the canned input in the test suite.
>

Yes, this is a great advantage of unit tests.  No cost until you explicitly
run them.


> - No class invariants.
> - Inheritance is not handled correctly.
>

These are true.  Also they are things I care very little about.

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Why is design-by-contracts not widely adopted?

2018-09-30 Thread Steven D'Aprano
On Fri, Sep 28, 2018 at 01:49:01PM +0100, Paul Moore wrote:

> There's clearly a number of trade-offs going on here:
> 
> * Conditions should be short, to avoid clutter
> * Writing helper functions that are *only* used in conditions is more
> code to test or get wrong

This is no different from any other refactoring. If you have a function 
that checks its input:

def spam(arg):
if condition(arg) and other_condition(arg) or alt_condition(arg):
raise ValueError

and refactor it to a helper:

def invalid(arg):
return condition(arg) and other_condition(arg) or alt_condition(arg)

def spam(arg):
if invalid(arg):
raise ValueError

how is that a bad thing just because we call it a "precondition" instead 
of calling it "error checking"?

Of course we don't necessarily want the proliferation of masses and 
masses of tiny helper functions, but nor should we fear them. Helpers 
should carry their own weight, and if they do, we should use them. 
Whether they are used for contracts or not makes zero difference.


> * Sometimes it's just plain hard to express a verbal constraint in code

Indeed.

People seem to be arguing against some strawman of "Design By Contract 
is a magic bullet that solves every imaginable problem". Of course it 
doesn't. Some constraints are too hard to specify as code. Okay, then 
don't do that.

DbC isn't "all or nothing". If you can't write a contract for something, 
don't. You still get value from the contracts you do write.


[...]
> But given that *all* the examples I've seen of contracts have this
> issue (difficult to read expressions) I suspect the problem is
> inherent.

Are you specifically talking about *Python* examples? Or contracts in 
general?

I don't know Eiffel very well, but I find this easy to read and 
understand (almost as easy as Python). The trickiest thing is the 
implicit "self".

put (x: ELEMENT; key: STRING) is
-- Insert x so that it will be retrievable through key.
require
count <= capacity
not key.empty
do
... Some insertion algorithm ...
ensure
has (x)
item (key) = x 
count = old count + 1
end

https://www.eiffel.com/values/design-by-contract/introduction/


Here are a couple of examples from Cobra:

def fraction( numer as int, denom as int) as float
require
numer > 0
denom <> 0
body
  ...

def bumpState( incr as int) as int
require
incr > 0
ensure 
result >= incr
.state = old.state + incr 
body
  .state += incr
  return .state


http://cobra-language.com/trac/cobra/wiki/Contracts


If you find them difficult to read, I don't know what to say :-)



> Another thing that I haven't yet seen clearly explained. How do these
> contracts get *run*? Are they checked on every call to the function,

Yes, that's the point of them. In development they're always on. Every 
time you run your dev code, it tests itself.


> even in production code? 

That's up to you, but typical practice is to check pre-conditions (your 
input) but not post-conditions (your output) in production.


> Is there a means to turn them off? What's the
> runtime overhead of a "turned off" contract (even if it's just an
> if-test per condition, that can still add up)?


Other languages may offer different options, but in Eiffel, contracts 
checking can be set to:

no:assertions have no run-time effect.
require:   monitor preconditions only, on routine entry.
ensure:preconditions on entry, postconditions on exit.
invariant: same as ensure, plus class invariant on both entry
   and exit for qualified calls.
all:   same as invariant, plus check instructions, 
   loop invariants and loop variants.

You can set the checking level globally, or class-by-class. The default 
is to check only preconditions. That is, for methods to validate their 
inputs. Quoting from the Eiffel docs:

When releasing the final version of a system, it is usually 
appropriate to turn off assertion monitoring, or bring it down
to the ``require`` level. The exact policy depends on the 
circumstances; it is a trade off between efficiency considerations, 
the potential cost of mistakes, and how much the developers and 
quality assurance team trust the product. When developing the 
software, however, you should always assume -- to avoid loosening 
your guard -- that in the end monitoring will be turned off. 

https://www.eiffel.org/doc/eiffel/ET-_Design_by_Contract_%28tm%29%2C_Assertions_and_Exceptions


The intention for Python would be similar:

- we ought to be able disable contract checking globally;

- and preferrably on a case-by-case basis;

- a disabled contact ought to be like a disabled assertion, 
  that is, completely gone with no 

Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Chris Angelico
On Mon, Oct 1, 2018 at 12:18 AM David Mertz  wrote:
>
> For similar reasons, I'd like an iInf too, FWIW.  It's good for an overflow 
> value, although it's hard to get there in Python ints (would 
> 'NaNAwareInt(1)/0' be an exception or iInf?).  Bonus points for anyone who 
> knows the actual maximum size of Python ints :-).
>

Whatever the maximum is, it's insanely huge. I basically consider that
a Python int is as large as your computer has memory to store. I can
work with numbers so large that converting to string takes a notable
amount of time (never mind about actually printing it to a console,
just 'x = str(x)' pauses the interpreter for ages). If there's a
limit, it'll probably be described as something like 2**2**2**N for
some ridiculously large N.

Want to share what the maximum actually is? I'm very curious!

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Kyle Lahnakoski


On 2018-09-30 09:41, Steve Barnes wrote:
> I am roughing out such a class and some test cases which will hopefully 
> include some cases where the hoped for advantages can be realised.
>
> My thinking on bitwise operations is to do the same as arithmetic 
> operations, i.e. (anything op iNaN) = iNaN and likewise for shift 
> operations.

Steve,

While you are extending a number system, can every int be truthy, while
only iNan be falsey?  I found that behaviour more useful because
checking if there is a value is more common than checking if it is a
zero value.

Thank you
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Kyle Lahnakoski


On 2018-09-30 09:41, Steve Barnes wrote:
> I am roughing out such a class and some test cases which will hopefully 
> include some cases where the hoped for advantages can be realised.
>
> My thinking on bitwise operations is to do the same as arithmetic 
> operations, i.e. (anything op iNaN) = iNaN and likewise for shift 
> operations.

Steve,

While you are extending a number system, can every int be truthy, while
only iNan be falsey?  I found that behaviour more useful because
checking if there is a value is more common than checking if it is a
zero value.

Thank you
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
For similar reasons, I'd like an iInf too, FWIW.  It's good for an overflow
value, although it's hard to get there in Python ints (would
'NaNAwareInt(1)/0' be an exception or iInf?).  Bonus points for anyone who
knows the actual maximum size of Python ints :-).

However, the main use I'd have for iInf is simply as a starting value in a
minimization loop.  E.g.

minimum = NaNAwareInt('inf')
for i in the_data:
minimum = min(i, minimum)

other_stuff(i, minimum, a, b, c)


I've written that code a fair number of times; usually I just pick a
placeholder value that is "absurdly large relative to my domain", but a
clean infinity would be slightly better.  E.g. 'minimum = 10**100'.

On Sun, Sep 30, 2018 at 9:55 AM David Mertz  wrote:

> Notwithstanding my observation of one case where 'nan  float' doesn't
> stay a nan, I definitely want something like iNaN. Btw are there other
> operations on NaN's do not produce NaN's?
>
> I suspect a NaNAwareInt subclass is the easiest way to get there, but I'm
> agnostic on that detail.
>
> For the very same reasons that other numeric types benefit from NaN, ints
> would also. I.e. I want to do a series of numeric operations on a bunch of
> input numbers, and it's less cumbersome to check if we went to NaN-land at
> the end than it is to try/except around every op.
>
>
> On Sun, Sep 30, 2018, 9:42 AM Steve Barnes  wrote:
>
>>
>>
>> On 30/09/2018 13:55, Steven D'Aprano wrote:
>> > On Sun, Sep 30, 2018 at 12:09:45PM +0300, Serhiy Storchaka wrote:
>> >> 30.09.18 04:07, Steven D'Aprano пише:
>> >>> Telling people that they don't understand their own code when you
>> don't
>> >>> know their code is not very productive.
>> >>
>> >> I can't tell him what he should do with his (not working) code, but it
>> >> doesn't look like a good justification for changes in the Python core.
>> >
>> > You don't know that his code is not working. For all you know, Steve has
>> > working code that works around the lack of an int NAN in some other,
>> > more clumsy, less elegant, ugly and slow way.
>> >
>> > NANs are useful for when you don't want a calculation to halt on certain
>> > errors, or on missing data. That ability of a NAN to propogate through
>> > the calculation instead of halting can be useful when your data are
>> > ints, not just floats or Decimals.
>> >
>> > Earlier, I suggested that this proposal would probably be best done as a
>> > subclass of int. It certainly should be prototyped as a subclass before
>> > we consider making a builtin int NAN. Since Steve has already agreed to
>> > work on that first, I think any further discussion would be pointless
>> > until he comes back to us. He may decide that a subclass solves his
>> > problem and no longer want a builtin int NAN.
>> >
>> >
>> I have had (over the years) a lot of working code with lots of checks in
>> and a huge number of paths through due to the lack of such of iNaN, or
>> something to return for "that didn't work", floats & complex have NaN,
>> strings have empty string list and sets can be empty but there is no
>> such option for integers. Hence the suggestion. I am hartened that the
>> authors of the Decimal library also felt the need for NaN (as well as
>> INF & -INF).
>>
>> I am roughing out such a class and some test cases which will hopefully
>> include some cases where the hoped for advantages can be realised.
>>
>> My thinking on bitwise operations is to do the same as arithmetic
>> operations, i.e. (anything op iNaN) = iNaN and likewise for shift
>> operations.
>> --
>> Steve (Gadget) Barnes
>> Any opinions in this message are my personal opinions and do not reflect
>> those of my employer.
>>
>> ---
>> This email has been checked for viruses by AVG.
>> https://www.avg.com
>>
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread David Mertz
Notwithstanding my observation of one case where 'nan  float' doesn't
stay a nan, I definitely want something like iNaN. Btw are there other
operations on NaN's do not produce NaN's?

I suspect a NaNAwareInt subclass is the easiest way to get there, but I'm
agnostic on that detail.

For the very same reasons that other numeric types benefit from NaN, ints
would also. I.e. I want to do a series of numeric operations on a bunch of
input numbers, and it's less cumbersome to check if we went to NaN-land at
the end than it is to try/except around every op.


On Sun, Sep 30, 2018, 9:42 AM Steve Barnes  wrote:

>
>
> On 30/09/2018 13:55, Steven D'Aprano wrote:
> > On Sun, Sep 30, 2018 at 12:09:45PM +0300, Serhiy Storchaka wrote:
> >> 30.09.18 04:07, Steven D'Aprano пише:
> >>> Telling people that they don't understand their own code when you don't
> >>> know their code is not very productive.
> >>
> >> I can't tell him what he should do with his (not working) code, but it
> >> doesn't look like a good justification for changes in the Python core.
> >
> > You don't know that his code is not working. For all you know, Steve has
> > working code that works around the lack of an int NAN in some other,
> > more clumsy, less elegant, ugly and slow way.
> >
> > NANs are useful for when you don't want a calculation to halt on certain
> > errors, or on missing data. That ability of a NAN to propogate through
> > the calculation instead of halting can be useful when your data are
> > ints, not just floats or Decimals.
> >
> > Earlier, I suggested that this proposal would probably be best done as a
> > subclass of int. It certainly should be prototyped as a subclass before
> > we consider making a builtin int NAN. Since Steve has already agreed to
> > work on that first, I think any further discussion would be pointless
> > until he comes back to us. He may decide that a subclass solves his
> > problem and no longer want a builtin int NAN.
> >
> >
> I have had (over the years) a lot of working code with lots of checks in
> and a huge number of paths through due to the lack of such of iNaN, or
> something to return for "that didn't work", floats & complex have NaN,
> strings have empty string list and sets can be empty but there is no
> such option for integers. Hence the suggestion. I am hartened that the
> authors of the Decimal library also felt the need for NaN (as well as
> INF & -INF).
>
> I am roughing out such a class and some test cases which will hopefully
> include some cases where the hoped for advantages can be realised.
>
> My thinking on bitwise operations is to do the same as arithmetic
> operations, i.e. (anything op iNaN) = iNaN and likewise for shift
> operations.
> --
> Steve (Gadget) Barnes
> Any opinions in this message are my personal opinions and do not reflect
> those of my employer.
>
> ---
> This email has been checked for viruses by AVG.
> https://www.avg.com
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Steve Barnes


On 30/09/2018 13:55, Steven D'Aprano wrote:
> On Sun, Sep 30, 2018 at 12:09:45PM +0300, Serhiy Storchaka wrote:
>> 30.09.18 04:07, Steven D'Aprano пише:
>>> Telling people that they don't understand their own code when you don't
>>> know their code is not very productive.
>>
>> I can't tell him what he should do with his (not working) code, but it
>> doesn't look like a good justification for changes in the Python core.
> 
> You don't know that his code is not working. For all you know, Steve has
> working code that works around the lack of an int NAN in some other,
> more clumsy, less elegant, ugly and slow way.
> 
> NANs are useful for when you don't want a calculation to halt on certain
> errors, or on missing data. That ability of a NAN to propogate through
> the calculation instead of halting can be useful when your data are
> ints, not just floats or Decimals.
> 
> Earlier, I suggested that this proposal would probably be best done as a
> subclass of int. It certainly should be prototyped as a subclass before
> we consider making a builtin int NAN. Since Steve has already agreed to
> work on that first, I think any further discussion would be pointless
> until he comes back to us. He may decide that a subclass solves his
> problem and no longer want a builtin int NAN.
> 
> 
I have had (over the years) a lot of working code with lots of checks in 
and a huge number of paths through due to the lack of such of iNaN, or 
something to return for "that didn't work", floats & complex have NaN, 
strings have empty string list and sets can be empty but there is no 
such option for integers. Hence the suggestion. I am hartened that the 
authors of the Decimal library also felt the need for NaN (as well as 
INF & -INF).

I am roughing out such a class and some test cases which will hopefully 
include some cases where the hoped for advantages can be realised.

My thinking on bitwise operations is to do the same as arithmetic 
operations, i.e. (anything op iNaN) = iNaN and likewise for shift 
operations.
-- 
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect 
those of my employer.

---
This email has been checked for viruses by AVG.
https://www.avg.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Steven D'Aprano
On Sun, Sep 30, 2018 at 12:09:45PM +0300, Serhiy Storchaka wrote:
> 30.09.18 04:07, Steven D'Aprano пише:
> >Telling people that they don't understand their own code when you don't
> >know their code is not very productive.
> 
> I can't tell him what he should do with his (not working) code, but it 
> doesn't look like a good justification for changes in the Python core.

You don't know that his code is not working. For all you know, Steve has 
working code that works around the lack of an int NAN in some other, 
more clumsy, less elegant, ugly and slow way.

NANs are useful for when you don't want a calculation to halt on certain 
errors, or on missing data. That ability of a NAN to propogate through 
the calculation instead of halting can be useful when your data are 
ints, not just floats or Decimals.

Earlier, I suggested that this proposal would probably be best done as a 
subclass of int. It certainly should be prototyped as a subclass before 
we consider making a builtin int NAN. Since Steve has already agreed to 
work on that first, I think any further discussion would be pointless 
until he comes back to us. He may decide that a subclass solves his 
problem and no longer want a builtin int NAN.


-- 
Steve
but not the same Steve as above...
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)

2018-09-30 Thread Elazar
On Sun, Sep 30, 2018, 15:12 Stephen J. Turnbull <
turnbull.stephen...@u.tsukuba.ac.jp> wrote:

> Steven D'Aprano writes:
>
>  > (4) Inheritance
>  >
>  > Contracts are inherited, unit tests are not.
>
> What does "inherited" mean?  Just that methods that are not overridden
> retain their contracts?
>

Contracts are attached to interfaces, not to specifications. So when you
have abstract base class, it defines contracts, and implementing classes
must adhere to these contracts - the can only strengthen it, not weaken it.

This way the user code need pnly be aware of the specification, not the
implementation.

So method that _are_ overridden retain their contracts.

This is precisely like with types, since types are contracts (and vice
versa, in a way).

Elazar
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)

2018-09-30 Thread Stephen J. Turnbull
Steven D'Aprano writes:

 > (1) Distance 

 > (2) Self-documenting code

 > (3) The "Have you performed the *right* tests?" problem

 > (4) Inheritance
 > 
 > Contracts are inherited, unit tests are not.

What does "inherited" mean?  Just that methods that are not overridden
retain their contracts?

 > (6) Separation of concerns: function algorithm versus error checking
 > 
 > Functions ought to validate their input, but doing so obfuscates the 
 > function implementation. Making that input validation a pre-condition 
 > separates the error checking and input validation from the algorithm 
 > proper, which helps make the code self-documenting.

There's nothing in the Eiffel syntax that distinguishes *which*
contract(s) was (were) violated.  Is there some magic?  Or does the
Eiffel process just die?  (ISTR that is a typical error "recovery"
approach in systems implemented in Eiffel, maybe from the Beautiful
Code book?)

 > (7) You can't unit test loop invariants

I don't see how a loop invariant can be elegantly specified without
mixing it in to the implementation.  Can you show an example of code
written in a language with support for loop invariants *not* mixed
into the implementation?

 > (8) Executable documentation

I don't see how any of your points fail to be satisfied by use of
asserts with a convention that (except for loop invariants) they're
placed either at the beginning or the end of the function, depending
on whether they're pre- or post-conditions.  This requires a single-
exit style which may sometimes be unnatural, of course.

AFAICS you can program in contract style already in Python.  Contracts
involving both beginning and end state would require annoying local
variables, definitely.  But other than that, all I see is a desire for
unnecessary syntax, or stdlib, support.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Suggestion: Extend integers to include iNaN

2018-09-30 Thread Serhiy Storchaka

30.09.18 04:07, Steven D'Aprano пише:

Telling people that they don't understand their own code when you don't
know their code is not very productive.


I can't tell him what he should do with his (not working) code, but it 
doesn't look like a good justification for changes in the Python core.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Make None a subclass of int [alternative to iNaN]

2018-09-30 Thread Serhiy Storchaka

30.09.18 09:05, Ken Hilton пише:
Reading the iNaN discussion, most of the opposition seems to be that 
adding iNaN would add a new special value to integers and therefore add 
new complexity.


I propose, instead, that we make None a subclass of int (or even a 
certain value of int) to represent iNaN. Therefore:


     >>> None + 1, None - 1, None * 2, None / 2, None // 2
     (None, None, None, nan, None) # mathematical operations on NaN 
return NaN

     >>> None & 1, None | 1, None ^ 1
     # I'm not sure about this one. The following could be plausible:
     (0, 1, 1)
     # or this might make more sense, as this *is* NaN we're talking about:
     (None, None, None)
     >>> isinstance(None, int)
     True # the whole point of this idea
     >>> issubclass(type(None), int)
     True # no matter whether None *is* an int or just a subclass, this 
will be true as issubclass(int, int) is True


I know this is a crazy idea, but I thought it could have some merit, so 
why not throw it out here?


This will make some errors passing silently (instead of raising a 
TypeError or AttributeError earlier) and either cause errors far from 
the initial place or producing an incorrect result.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)

2018-09-30 Thread Chris Angelico
On Sun, Sep 30, 2018 at 6:03 PM Steven D'Aprano  wrote:
>
> On Sun, Sep 30, 2018 at 02:50:28PM +1000, Chris Angelico wrote:
>
> > And yet all the examples I've seen have just been poor substitutes for
> > unit tests. Can we get some examples that actually do a better job of
> > selling contracts?
>
> In no particular order...
>
> (1) Distance

Don't doctests deal with this too? With the exact same downsides?

> (2) Self-documenting code

Ditto

> (3) The "Have you performed the *right* tests?" problem

Great if your contracts can actually be perfectly defined. Every time
a weird case is mentioned, those advocating contracts (mainly Marko)
give examples showing "hey, contracts can do that too", and they're
just testing specifics.

> (4) Inheritance

Okay, that one I 100% grant you.

> (5) Unit tests and contracts are complementary, not alternatives

That I agree with.

> (6) Separation of concerns: function algorithm versus error checking

Agreed, so long as you can define the contract in a way that isn't
just duplicating the function's own body.

> (7) You can't unit test loop invariants

Sure.

> (8) Executable documentation

Granted, but there are many forms of that.

Contracts are great for some situations, but I'm seeing a lot of cases
where they're just plain not, yet advocates still say "use contracts,
use contracts". Why?

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)

2018-09-30 Thread Steven D'Aprano
On Sun, Sep 30, 2018 at 02:50:28PM +1000, Chris Angelico wrote:

> And yet all the examples I've seen have just been poor substitutes for
> unit tests. Can we get some examples that actually do a better job of
> selling contracts?

In no particular order...

(1) Distance 

Unit tests are far away from the code you are looking at. Things which 
go together ought to be together, but typically unit tests are not just 
seperate from the thing they are testing, but in a completely different 
file.

Contracts are right there, next to the thing they belong with, but 
without being mixed into the implementation of the method or function.


(2) Self-documenting code

Contracts are self-documenting code. Unit tests are not. Unit tests are 
full of boilerplate, creating instances, setting up test data, checking 
the result. Contracts simply cut to the chase and state the 
requirements and the promises made:

the input must be a non-empty list
the result will be a string starting with "Aardvark"

as executable code.


(3) The "Have you performed the *right* tests?" problem

Unit tests are great, but they have a serious problem: they test ONLY 
the canned data you put in your test. For non-trivial functions, unit 
tests tell you nothing about the general behaviour of your function, 
only the specific behaviour with the given input:

The key problem with testing is that a test (of any kind) 
that uses one particular set of inputs tells you nothing 
at all about the behaviour of the system or component when 
it is given a different set of inputs.

http://thinkrelevance.com/blog/2013/11/26/better-than-unit-tests

Contracts are one (partial) solution to this problem.

If you have a unit test that does this:

def test_spam(self):
self.AssertEqual(spam(2).count("eggs"), 2)

then it tests ONLY that spam(2) contains "eggs" twice, and that's it. It 
tells you nothing about whether spam(3) or spam(1028374527601) is 
correct. In fact, under Test Driven Development, it would be normal to 
write the test first, and then implement spam as a stub that does this:

def spam(n):
return "eggs eggs"

proving my point that a passing test with one input doesn't mean the 
function is correct for another input.

In contrast, the post-condition:

def spam(n):
ensure:
result.count("eggs") == max(0, n)
# implementation


is tested on every invocation of spam (up to the point that you decide 
to disable post-condition checks). There is no need for separate tests 
for spam(2) and spam(3) and spam(1028374527601) unless you have some 
specific need for them. (Say, a regression test after fixing a 
particular bug.)


(4) Inheritance

Contracts are inherited, unit tests are not.


(5) Unit tests and contracts are complementary, not alternatives

Unit tests and contracts do overlap, and in the areas of overlap 
contracts are generally superior. But sometimes it is too hard to 
specify a contract in sufficient detail, and so unit tests are more 
appropriate.

And for some especially simple functions, you can't specify the 
post-condition except by duplicating the implementation:

def max(a, b):
"""Return the maximum of a and b."""
ensure:
result == a if a >= b else b
implementation:
return a if a >= b else b

In that case, a post-condition is a waste of time, and one should just 
unit test it.

https://sebnozzi.github.io/362/contracts-replace-unit-tests/

Another way to think about it is that unit tests and contracts have 
different purposes. Pre-conditions and class invariants are a form of 
defensive programming that ensures that your prerequisites are met, that 
code is called with the correct parameters, etc. Unit tests are a way of 
doing spot tests that the code works with certain specified inputs.


(6) Separation of concerns: function algorithm versus error checking

Functions ought to validate their input, but doing so obfuscates the 
function implementation. Making that input validation a pre-condition 
separates the error checking and input validation from the algorithm 
proper, which helps make the code self-documenting.


(7) You can't unit test loop invariants

Some languages have support for testing loop invariants. You can't unit 
test loop invariants at all.

https://en.wikipedia.org/wiki/Loop_invariant#Programming_language_support


(8) Executable documentation

Contracts are executable code that document what input is valid and what 
result is returned. Executable code is preferrable to dead comments 
because comments rot:

"At Resolver we've found it useful to short-circuit any doubt and just 
refer to comments in code as 'lies'. "
-- Michael Foord paraphrases Christian Muirhead on python-dev, 2009-03-22

Contracts can also be extracted by static tools.




-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org

Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)

2018-09-30 Thread Marko Ristin-Kaufmann
Hi Cameron,

Just a word of caution: I made a mistake and badly designed interface to
icontract. It will change in the near future from:

@post(lambda arg1, arg2, result: arg1 < result < arg2)

most probably to:

@ensures(lambda P:  P.arg1 < result < P.arg2)

This avoids any name conflicts with "result" if it's in the arguments and
also many conflicts with web frameworks which frequently use "post". We
will also add snapshotting before the function execution:
@snapshot(lambda P, var2: set(arg2))
@ensures(lambda O, P: P.arg1 < result and result in O.var2)

so that postcondition can deal with state transitions. There are also some
other approaches in discussion.

The library name will also need to change. When I started developing it, I
was not aware of Java icontract library. It will be probably renamed to
"pcontract" or any other suggested better name :)

Please see the github issues for more details and current discussions:
https://github.com/Parquery/icontract/issues

On Sun, 30 Sep 2018 at 06:44, Cameron Simpson  wrote:

> On 30Sep2018 12:17, Chris Angelico  wrote:
> >At the moment, I'm seeing decorator-based contracts as a clunky
> >version of unit tests. We already have "inline unit testing" - it's
> >called doctest - and I haven't seen anything pinned down as "hey, this
> >is what it'd take to make contracts more viable". Certainly nothing
> >that couldn't be done as a third-party package. But I'm still open to
> >being swayed on that point.
>
> Decorator based contracts are very little like clunky unit tests to me.
> I'm
> basing my opinion on the icontracts pip package, which I'm going to start
> using.
>
> In case you've been looking at something different, it provides a small
> number
> of decorators including @pre(test-function) and @post(test-function) and
> the
> class invariant decorator @inv, with good error messages for violations.
>
> They are _functionally_ like putting assertions in your code at the start
> and
> end of your functions, but have some advantages:
>
> - they're exposed, not buried inside the function, where they're easy to
> see
>   and can be considered as contracts
>
> - they run on _every_ function call, not just during your testing, and get
>   turned off just like assertions do: when you run Python with the -O
>   (optimise) option. (There's some more tuning available too.)
>
> - the assertions make qualitative statements about the object/parameter
> state
>   in the form "the state is consistent if these things apply";
>   tests tend to say "here's a situation, do these things and examine these
>   results". You need to invent the situations and the results, rather than
>   making general statements about the purpose and functional semantics of
> the
>   class.
>
> They're different to both unit tests _and_ doctests because they get
> exercised
> during normal code execution. Both unit tests and doctests run _only_
> during
> your test phase, with only whatever test scenarios you have devised.
>
> The difficulty with unit tests and doctests (both of which I use) and also
> integration tests is making something small enough to run but big/wide
> enough
> to cover all the relevant cases. They _do not_ run against all your real
> world
> data. It can be quite hard to apply them to your real world data.
>
> Also, all the @pre/@post/@inv stuff will run _during_ your unit tests and
> doctests as well, so they get included in your test regime for free.
>
> I've got a few classes which have a selftest method whose purpose is to
> confirm
> correctness of the instance state, and I call that from a few methods at
> start
> and end, particularly those for which unit tests have been hard to write
> or I
> know are inadequately covered (and probably never will be because devising
> a
> sufficient test case is impractical, especially for hard to envisage
> corner
> cases).
>
> The icontracts module will be very helpful to me here: I can pull out the
> self-test function as the class invariant, and make a bunch of @pre/@post
> assertions corresponding the the method semantic definition.
>
> The flip side of this is that there's no case for language changes in what
> I
> say above: the decorators look pretty good to my eye.
>
> Cheers,
> Cameron Simpson 
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Why is design-by-contracts not widely adopted?

2018-09-30 Thread Marko Ristin-Kaufmann
Hi,

I compiled a couple of issues on github to provide a more structured ground
for discussions on icontract features:
https://github.com/Parquery/icontract/issues (@David Maertz: I also
included the issue with automatically generated __doc__ in case you are
still interested in it).

Cheers,
Marko

On Sat, 29 Sep 2018 at 17:27, Stephen J. Turnbull <
turnbull.stephen...@u.tsukuba.ac.jp> wrote:

> Steven D'Aprano writes:
>
>  > put (x: ELEMENT; key: STRING) is
>  >  -- Insert x so that it will be retrievable through key.
>  >  require
>  >  count <= capacity
>  >  not key.empty
>  >  do
>  >  ... Some insertion algorithm ...
>  >  ensure
>  >  has (x)
>  >  item (key) = x
>  >  count = old count + 1
>  >  end
>  >
>  > Two pre-conditions, and three post-conditions. That's hardly
>  > complex.
>
> You can already do this:
>
> def put(self, x: Element, key: str) -> None:
> """Insert x so that it will be retrievable through key."""
>
> # CHECKING PRECONDITIONS
> _old_count = self.count
> assert self.count <= self.capacity,
> assert key
>
> # IMPLEMENTATION
> ... some assertion algorithm ...
>
> # CHECKING POSTCONDITIONS
> assert x in self
> assert self[key] == x
> assert self.count == _old_count
>
> return
>
> I don't see a big advantage to having syntax, unless the syntax allows
> you to do things like turn off "expensive" contracts only.  Granted,
> you save a little bit of typing and eye movement (you can omit
> "assert" and have syntax instead of an assignment for checking
> postconditions dependent on initial state).
>
> A document generator can look for the special comments (as with
> encoding cookies), and suck in all the asserts following until a
> non-assert line of code (or the next special comment).  The
> assignments will need special handling, an additional special comment
> or something.  With PEP 572, I think you could even do this:
>
> assert ((_old_count := self.count),)
>
> to get the benefit of python -O here.
>
>  > If I were writing this in Python, I'd write something like this:
>  >
>  > def put(self, x, key):
>  > """Insert x so that it will be retrievable through key."""
>  > # Input checks are pre-conditions!
>  > if self.count > capacity:
>  > raise DatabaseFullError
>  > if not key:
>  > raise ValueError
>  > # .. Some insertion algorithm ...
>
> But this is quite different, as I understand it.  Nothing I've seen in
> the discussion so far suggests that a contract violation allows
> raising differentiated exceptions, and it seems very unlikely from the
> syntax in your example above.  I could easily see both of these errors
> being retryable:
>
> for _ in range(3):
> try:
> db.put(x, key)
> except DatabaseFullError:
> db.resize(expansion_factor=1.5)
> db.put(x, key)
> except ValueError:
> db.put(x, alternative_key)
>
>  > and then stick the post-conditions in a unit test, usually in a
>  > completely different file:
>
> If you like the contract-writing style, why would you do either of
> these instead of something like the code I wrote above?
>
>  > So what's wrong with the status quo?
>  >
>  > - The pre-condition checks are embedded right there in the
>  >   method implementation, mixing up the core algorithm with the
>  >   associated error checking.
>
> You don't need syntax to separate them, you can use a convention, as I
> did above.
>
>  > - Which in turn makes it hard to distinguish the checks from
>  >   the implementation, and impossible to do so automatically.
>
> sed can do it, why can't we?
>
>  > - Half of the checks are very far away, in a separate file,
>  >   assuming I even remembered or bothered to write the test.
>
> That was your choice.  There's nothing about the assert statement that
> says you're not allowed to use it at the end of a definition.
>
>  > - The post-conditions aren't checked unless I run my test suite, and
>  >   then they only check the canned input in the test suite.
>
> Ditto.
>
>  > - The pre-conditions can't be easily disabled in production.
>
> What's so hard about python -O?
>
>  > - No class invariants.
>
> Examples?
>
>  > - Inheritance is not handled correctly.
>
> Examples?  Mixins and classes with additional functionality should
> work fine AFAICS.  I guess you'd have to write the contracts in each
> subclass of an abstract class, which is definitely a minus for some of
> the contracts.  But I don't see offhand why you would expect that the
> full contract of a method of a parent class would typically make sense
> without change for an overriding implementation, and might not make
> sense for a class with restricted functionality.
>
>  > The status quo is all so very ad-hoc and messy. Design By Contract
>  > syntax would 

[Python-ideas] Make None a subclass of int [alternative to iNaN]

2018-09-30 Thread Ken Hilton
Hi all,

Reading the iNaN discussion, most of the opposition seems to be that adding
iNaN would add a new special value to integers and therefore add new
complexity.

I propose, instead, that we make None a subclass of int (or even a certain
value of int) to represent iNaN. Therefore:

>>> None + 1, None - 1, None * 2, None / 2, None // 2
(None, None, None, nan, None) # mathematical operations on NaN return
NaN
>>> None & 1, None | 1, None ^ 1
# I'm not sure about this one. The following could be plausible:
(0, 1, 1)
# or this might make more sense, as this *is* NaN we're talking about:
(None, None, None)
>>> isinstance(None, int)
True # the whole point of this idea
>>> issubclass(type(None), int)
True # no matter whether None *is* an int or just a subclass, this will
be true as issubclass(int, int) is True

I know this is a crazy idea, but I thought it could have some merit, so why
not throw it out here?

Sharing,
Ken Hilton;
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/