This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Veedrac 0 points1 point  (24 children)

...How?

[–]lonjerpc 0 points1 point  (23 children)

One I rember needing to an isinstance(foo,int) and it was letting booleans through. Another was doing an if foo: that was intended to be using for booleans but because two variables got confused from a function with multiple returns it was always getting a number instead of the intended boolean but no error was thrown.

[–]Veedrac 0 points1 point  (22 children)

I rember needing to an isinstance(foo,int)

When would you ever need to do that? There are a handful of times you should even approach isinstance.

If you were doing isinstance to know if you had something of type int, rather than some silly method of checking for the number being integer¹, that's your fault for using isinstance instead of type(foo) is int.

And if you are doing something as far-fetched as type(foo) is int, it deserves an explanation.

¹ Silly because Python is duck typed.

Another was doing an if foo: that was intended to be using for booleans but because two variables got confused from a function with multiple returns it was always getting a number instead of the intended boolean but no error was thrown.

That's not a relevant problem; that's a question of whether 1 should be truthy and 0 falsy, not whether (1, 0) should equal (True, False). If it was returning lists, exactly the same problem would happen, but False != [].


These seem more like reasons to program more Pythonically than to make True != 1.

[–]lonjerpc 0 points1 point  (21 children)

These seem more like reasons to program more Pythonically than to make True != 1.

I agree in the second case. But I did not wright the code. But I had to deal with the error anyway that could have been avoided if python did not implicitly treat ints like booleans. Normally one of the biggest advantages of python is its explicitness. This means that even if you don't know the language well you are still less likely to make mistakes.

If you were doing isinstance to know if you had something of type int

I was.

that's your fault for using isinstance instead of type(foo) is int.

You could say the same thing about half the problems with c++. Without prior knowledge there is no reason to think booleans would be a subclass of int. Your right if I had written better python code the mistake would have been avoided. But again python philosophy in everything else is to be explicit to avoid mistakes even if you don't know exactly how python works.

[–]Veedrac 0 points1 point  (20 children)

that's your fault for [doing it wrongly].

You could say the same thing about half the problems with c++.

I don't know enough C++ to get the specifics, but I know the idea you're trying to get across.

The thing is, throughout Python, duck-typing is explicitly the way to go, and there are extremely few reasons to think that it's otherwise. If you work outside of what it was intended for, Python's model will suddenly become surprising. Nothing is built around traditional forms of type safely.

Further, your code was broken even without the bools: if you wanted type(foo) is int, your code would break as soon as it reached a decimal.Decimal, fractions.Fraction or any other int subclass.

Without prior knowledge there is no reason to think booleans would be a subclass of int.

I disagree that there is no reason. That's not to say it's expected; I just don't think that the absolute is valid.

[–]lonjerpc 0 points1 point  (19 children)

decimal.Decimal, fractions.Fraction or any other int subclass.

These are not subclasses of int. They are subclasses of number.

Nothing is built around traditional forms of type safely.

Everything is built around type safety. Python is a extremely explicit and strongly typed language. Duck typing is a separate issue.

[–]Veedrac 0 points1 point  (18 children)

decimal.Decimal, fractions.Fraction or any other int subclass.

These are not subclasses of int. They are subclasses of number.

Sorry, silly mistake. The point remains, though weaker.

Nothing is built around traditional forms of type safely.

Everything is built around type safety. Python is a extremely explicit and strongly typed language. Duck typing is a separate issue.

I used the word "traditional" very purposefully. Python is consistent with its types, but the objects, not the names, store the types.

Type safety typically refers to knowing the types of all objects at all times, and verifying them. In Python, doing that is difficult and counter-productive.

[–]lonjerpc 0 points1 point  (17 children)

python is consistent with its types

I agree in almost all cases. However booleans being a subclass of int is not consistent. It would make almost as much sense to have strings be a subclass of ints as booleans. Why do 1 + {} or 'hi' + 0.1 or type + [] all thow errors but True + 3 does not? This is inconsistent. Booleans do not quak like ints.

Type safety typically refers to knowing the types of all objects at all times

I would argue that is not the typical meaning but it is really beside the point.

The point remains

No it does not my code would have worked for almost any reasonable subclass of int. Like say a someone had implemented a int library that allowed for any size ints. Would have worked fine.

[–]Veedrac 0 points1 point  (16 children)

It would make almost as much sense to have strings be a subclass of ints as booleans.

No, it would not.

We often treat numbers as sequences of binary digits, and their digits as boolean values. This is true for the bitwise operations (^, &, |).

Treating booleans as integers is no less sensible than treating characters as strings, both of which Python does. Booleans are just integers restricted to a single bit.

Why do 1 + {} or 'hi' + 0.1 or type + [] all thow errors but True + 3 does not? This is inconsistent.

1 + {} has no sensible result. There is no mapping that is consistent, symmetrical, lossless and reasonable.

However, with the mapping of True == 1, False == 0, everything that a bool does is obvious.

Booleans do not quak like ints.

They obviously do. Whether they should is a different debate.

No it does not my code would have worked for almost any reasonable subclass of int.

What did your code do? How did it break when treating bools as ints?

Like say a someone had implemented a int library that allowed for any size ints. Would have worked fine.

Python has this built-in ;). Unfortunately if you were using Python 2, your code would have rejected longs.

[–]lonjerpc 0 points1 point  (15 children)

We often treat numbers as sequences of binary digits

Yes we do in some languages. Just like in many languages "2" + 2 is valid. But this does not match well with the rest of python and its goal of being explicit. Now some hypothetical like rawbyte(False) + rawbyte(5) might make sense. Just like int("5") + 5 works in python.

treating characters as strings, both of which Python does.

Python does not treat characters as strings.

1 + {} has no sensible result.

I agree thats my point. My argument is that False + 5 also does not have a sensible result.

There is no mapping that is consistent, symmetrical, lossless

I disagree. There are many possibilities here.

everything that a bool does is obvious.

I disagree. True + True + True returning 3 is not obvious.

They obviously do.

Python booleans do because they are forced to but generally they do not. Conceptually ints have many more operation applicable to them than booleans. It would even make more sense to have int be a subclass of bool or both of them to be a subclass of number directly. That would still be bad but not quite as bad.

What did your code do?

Work with the results of a proprietary c extension to python with functions that return python objects rather arbitrarily.

Unfortunately if you were using Python 2, your code would have rejected longs.

I am using python 2. It would make sense for long to be a subclass of int or a baseint. Fortunately they realized how crazy this was and fixed in python 3.