23
\$\begingroup\$

This is a rather common inquiry in contests that require computing elements of a sequence.

For example, consider the following recursive implementation of the factorial function (Python):

f = lambda n:n<1or n*f(n-1)

This works well for all positive n; f(n) returns the required result as an int.

However, f(0) will return the result of the comparison n<1, which is the the bool True.

Fixing this is easy enough, but it costs a few bytes:

f = lambda n:0**n or n*f(n-1)

While it is possible to think of the Booleans True and False as numbers (usually 1 and 0) and use them as such in languages such as Python, languages such as Java or Ruby do not even allow casting a Boolean to a numeric type.

Since this is such a common scenario, I think we would benefit from a default. If a challenge doesn't contemplate returning Booleans instead of numbers, should it be allowed or forbidden?

\$\endgroup\$
  • \$\begingroup\$ Python says True's an integer: >>> isinstance(0 < 1, int) True When has it ever lied to us? \$\endgroup\$ – feersum Apr 29 '16 at 4:45
  • \$\begingroup\$ @feersum or more simply; >>> True == 1 True \$\endgroup\$ – Cyoce Apr 29 '16 at 7:16
  • \$\begingroup\$ @feersum That's because in Python, bool is a trivial subclass of int \$\endgroup\$ – cat Apr 29 '16 at 16:15
  • \$\begingroup\$ @Cyoce == may cast 1 to True. \$\endgroup\$ – Rɪᴋᴇʀ Apr 30 '16 at 1:48
  • 1
    \$\begingroup\$ @EᴀsᴛᴇʀʟʏIʀᴋ Python does not have casts. the int(), bool() and etc functions are like casts, but they aren't actually casts. The fact is, True and False are numbers in Pyfon. \$\endgroup\$ – cat Apr 30 '16 at 16:13
  • \$\begingroup\$ @Riker feersum's comment shows that there's no type casting. \$\endgroup\$ – mbomb007 Mar 22 '17 at 14:45
  • \$\begingroup\$ When you try 1 is True it returns false, in Python.... \$\endgroup\$ – Comrade SparklePony Mar 22 '17 at 19:41
  • \$\begingroup\$ @SparklePony So does [] is []. \$\endgroup\$ – Dennis Mar 22 '17 at 23:24
  • \$\begingroup\$ @Dennis True is True returns True.... \$\endgroup\$ – Comrade SparklePony Mar 23 '17 at 14:04
  • \$\begingroup\$ @ComradeSparklePony is tests for reference equality. Every instance of True is the same object, but this is not necessarily true for [], "", 1, etc. \$\endgroup\$ – Esolanging Fruit Oct 11 '17 at 15:41
26
\$\begingroup\$

If it quacks like a number, it's a number

Let's look at some Python examples.

>>> 2 * 1
2

>>> 2 * 0
0

Cool, 2, 1, and 0 are all numbers. That's not being contested here.

>>> 2 * True
2

>>> 2 * False
0

True and False act just like 1 and 0 (respectively). In fact, 1 == True and 0 == False. The only difference is that 1 and 0 are instances of int, and True and False are instances of bool (which is itself a subclass of int). This is by design.

In C, they are exactly the same: true and false are preprocesser macros defined as 1 and 0, respectively.

In short: if you can use a boolean just like a number, then booleans are acceptable substitutes for numbers, since they're functionally identical.

More general: Data types can be substituted so long as the alternate data type is functionally identical to the intended/original data type. For C, this means using uint_8 instead of char is acceptable. For Python, this means that bool and int are interchangeable.

However, this does not apply to challenges where an exact string output is required. For example, in Ninety-Nine Bottles of Beer, the second-to-last verse must be "1 bottle of beer on the wall...", not "True bottle of beer on the wall...".

