Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Note: Even though this contains Python, it's not specifically about Python. It's more generally about expecting a certain behaviour from a language which is not necessarily the same across compilers/interpreters.


So I came across this question:

How do I convert a boolean to int in Python? Can I just do int(mybool)?

My response was to write:

1 if mybool else 0

My reasoning was that blindly "casting" to int would rely on the internal implementation of the compiler/interpreter. And who knows, if running through a different interpreter int(mybool) might return something else. Explicitly stating the value for a "truthy" value and for a "falsey" value will always yield the expected behaviour.

This is surely something which one can consider for most languages.

Am I too picky about this? I know that I have written int(mybool) myself in the past. And that question made me think: Was that okay? Given that this is a very common case, are the compilers/interpreters smart enough to to "the right thing" for bool -> int conversions?

Now, for the special case for duck-typing languages like Python, int(mybool) might certainly be a really bad idea, but other languages are a bit clearer on their typing.

share|improve this question

closed as too broad by gnat, BЈовић, MichaelT, jwenting, amon May 7 at 10:56

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

2  
All other things being equal, I think you do want to rely on the compiler's interpretation (unless, of course, you don't. I've seen some fairly strange ways that booleans are interpreted; if you change that interpretation, you might confuse people). –  Robert Harvey May 6 at 14:29
4  
this answer says that the conversion is guaranties by the standard (at least for c++). –  BЈовић May 6 at 15:03
1  
In C++, the result is well defined. In C, the result is well defined if you're using the built-in bool (_Bool) type, introduced by C99, but older code may define bool in some other way that permits values other than 0 and 1. In Ada, you can't convert a Boolean to type Integer, but the Boolean'Pos attribute yields 0 for False, 1 for True. And so on, with varying answers for all language with a built-in boolean type. I don't believe there's a language-independent answer. –  Keith Thompson May 6 at 21:26
    
