As a programmer, my favorite way to think about Vacuous Truth is to think about the relationship between binary operators and their corresponding sequence operators. Think about taking an operator like "plus" and extending it to sequences or lists of things. What properties would we like those extensions to have? Let's start with a simple example:
Sum is the "sequence extension" of Plus.
Sum([a, b, c]) = a + b + c -- basically our definition
Sum([a, b, c]) = Sum([a, b]) + Sum([c]) -- distributive
Sum([]) = 0 -- identity
Let's keep things simple by assuming our operator is associative and has an identity (i.e., it is a monoid). We can take any monoid and extend it to sequences. Assume @ is some monoid. We define the sequence aggregate "Agg" as: [0] Agg([a, b, c]) = a @ b @ c == ((a @ b) @ c) == (a @ (b @ c)) -- definition + associativity
[1] Agg([a, b, c]) = Agg([a, b]) @ Agg([c]) -- distributive
[2] Agg([]) = Identity(@)
Note that property 2 is required if we want Agg([]) to have a value at all, since Agg([]) == Agg([] concat []) == Agg([]) @ Agg([]). If Agg([]) doesn't have a value, then it's not really properly distributive, since Agg([a]) == Agg([a] concat []) == Agg([a]) @ Agg([]) == ???. So we see that if we have an identity for the operator, it really should be the same as Agg([]).So let's extend AND and OR to sequence operators. The extension of AND can be called "Every", and it operates on sets of booleans. In particular, Every([]) == Identity(AND). The Identity of AND is "true", so Every([]) == True. The extension of OR can be called "Any", and Any([]) == Identity(OR) == False.
This is the easiest way for me to remember the truth values of Every([]) and Any([]): they must be the identities of the corresponding boolean operators.
Any([Your name is Bob, you can fly]) == Any([Your name is Bob, you can fly] concat []) == Any([Your name is Bob]) OR Any([You can fly]) OR Any([]) == (Your name is Bob) OR (You can fly) OR (False). Any([]) == False.