\$\endgroup\$
  • \$\begingroup\$ This makes sense to me. Duck-typing FTW! \$\endgroup\$ – Cyoce Apr 29 '16 at 7:16
  • 5
    \$\begingroup\$ While we're at it, does the same logic apply to chars? For example, if I'm golfing in C and I output '*' where the correct answer is 42, is that acceptable? (I assume the answer is yes, but it would be nice to have this explicitly stated, and it's relevant to the current question) \$\endgroup\$ – DJMcMayhem Apr 29 '16 at 16:38
  • 4
    \$\begingroup\$ @DrGreenEggsandHamDJ In C, there is no difference between char c = '*'; and char c = 42; (since char is an integral type), so I'd say that's valid. \$\endgroup\$ – Mego Apr 29 '16 at 18:49
  • \$\begingroup\$ Does just like a number mean you have to be able to replace numbers with the associated Booleans in all arithmetic operations? \$\endgroup\$ – Dennis Apr 29 '16 at 18:58
  • \$\begingroup\$ @Dennis In all operations relevant to the submission. So, for your example (f = lambda n:n<1or n*f(n-1)), you can use any data type for n, so long as <, *, and - work the same as they do for integers. \$\endgroup\$ – Mego Apr 29 '16 at 19:05
  • 5
    \$\begingroup\$ That seems a bit weak. It would allow "\n \v\f\r" (in JavaScript) and "abc" (in Perl) as valid representations of 0. \$\endgroup\$ – Dennis Apr 29 '16 at 19:07
  • \$\begingroup\$ @Dennis Valid point. I'll change it to "all operations". \$\endgroup\$ – Mego Apr 29 '16 at 19:19
  • 3
    \$\begingroup\$ How does this extend to, say, True bottle of beer on the wall (amongst the other lines of the relevant song)? \$\endgroup\$ – Sp3000 May 1 '16 at 14:02
  • 2
    \$\begingroup\$ @Sp3000 When a challenge has specific, strict output, it must match byte-for-byte. If the challenge just wants a value for an output (and is not strict on the format), then these looser rules apply. \$\endgroup\$ – Mego May 1 '16 at 18:01
  • \$\begingroup\$ @Mego Just to clarify - I don't necessarily mean Kolmogorov complexity problems, e.g. if there was a problem that required returning a certain number of integer dollars - would "$True" still be fine? \$\endgroup\$ – Sp3000 May 9 '16 at 15:13
  • \$\begingroup\$ Data types can be substituted so long as they are functionally identical. I think this should rather be one-way: data type A can be used instead of data type B if doing so results in something functionally identical (even if the reverse substitution does not). For example, in Matlab false can be used instead of 0, but replacing a false by a 0 may produce different results \$\endgroup\$ – Luis Mendo May 9 '16 at 23:03
  • \$\begingroup\$ @LuisMendo I like that wording. I'll edit this post soon. \$\endgroup\$ – Mego May 9 '16 at 23:09
  • 6
    \$\begingroup\$ This answer seems to me to create more confusion than previously existed. What does "functionally identical" mean? It obviously doesn't mean that there's no function which distinguishes them, or the question wouldn't have arisen in the first place. To take the first example, of Python True vs 1, printing them gives different results. \$\endgroup\$ – Peter Taylor May 10 '16 at 10:09
  • 3
    \$\begingroup\$ @Sp3000 I think that (assuming that $ just means $, not a eval operator like Julia) doesn't count as integer output anymore. That is a string, and True is not one. TL;DR: That isn't plain integer output, so True won't work \$\endgroup\$ – Rɪᴋᴇʀ Jun 6 '16 at 14:37
  • \$\begingroup\$ Does it need to be functionally equivalent in the language being used? Can I return true instead of 1 in a language where they are not equivalent, mimicking the output of a function in a language where they are equivalent? \$\endgroup\$ – Sparr Dec 20 '18 at 2:02
11
\$\begingroup\$

By default, answers should provide what the question asks for

If the question asks for a number, the answer should provide a number. We have various defaults partly to reduce boilerplate, but also to cover issues which a first-time poster wouldn't think about and where their failure to think about it would seriously affect question quality.

A first-time poster wouldn't think about allowing answers to their integer number sequence question to print True rather than 1, and it would be quite reasonable for their reaction when someone does that and then points at meta to be along the lines of "This is stupid. I'm going to edit my question."

So consider two scenarios:

Scenario 1: new user posts a question, making perfectly reasonable assumptions about what kind of answers would be permitted; someone posts an answer which prompts the new user to want to disqualify that answer. This runs up against our general distaste for question edits which disqualify existing answers.

Scenario 2: new user posts a question; experienced user requests them to edit it to allow Booleans. Either they don't want to, and make that clear; or they agree, and edit. In neither case is any existing answer disqualified.

The second scenario seems to me to be clearly preferable and the comparison seems to be sufficient reason in itself to require that by default this should not be allowed.

Of course, nothing prevents those who want from adding the following line to their questions:

If your language has a Boolean type for which true and false are each equal to exactly one integer value, you may return/output that type instead of an integer when the specified output would otherwise be that integer.

\$\endgroup\$
5
\$\begingroup\$

Not in Inputs/Outputs

Allowing booleans to be returned instead of numbers is completely against the whole point of booleans in languages.

Booleans are not necessary, but are implemented to make a distinction between the "simple" numbers 1 and 0 and the boolean values true and false.

The implementation of booleans in the language has no influence on this: the fact that it is implemented means that it is intended to be semantically different from numbers.

Note: If your boolean gets returned as a number, then that's obviously valid. Similarly you can use booleans however you want inside your program.

Note 2: I have the exact same view for chars. Arguing that an output of '*' is valid if the expected output is 42 is completely ridiculous. As before, if your '*' gets printed as 42 then it's fine.

\$\endgroup\$
  • 2
    \$\begingroup\$ I agree with this for the most part, but in code-golfing requiring to cast to a separate type for code-golf where in code it would work as a number could be considered pointless. \$\endgroup\$ – Downgoat May 1 '16 at 5:23
  • \$\begingroup\$ * IS valid for 42 if we're using brainfuck... \$\endgroup\$ – mbomb007 Mar 22 '17 at 14:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .