|
|
|
@ -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. |
|
|
|
|