Finish up the draft of the boolean values post.
This commit is contained in:
parent
6f0667bb28
commit
6c3780d9ea
|
@ -6,7 +6,7 @@ draft: ["Java", "Haskell"]
|
|||
|
||||
A friend of mine recently had an interview for a software
|
||||
engineering position. They later recounted to me the content
|
||||
of the techical questions that they had been asked. Some had
|
||||
of the technical questions that they had been asked. Some had
|
||||
been pretty standard:
|
||||
|
||||
* __"What's the difference between concurrency
|
||||
|
@ -20,9 +20,9 @@ But then, they recounted a rather interesting question:
|
|||
|
||||
> How many values does a bool have?
|
||||
|
||||
Innocous at first, isn't it? Probably a bit simpler, in fact,
|
||||
Innocuous at first, isn't it? Probably a bit simpler, in fact,
|
||||
than the questions about methods and functions, concurrency
|
||||
and parallelism. It's plausible that a programmer
|
||||
and parallelism. It's plausible that a candidate
|
||||
has not done much concurrent or parallel programming in their
|
||||
life, or that they came from a language in which functions
|
||||
were rare and methods were ubiquitous. It's not plausible,
|
||||
|
@ -44,13 +44,13 @@ is a property of _something_ that defines what the _something_
|
|||
means and what you can do with it. That _something_ can be
|
||||
several things; for our purposes, it can either be an
|
||||
_expression_ in a programming language (in the form of `fact(n)`)
|
||||
or a value in that same programming langauge (like `5`).
|
||||
or a value in that same programming language (like `5`).
|
||||
|
||||
Dealing with values is rather simple. Most languages have finite numbers,
|
||||
usually with \\(2^{32}\\) values, which have type `int`,
|
||||
`i32`, or something in a similar vein. Most languages also have
|
||||
strings, of which there are as many as you have memory to contain,
|
||||
and which have the type `string`, `String`, or occasianlly
|
||||
and which have the type `string`, `String`, or occasionally
|
||||
the more confusing `char*`. Most languages also have booleans,
|
||||
as we discussed above.
|
||||
|
||||
|
@ -124,7 +124,7 @@ But why does _this_ matter? Well, it matters because we don't know
|
|||
whether or not this function will diverge, and thus, we can't
|
||||
'throw it out of the window' like we wanted to with `meaningOfLife`!
|
||||
In general, it's _impossible to tell_ whether or not a program will
|
||||
terminate; that is the [halting prorblem](https://en.wikipedia.org/wiki/Halting_problem).
|
||||
terminate; that is the [halting problem](https://en.wikipedia.org/wiki/Halting_problem).
|
||||
So, what do we do?
|
||||
|
||||
It turns out to be convenient -- formally -- to treat the result of a diverging computation
|
||||
|
@ -187,7 +187,7 @@ expression. What you're doing is a kind of academic autofellatio.
|
|||
Alright, I can accept this criticism. Perhaps just calling a nonterminating
|
||||
function a value _is_ far-fetched (even though denotational semantics
|
||||
_do_ extend types with \\(\\bot\\)). But denotational semantics is not
|
||||
the only place where types are implcitily extend with an extra value;
|
||||
the only place where types are implicitly extend with an extra value;
|
||||
let's look at Java.
|
||||
|
||||
In Java, we have `null`. At the
|
||||
|
@ -218,3 +218,90 @@ Boolean myTrue = true;
|
|||
Boolean myFalse = false;
|
||||
Boolean myBool = null;
|
||||
```
|
||||
|
||||
Beautiful, isn't it? And, unlike Haskell, where you can't _really_
|
||||
check if your `Bool` is `undefined` (because you can't tell whether
|
||||
a non-terminating computation is as such), you can very easily
|
||||
check if your `Boolean` is `true`, `false`, or `null`:
|
||||
|
||||
```Java
|
||||
assert myTrue != myFalse;
|
||||
assert myFalse != myBool;
|
||||
assert myTrue != myBool;
|
||||
```
|
||||
|
||||
We're okay to use `!=` here, instead of `equals`, because it so happens
|
||||
each boxed instance of a `boolean` value
|
||||
[refers to the same `Boolean` object](https://stackoverflow.com/questions/28636738/equality-of-boxed-boolean).
|
||||
In fact, this means that a `Boolean` variable can have __exactly__ 3 values!
|
||||
|
||||
### C and Integers
|
||||
Oh the luxury of having a type representing booleans in your language!
|
||||
It's almost overly indulgent compared to the spartan minimalism of C.
|
||||
In C, boolean conditions are represented as numbers. You can perhaps get
|
||||
away with throwing around `char` or `short int`, but even then,
|
||||
these types allow far more values than two!
|
||||
|
||||
```C
|
||||
unsigned char test = 255;
|
||||
while(test) test -= 1;
|
||||
```
|
||||
|
||||
This loop will run 255 times, thereby demonstrating
|
||||
that C has at least 255 values that can be used
|
||||
to represent the boolean `true`. There are other languages
|
||||
with the notion of 'truthy' and 'falsey' values. However,
|
||||
some of them differ from C in that they also extend this notion
|
||||
to apply to equality. In JavaScript:
|
||||
|
||||
```JavaScript
|
||||
console.assert(true == 1)
|
||||
console.assert(false == 0)
|
||||
```
|
||||
|
||||
Then, there are still exactly two distinct values
|
||||
modulo `==`. No such luck in C, though! We have 256 values that fit in `unsigned char`,
|
||||
all of which are also distinct modulo `==`. Our boolean
|
||||
variable can contain all of these values. And there is no
|
||||
respite to be found with `enum`s, either. We could try define:
|
||||
|
||||
```C
|
||||
enum bool { TRUE, FALSE };
|
||||
```
|
||||
|
||||
But unfortunately, all this does is define `bool` to be a numeric
|
||||
type that can hold at least 2 distinct values, and define
|
||||
numeric constants `TRUE` and `FALSE`. So in fact, you can
|
||||
_still_ write the following code:
|
||||
|
||||
```C
|
||||
enum bool b1 = TRUE;
|
||||
enum bool b2 = FALSE;
|
||||
enum bool b3 = 15;
|
||||
```
|
||||
|
||||
And so, no matter how hard you try, your 'boolean'
|
||||
variable can have many, many values!
|
||||
|
||||
### Conclusion
|
||||
I think that 'how many values does a boolean have' is a strange
|
||||
question. Its purpose can be one of two things:
|
||||
|
||||
* The interviewer expected a long-form response such as this one.
|
||||
This is a weird expectation for a software engineering candidate -
|
||||
how does knowing about \\(\\bot\\), `undefined`, or `null` help in
|
||||
creating software, especially if this information is irrelevant
|
||||
to the company's language of choice?
|
||||
* The interviewer expected the simple answer. In that case,
|
||||
my previous observation applies: what software engineering
|
||||
candidate has _not_ seen a boolean in their time programming?
|
||||
Surely candidates are better screened before they are offered
|
||||
an interview?
|
||||
|
||||
Despite the question's weirdness, I think that the resulting
|
||||
investigation of the matter -- outside of the interview setting --
|
||||
is useful, and perhaps, in a way, enlightening. It may help
|
||||
one understand the design choices made in _their_ language of choice,
|
||||
and how those choices shape the code that they write.
|
||||
|
||||
That's all I have! I hope that you found it interesting.
|
||||
|
|
Loading…
Reference in New Issue
Block a user