You seem to be getting a number of answers that are focusing on specific parts of the question (the title, the python aspect. Do you think you could edit your question so that it makes it clear what you are asking? –  MichaelT May 7 at 0:19
    
If my non-techie wife asks my 5 yo son if he has an apple in his bag and he answers '1'. I explain that 1 means yes, and she ask "Why? Why 1, why not not 10, or 'A'?", I would say "History" After a long discussion I think we would come to an agreement that "Yes" and "No" work just fine and 1 and 0 to mean yes and no is a dumb idea..... –  mattnz May 7 at 1:01

3 Answers 3

With other languages the situation is not so clear, but python happens to be specified in such a way that you can depend on it always casting to 1 and 0. Python's designers are some of the best with regard to the principle of least astonishment.

The issue is that python is relatively rare as a first language, and programmers transfer practices from other languages that become superstitions in the new language. If their first language was C++, they are going to be very nervous about casting a boolean instead of using a branch, especially if python is more of a hobby language for them than something they use in depth.

Code is for humans to read more than computers. It's often less hassle to use a construct that works reliably across programming languages than to depend on in-depth knowledge of the specification of one language or creating a comment to that effect. It's the same reason we use parentheses in cases where operator precedence might differ between languages. It's less effort to read for multi-lingual programmers.

That doesn't mean we shouldn't try to write idiomatic code, just keep in mind your maintainers when either method will do.

share|improve this answer
    
so, the question is about python, and not all languages? –  BЈовић May 6 at 15:19
    
The question is not tagged with a specific language, but there is a quote about Python. I think addressing both concerns the way this answer does will both answer the question as well as making it applicable to more situations, hence more useful to people besides the asker. –  Snowman May 6 at 15:41
    
@BЈовић The question was not about Python. I just used it as an example. That aside, the argument for idiomatic code is very compelling. –  exhuma May 6 at 17:48
    
@exhuma The problem is : what may be well defined in one language, causes an undefined behavior in another. This is one of such things. –  BЈовић May 7 at 6:54

The title of your question asks "is it a good idea" but the body asks "what is the correct way to do this?" I will address the concern in the title.

At its core, a boolean is simply a single bit. However, it represents truth, not a number: while a bit may represent zero or one, it represents true and false when that bit is a boolean. What does "true" mean in the context of a number? That makes as much sense as casting the color "red" to a number.

For this reason, I argue that it is not a good idea to convert or cast a boolean to an integer or any other type. That destroys the true/false meaning of the boolean.

Java tends to be a whipping boy for implementing half-assed language decisions, but I strongly believe one thing they got right was going out of their way to treat booleans as anything but an integer. In Java, it is not possible to cast a boolean as an integer or any other type for the same reasons I already outlined.


Based on the discussion in the comments, I need to address the bigger picture of why this is the case. A cast works for an is-a relationship, and it needs to be unambiguous.

is-a: would it be possible to cast a string to a list? No, there is no is-a relationship between them. It would be possible to convert a string to a list, e.g. by expressing it as a list of characters. Casting should be used to take an object and use it as a more specific type: e.g. casting a Shape to a Square. Casting to a Color makes no sense: but retrieving the color attribute of the shape does make sense.

unambiguous: a cast needs to have no ambiguity about how to perform a conversion. Casting a string to an integer does not make sense, because additional information is needed: what radix should be used to perform the conversion? If converting a date to an integer, should the cast get the number of seconds since epoch? The hour of the day? The year? A simple cast does not and cannot have this knowledge: a conversion function is necessary.

share|improve this answer
    
Why should booleans be any different than integers, floats, dates, or strings? If casting a Boolean isn't ok, are any casts ever ok? –  DougM May 6 at 17:33
3  
a float and an integer are both numbers. It makes sense to cast between them. I would also argue that a date and a string should not be castable to integers. They are not intrinsically numeric. A date may be able to convert itself to an integer a different way (e.g. get the number of seconds since epoch) but not via casting. Similarly, a string may be able to be parsed as an integer, but I think that should also be a higher-level mechanism than a cast. –  Snowman May 6 at 17:40
4  
I would like to expand on that last comment a bit. A date can be expressed as multiple numbers: seconds since epoch, a month number, day of month, etc. so a simple cast is not selective enough. In needs a conversion function to be specific enough. Same with a string: what does (int) "0724" mean? Is that a decimal 724 zero-padded, or octal? A cast is not smart enough. Again, some kind of conversion function is needed in order to specify the additional information required to convert the value (e.g. radix). –  Snowman May 6 at 17:54
2  
A boolean is not necessarily just a single bit. There are in fact cases where -1 is used to indicate TRUE, which is equal to 0xFFFFFFFF (32 bit int assumed). That's one of the reasons why it is not a good idea. –  JensG May 6 at 18:06
1  
I am okay with casting a float to an int losing precision, since that is well-defined based on the types of numbers used. If additional control is needed to control e.g. rounding or to perform validation on the domain or range of the conversion, a function should be used instead. –  Snowman May 6 at 19:39

Although I think it's generally best to use conditional language for the conversion regardless of what the Boolean variable represents, it's worthwhile to note that Boolean variables may be used in two semantically-distinct ways, and the preferred way of writing the code is different for each.

Although some people would suggest that someCondition == true or someCondition == false should always be regarded as redundant and replaced with someCondition and !someCondition, I would suggest that the two kinds of expressions be regarded as having slightly different meanings and implications. Both will generate identical machine code, and in most cases the latter would be preferable, but the former would interpret someCondition as an abstract "value" rather than a statement about truth or falsity. For example, if one is writing embedded system code and the devlopment tools provide a bool portState(pinNumber) method, writing buttonPressed = (portState(BUTTON_PORT) == false); may be better than buttonPressed = !portState(BUTTON_PORT);. I would interpret the former as `The button is pressed when the I/O pin is a logic low level"; I'm not sure how I'd vocalize the latter.

share|improve this answer
    
Nice example: Especially when you're working with make and break contacts at the same time the !portState() version gets confusing as hell in a matter of minutes. –  Tonny May 6 at 21:53
    
@Tonny: I'm not sure how best to describe when to use the == form, but I think the cases where it "feels" right are those where which cross "domains", either between hardware states and local meanings, or "what was the last value written to a variable". Perhaps a principle would be "Use == if one would be inclined to use custom 2-state types if it were efficient and convenient as Boolean, and if one would want to switch between types." –  supercat May 6 at 22:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.